From 7e8d8308e35df91d2f1afdf94c93a2d14f3e5b16 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 3 May 2008 14:37:10 +0000 Subject: [PATCH 01/98] Initial Import --- client/about.ui | 88 + client/hexlineedit.cpp | 69 + client/hexlineedit.h | 24 + client/icons/bullet_error.png | Bin 0 -> 454 bytes client/icons/bullet_green.png | Bin 0 -> 295 bytes client/icons/bullet_orange.png | Bin 0 -> 283 bytes client/icons/bullet_red.png | Bin 0 -> 287 bytes client/icons/bullet_yellow.png | Bin 0 -> 287 bytes client/icons/control_play.png | Bin 0 -> 592 bytes client/icons/control_stop.png | Bin 0 -> 403 bytes client/icons/gaps.png | Bin 0 -> 3467 bytes client/icons/magnifier.png | Bin 0 -> 615 bytes client/icons/portgroup_add.png | Bin 0 -> 781 bytes client/icons/portgroup_connect.png | Bin 0 -> 748 bytes client/icons/portgroup_delete.png | Bin 0 -> 775 bytes client/icons/portgroup_disconnect.png | Bin 0 -> 796 bytes client/icons/sound_mute.png | Bin 0 -> 474 bytes client/icons/sound_none.png | Bin 0 -> 417 bytes client/icons/stream_add.png | Bin 0 -> 814 bytes client/icons/stream_delete.png | Bin 0 -> 847 bytes client/icons/stream_edit.png | Bin 0 -> 865 bytes client/main.cpp | 11 + client/mainwindow.cpp | 30 + client/mainwindow.h | 18 + client/mainwindow.ui | 159 ++ client/modeltest.cpp | 542 +++++ client/modeltest.h | 76 + client/modeltest.pri | 4 + client/mythread.cpp | 24 + client/mythread.h | 23 + client/ostinato.pro | 42 + client/ostinato.qrc | 21 + client/port.cpp | 24 + client/port.h | 55 + client/portgroup.cpp | 169 ++ client/portgroup.h | 66 + client/portgrouplist.cpp | 108 + client/portgrouplist.h | 47 + client/portgrouplistmodel.h | 55 + client/portlistmodel.cpp | 191 ++ client/portlistmodel.h | 37 + client/portmodel.cpp | 314 +++ client/portmodel.h | 51 + client/portstatsfilter.ui | 124 + client/portstatsfilterdialog.cpp | 9 + client/portstatsfilterdialog.h | 19 + client/portstatsmodel.cpp | 119 + client/portstatsmodel.h | 59 + client/portstatswindow.cpp | 15 + client/portstatswindow.h | 21 + client/portstatswindow.ui | 133 + client/portswindow.cpp | 320 +++ client/portswindow.h | 56 + client/portswindow.ui | 214 ++ client/stream.cpp | 123 + client/stream.h | 307 +++ client/streamconfigdialog.cpp | 677 ++++++ client/streamconfigdialog.h | 58 + client/streamconfigdialog.ui | 3224 +++++++++++++++++++++++++ client/streamlistmodel.cpp | 119 + client/streamlistmodel.h | 46 + client/streammodel.cpp | 218 ++ client/streammodel.h | 49 + common/protocol.h | 53 + server/abstracthost.h | 12 + server/drone.cpp | 85 + server/drone.h | 36 + server/drone.pro | 9 + server/drone.ui | 126 + server/drone_main.cpp | 22 + server/rxtx.cpp | 147 ++ server/rxtx.h | 35 + 72 files changed, 8683 insertions(+) create mode 100644 client/about.ui create mode 100644 client/hexlineedit.cpp create mode 100644 client/hexlineedit.h create mode 100644 client/icons/bullet_error.png create mode 100644 client/icons/bullet_green.png create mode 100644 client/icons/bullet_orange.png create mode 100644 client/icons/bullet_red.png create mode 100644 client/icons/bullet_yellow.png create mode 100644 client/icons/control_play.png create mode 100644 client/icons/control_stop.png create mode 100644 client/icons/gaps.png create mode 100644 client/icons/magnifier.png create mode 100644 client/icons/portgroup_add.png create mode 100644 client/icons/portgroup_connect.png create mode 100644 client/icons/portgroup_delete.png create mode 100644 client/icons/portgroup_disconnect.png create mode 100644 client/icons/sound_mute.png create mode 100644 client/icons/sound_none.png create mode 100644 client/icons/stream_add.png create mode 100644 client/icons/stream_delete.png create mode 100644 client/icons/stream_edit.png create mode 100644 client/main.cpp create mode 100644 client/mainwindow.cpp create mode 100644 client/mainwindow.h create mode 100644 client/mainwindow.ui create mode 100644 client/modeltest.cpp create mode 100644 client/modeltest.h create mode 100644 client/modeltest.pri create mode 100644 client/mythread.cpp create mode 100644 client/mythread.h create mode 100644 client/ostinato.pro create mode 100644 client/ostinato.qrc create mode 100644 client/port.cpp create mode 100644 client/port.h create mode 100644 client/portgroup.cpp create mode 100644 client/portgroup.h create mode 100644 client/portgrouplist.cpp create mode 100644 client/portgrouplist.h create mode 100644 client/portgrouplistmodel.h create mode 100644 client/portlistmodel.cpp create mode 100644 client/portlistmodel.h create mode 100644 client/portmodel.cpp create mode 100644 client/portmodel.h create mode 100644 client/portstatsfilter.ui create mode 100644 client/portstatsfilterdialog.cpp create mode 100644 client/portstatsfilterdialog.h create mode 100644 client/portstatsmodel.cpp create mode 100644 client/portstatsmodel.h create mode 100644 client/portstatswindow.cpp create mode 100644 client/portstatswindow.h create mode 100644 client/portstatswindow.ui create mode 100644 client/portswindow.cpp create mode 100644 client/portswindow.h create mode 100644 client/portswindow.ui create mode 100644 client/stream.cpp create mode 100644 client/stream.h create mode 100644 client/streamconfigdialog.cpp create mode 100644 client/streamconfigdialog.h create mode 100644 client/streamconfigdialog.ui create mode 100644 client/streamlistmodel.cpp create mode 100644 client/streamlistmodel.h create mode 100644 client/streammodel.cpp create mode 100644 client/streammodel.h create mode 100644 common/protocol.h create mode 100644 server/abstracthost.h create mode 100644 server/drone.cpp create mode 100644 server/drone.h create mode 100644 server/drone.pro create mode 100644 server/drone.ui create mode 100644 server/drone_main.cpp create mode 100644 server/rxtx.cpp create mode 100644 server/rxtx.h diff --git a/client/about.ui b/client/about.ui new file mode 100644 index 0000000..2256d60 --- /dev/null +++ b/client/about.ui @@ -0,0 +1,88 @@ + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + QFrame::Box + + + QFrame::Raised + + + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:29pt; font-weight:600;">Ostinato</span></p></body></html> + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/client/hexlineedit.cpp b/client/hexlineedit.cpp new file mode 100644 index 0000000..a983bfd --- /dev/null +++ b/client/hexlineedit.cpp @@ -0,0 +1,69 @@ +#include "hexlineedit.h" +#include "qdebug.h" + +QString & uintToHexStr(quint32 num, QString &hexStr, quint8 octets); +HexLineEdit::HexLineEdit( QWidget * parent) + : QLineEdit(parent) +{ + //QLineEdit::QLineEdit(parent); +} + +void HexLineEdit::focusOutEvent( QFocusEvent *e ) +{ +#if 0 + const QValidator *v = validator(); + if ( v ) + { + int curpos = cursorPosition(); + QString str = text(); + if ( v->validate( str, curpos ) == QValidator::Acceptable ) + { + if ( curpos != cursorPosition() ) + setCursorPosition( curpos ); + if ( str != text() ) + setText( str ); + } + else + { + if ( curpos != cursorPosition() ) + setCursorPosition( curpos ); + str = text(); + v->fixup( str ); + if ( str != text() ) + { + setText( str ); + } + } + } + QLineEdit::focusOutEvent( e ); + emit focusOut(); +#else + bool isOk; + ulong num; + QString str; + + qDebug("before = %s\n", text().toAscii().data()); + num = text().remove(QChar(' ')).toULong(&isOk, 16); + setText(uintToHexStr(num, str, 4)); + qDebug("after = %s\n", text().toAscii().data()); + qDebug("after2 = %s\n", str.toAscii().data()); +#endif +} + +#if 0 +void HexLineEdit::focusInEvent( QFocusEvent *e ) +{ + QLineEdit::focusInEvent( e ); + emit focusIn(); +} + +void HexLineEdit::keyPressEvent( QKeyEvent *e ) +{ + QLineEdit::keyPressEvent( e ); + if ( e->key() == Key_Enter || e->key() == Key_Return ) + { + setSelection( 0, text().length() ); + } +} +#endif + diff --git a/client/hexlineedit.h b/client/hexlineedit.h new file mode 100644 index 0000000..7c5811e --- /dev/null +++ b/client/hexlineedit.h @@ -0,0 +1,24 @@ +#ifndef _HEXLINEEDIT +#define _HEXLINEEDIT + +#include + +class HexLineEdit : public QLineEdit +{ + Q_OBJECT +public: + // Constructors + HexLineEdit ( QWidget * parent); + +protected: + void focusOutEvent( QFocusEvent *e ); + //void focusInEvent( QFocusEvent *e ); + //void keyPressEvent( QKeyEvent *e ); + +signals: + //void focusIn(); + void focusOut(); +}; + +#endif + diff --git a/client/icons/bullet_error.png b/client/icons/bullet_error.png new file mode 100644 index 0000000000000000000000000000000000000000..bca2b491fd4a72918c37eb218bf9655d7f514750 GIT binary patch literal 454 zcmV;%0XhDOP);<5v0zO%9O+HCOhCe@lCtqI|U`n(Bw>E`n0X60GiU=_L{j`ZeTrWl7@6TVgmzQ|3 z5;Op46VsoczbZwwqJ7S==^_3_&=Ox0MY;dOCY;|ap-3z08F!}8RFQf3;+NC07*qoM6N<$g0j}hYXATM literal 0 HcmV?d00001 diff --git a/client/icons/bullet_green.png b/client/icons/bullet_green.png new file mode 100644 index 0000000000000000000000000000000000000000..058ad261f520490be9d3fc2e322392fdedfd1cbd GIT binary patch literal 295 zcmV+?0oeYDP)ef43{&%10 z`rmr0`TyJtv;LcOX%laN^>UMjsi!CYUwmcZ|JfI2{-1ED=f8fLD)C;hoM$LyFlFzu{izqk|8%^q0F(5@h6w@ zuSbE=i9QOwKvPc#-iPCap~BwXFHIr_gU^WCH%x0(Cm8h3e{9o}5`YUO%{ zPiLR-*D%CfK42<(c~V-?1q(}8{p2N#A`c~!wa4X-$LfsZ0%WH-1^Zy?%r3<3e~Rbycg=S_Egdz d?>~Yc*m~Z+JF!m3&mHJ+22WQ%mvv4FO#s^$Z2kZM literal 0 HcmV?d00001 diff --git a/client/icons/bullet_red.png b/client/icons/bullet_red.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd803115831933aa171497cfe9c1af983035f86 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i=8^mK6yu{izqk}mh50EX6wkMFui zZg|fh<-*g%H9O|;u|DY#DW^u;K&o-|vHe`x?xbw1zYx$2><(A#;6QU!sSfhO( ioL~suuJh6Vfb_?jd)=>7iZy|bXYh3Ob6Mw<&;$Tq>~Ep~ literal 0 HcmV?d00001 diff --git a/client/icons/bullet_yellow.png b/client/icons/bullet_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..6469cea7e99024577964e5c05a3d77d9200f18f9 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i=8^mK6yu{izqk}bDmp#c_6~(fb3t z9fO=s)r1xNys<0toy$Ta)Ef4L9Xj#;LuHACPs?SaC)p1!HoK`$|DN0S(B^2t{U;k3 z{z`Gkym)-$S?qyE;12cK15evqWFMuk`FjMfG>*N*A!+l(#* jF-_{7+4G}*QQ$ohjSunXc9>@Z9nawD>gTe~DWM4f1nGD{ literal 0 HcmV?d00001 diff --git a/client/icons/control_play.png b/client/icons/control_play.png new file mode 100644 index 0000000000000000000000000000000000000000..0846555d0ca84cb99d4c70dad80144a232604041 GIT binary patch literal 592 zcmV-W0k7R5;6} zlgp~&KoEw{L*wq6jM9+RMU)_iNO6K~b@$|K=nj zb2!5=4Mjq_zrU*f>U2#vSVnMZ9ja4cY`AdOM*t}k^goWqfa3Iq(>2kSH;P81hAqIyBm_{t1>+!KRdtb~{1AK7>C~ zD-Nov`UX!X6ET_La7f{B_|*cRuZGR%^C`gjd@jmW6h*+;8;{2{8ja|Fzf-YTq+l@k zGLg?!DijI~9$+CG0P)O;^z5vZ zY!uIB*x&E}vNJj4{?GTJBigE^o7UKdzE#&EBXnfjM2N9qUNJ=7T*(!I*v$dVF@wV! zPcbfCO)dpCHwm6#49koVc}1IZ;f0opGWdxBx;Rl@XzG}46S&UgQ6wI6lQE987w+r= zQ{sp)?}bM^P?n!- zT~4lR-Pg7MSkL>e=lQ*F-u0~YthKU)vU8%ye<9zMgZX)js7AapLE|j^=J~vJROe^I z(&M?NJ~7W*M-2>oC5CToECKAt6z3kP?=JghahTN>~yS67>c}Z93}> zdbBz%E>120m`o;aYYJ%K<8Rg1Y&LUSQ-Gg$1KTLA#Gu!q*Oem(0!jx*7aKuPeuFGNDpC0btN;(d)D|&X*tv zsGVG`d>ajV6n6GD)mvA}OCMl1n^7q2P&znT>^f~307{kGvTZczYaFLcF2_ObT*YS4 zYY_yQWt^hfj9yn>B}Q#9nM{2>88^g8U7D)c&S6(5gV7p2Abv9niVuXM1fW~k*AR@%-DH18Dxz&|o} z;n%^H@E(DLbq^qI=LSo^HJexB*TI#LIDbOo{8_PSsm%oM-nx>+ZtjeXb7M#cJ7$e& zhvs%Z7fu}_v70;hHMcOCj4Yr2GLv5pry&0diQU|-ey0xYsp3~OoB3c$0w2CT$R;|^ zUee+odx48NI_9mtjeG0`Ts!`XqE$98zJ86ng(d(pkCf6N?jn9&FXHjS1%}VOj@gDU zpw0VB7ZSULGf;8xyck`jXX>pMd^oUy}duExe!Jt18^ zf1Ig3`S_I$N*ApmRU4kPv5M4&?Vm|hJ? zTQ-UBccfa4bH!WPYr@)g<><*X0O$<{MoyT9Z$uk{qdU>=fBJIZP*$DeR%g!0Sj)N?(!q|;SG);8 z+VaUPnc5G48#xz9N(f@@yy5(~H{EK!#`g)d@_Qra0!e)WIrRPCY^L>5>Rb{o`Q$x@ z4H!w`NiCB`PG##qwqQ1!`TF}EyuD;9OW$6}t*raJlQf@?zF5umf_$5a_VNoPEwhl7 zJF>ZZE0_KM{LIoOn$4uXo5+RJhnSn1K|qrhq-7TJ={^krN%PZ4%Pb_i)1NH+6c=fj zJ+dPg&-`RFjn#>YP;u|42u|({;Y7BU?cYD(YQCP{<8yhXmkYNJgtKRTAQ@Su?D?_8 zrm_1Box-R4G>n=3F?+YKC3;SbFU$!Wfn4a&ISaTjI_)` zKHhtyioZSE*3dM%Gwb(UC;P+!j_kMDyP?m-(B#Ez`uAN1k4a(Yh6R)s-?y|~|Lr{Q zO^l~ar`{x`q!B+jnY7G8UQ1epyH^9!G7DLne#**c?xi!76y2lnPQ@HtK6iw$79DJ+ zxlOAU+`W8?yt7#Z2L`ZlOF95k-&sJ`u@ii=Wg~fKvuNEal4WZ@MzrC3-hGEp=hJ-} zM!&t5-CI|2=f*Wl+ud8aEKKT2NV6EGF4@V8y@!#OS;!l+)*)Bek(OD=y4|@|{GIr5 zH}l`bJ;bGWHz!mR3!p89C@L0E`|y zmeGU9+DtHjD2nKH<&>8d15`P~f4<^P4rlD(%@4K{6xIp=M`t(0%F7m|gCma4ZdLs0 zb>;LM@fKIIk8<_=ahqy=h}kSst`#XQHzNpOFp6XxF2!Vm1wG0v#%&g9G%@PB~uc9q0 zu_~jU7bc?tZD}z^qXDzogeX@0%{2viES%62rAkfm!Y#;Ta%A@M-^&(3sBxU-WyQ$k za^m_WvS-^Gh9)oOO7>A=dk(gl<~te9*mX8QStq|EKKT&wyc@NsHGeHpc3xeSEh)q>#Ygw&t zx*!PsY9$ERwtgNH`Zeae^i}+M;u4%(JOH?O<}iMZLeUiD@zW36p4#8l>|=y9jUlE> z0%wn8V9;y1k#iCMporQ^dn_fTWgIziieo2FV-`iO<>X^98o6Ke03UBJ0QwCbjZ;7~ zoC2D0?$?Vpi@kg6Dv}a{_*?2629BCdgTOEVaxR_0#mx(ywv2!8+VBJ~zZ26Xfd+xK zJK+j~FiQ}GIn`{h34*YxnyrH%2>a@kuuLWsqh}6BAy=^Nue;dy#UU(}3q-W__xamh++`TPrGd}z~$?tCFO7=0n z{bGep<30<~O;u=5G(&f?89!_Y!o^8OY?K2enEHH7cdSL5XuXt_ac3z`H6@p=H^+}=!SdB8+K4ieinWX=0;PZnI7?Sj!#qJ*z!Q6Ej^c^;h^p9p!kblMIu^-`lwrZ1k%;E4k$ zEh{0YVQ^hS)r=rmE>o-H7Z6HNSS#XRO=jErdECgkV7s`_fJ_ET`>G4QTYE=F^mC<8 zQZBF0zQLH3oBZo=384YDeex!kE08PftnBXI{wP&y1}4tJ)zg>MltfGE{6}nfe;n6; zt5{=e<_+ig!GAt+A5j#qi=vn!ilX)ro1xN{TdnVEQ526od1O_Q%N15negV811R<9z z7&@_{tor2raaMh5;_|tpgjU|K>fV1ed$)gN)B9HdIr-O_JS&BxZkLt*hnJeks_QhHavJXk~YFb|o^V z8wxvnBBEYECRZR=C}kMz#kk9%wu)rQAGxX&%$nYQJ0gS7_F{Gp-)KxVU){5ZV$i z-+-FJZ;SNj*IEtc56HgBIKZ!_HUWr;>V&6HBdfN+&=xcbX^v8*COD!sCZmByjhmrz zsJNQ-@(UomRjk#1B}E!q$HpTF0(SN)JiPshY}*Z258o>NnmB6i$OO^nX~rN30#1%< zy2Q4}L8Zda+Y2WrM?5{;Na)prInyR$Z*PyEuQx9z#N+DX%!A?*`uBc`)r(W`tt=Ct zhO1?s1tw8e<9q>xMz+Vtzj0N4fPZiV!QoLT6m~Re-VQ_&Z~tH%o!t=tH!nY$xB27a zIU?!>+&mu}y3XrDkUlT-^hlqVsWsB)Wu7C_=Vc@$BqW|AQo@pukf=9E2}?pkqTV1S tEC~sTdV`d(BqSv24N}6AkdUZ1{09T)%`hW*ksAO2002ovPDHLkV1hWvtV{p^ literal 0 HcmV?d00001 diff --git a/client/icons/magnifier.png b/client/icons/magnifier.png new file mode 100644 index 0000000000000000000000000000000000000000..cf3d97f75e9cde9c143980d89272fe61fc2d64ee GIT binary patch literal 615 zcmV-t0+{`YP)gNuvOO$0ks zMIj=HnnBRUR?tKXG11rxCU4&7dG4NbuvR2_mEvc)n?Cow;~Wve|KR^>9@p5l)|QB+ z$jmun3q#x>;ss-PW_mnr2MHVzLAl1RW&0?VkixF*4t!St0YVb2wnKdU(kmOHiL;aW zK8Xte%(k>MVGG$E4no6dcNnb>BhVHHGD&1pv4YZ68kE2V03t5#PCEFm7=ad$6)+3B zTCmn*?A?=u(o~ET7~-7g0)ZB=6|lumi4}B}MLgy~Ysy6)Q5%Al7|05&1z3Jpu>cF8 z3?VXs*3<}%h3`5Wld)N2zJnk%Agw<~3k)sPTLFd=F5;d8-bj-09SkQuynfflNcZLN z!^_37fdZvzrq=9~mp*($%mcDRKC&qvaaZuX+C=AT6O*~tHl>0mcP<_q>-z%$xO(@! zYluq5a8VQI$S@4?r*v;gPo!QQ%pX3A#>xx4t=w-L6COWx?aj&`f+!YePsFtj=hOQR zP3=E2j@9L7s8;T^&s?u(Hdpu?CubjMrGn{t_37>9$|AD)QE08weJlKn8|OyjL~7oP zC8mPT`jzuH*Dh^I0048RGafUIT)4H~*m8m>egI0iH=(LB%b@@O002ovPDHLkV1lw0 B3WdP)7sBGH8?p(}ako9KYX(!NC_${+66f zCL^323pYiGbgW{=R3}SA9sZ^M67CqjK_%js%5CkR;me zO?bAIxNg3Ro($a-cu31+pwdB9n{8&kSIhHe>aHBjVXA_CRI@ z^iBXW91h1XCKo*~ZXPqvsnh6OjES;@0=+mMNtWPHly!FDxdig|gWCPa(Ea&26soIrWMt?>>7bAgsH$4Y)5&Bq8mV)C%YB7Y+Jw5j^+Hk8>AUFv z&`yo)gA$EKn@UpK+S;xY$oZXByDL@Ihu$X-O`7@r?DzRA6X`K2l^#WNxC<>WFJptl zO&yXgxs)7>#kLY#ED||;DijJqRXu2EXxy03=c9(D--^EXGrJ@OqsiBFdd$}K z%S6%_$lmt!JU(1H|HXST8NZXhS$l1}(mg$J6&O${e1)u?zBm5_@-L-Nh&J@-00000 LNkvXXu0mjfve9f* literal 0 HcmV?d00001 diff --git a/client/icons/portgroup_connect.png b/client/icons/portgroup_connect.png new file mode 100644 index 0000000000000000000000000000000000000000..024138eb33b9124af6db8149747adbb41c1b8cfc GIT binary patch literal 748 zcmVzR>QH2KN`fNj zBHaWZEgiB#>49kYe(borqx+hj`JS_1d)R}7LjHa+tu+qg(TC+eO4&q(D;ZL8C8o8; zLEfZxiIlQ~iE1b1qBZ2=VhsA0V`*@y@M|Sc2@Wtadv3g0hOc*O(ADVFjPTWAYz(JXS z8MBaa%aCO{h8lvp*ONKIh5Bg|-DNo^;jg=q=uDZ@vodOJXfu;GK`ze`H-VrWK!nUg zje)ufRUJ&ouB2nYB2_pI=gji&GcuBL=+DM-wBZ)fbc7&a9AP1Ztk5)S4Ah03bqXOt zxx}VdK|CIVljyc=oqO1G{;Qew7T~%?tSw{^mi$E(2^Td6>M8+m4H!qrBtj~%w(Y~Q zVrXkVOEN#2&@(U(cX3H&S97B(;-}{)?<>?0)RjVZqrJ&ONChgCgE9%PC}CSBp!+d1 z`bkAqacXYz!94aLsJZ!K=3b*?T#ge1nL>bsZNf4&8mt(EkXYZ?MK0YwH2ZOI9{(VN z&%WPH*v6AY+yG?)mZ`CxE@5ZK2lW}4Pr-ctMRE2V`yf8$PurT4&^p3q*2kt>M8OM& zl@MbQ=U&8BS_$dSjo(q&2Pyd!8`}{~Xr#A_DDL|G({Ha$;Xe@?&|@q4QbvV}D#ixB ey}zEqA^Zgf(1+rQ>#k7%0000IB7 zSr<&xRLO(9u(h={_FdAy0EUK!3MrvO*Y&f3KmiO&g5y9$Q%*Rnqqp}J)W0Ps5{YA+ zTvAd}77B$hJ~0JmcN`av>kyC&o4^difI2!lYS^~zClf(Ane0=k)bElpKc6BX2ZxUw z7vEG)E-$Y@I=vv+U4C3v=?dc);zUun5HFrTLsj)o!Os7L0!HQJ=8iapNsuI(y-9es z%;F+$U)e1f2jlO+YD-U^_7t#GX63+eQ88p$hD0W3jn@p|Iv!*7_8PHvvwI-30(vI^ z8H%E;Gdb&d@a8e&oHmZmbX1fj6qwoeNU{V)RrBn^a|z_V&UuWTpW3mMv4jc%z!Pr> zm%xmXO$DNUZ%CM4u*7P0pc^%V?Wpaag{2o`$?Tx6NFIQkt&?r+^PlIUHWP#Y%SY5* zYC<4Vg_YqxjJ$n~vQ*du@cC5Sy1YZQ$22W0FB?L#-|wR`Tr9LUW80ZV1jk~)n;R%7 z)Umaq5|d*Is8rXTSggM;cTmU|X_^+{?j(~*gVY6Tf6O4bIRcz$%BxaaN}(A)vFM9Y|u11$~II*CeXV}4Kt5h{aWbSmSRg)zoxZBrQl+iPQ*@N>AMLYl{sL3^s-3vtl?VU;002ovPDHLk FV1kc^U#9>7 literal 0 HcmV?d00001 diff --git a/client/icons/portgroup_disconnect.png b/client/icons/portgroup_disconnect.png new file mode 100644 index 0000000000000000000000000000000000000000..b335cb11c4d1a397b307883adcfe1e00c4cf8e6a GIT binary patch literal 796 zcmV+%1LOROP)h5&w{Y-QlBkdy7eSyz8|k(w=syt3MbOGZFmTy2f|dnI3kj6Sz)H!` z%1hM3FiovS8#Qs98Rxs5^PSs#9S4da6*};44(Iv3@B5rb3BwQ$Is?0$0ilY#Q^EELL=6SfS*Ly93GR<|lPYvfPXoM^)HN1)!-B@N5Zi(e|Ge`rl{XLurIiz-D}wHVI0N<*QWk}{)T2Jp~1;rnJ&N2haulNhlC*Od9Gf>KFEtyV>~T1KT( zMys`lcDs%9Y!**GpCvG7uAr)U^!sP%^?K-byD$s`r=o}<$KlrRw*+%D1$0-K<~|ff zfh@~77KHKSyI>I8i8yRaw2IR8ItU>!0|7iT3@*K1Y{mtMqF^t`<+5lr>Nw*0@#HI( zfyeDeD71=LjJFr0(_1)Hq)$07*qoM6N<$f*zgBZU6uP literal 0 HcmV?d00001 diff --git a/client/icons/sound_none.png b/client/icons/sound_none.png new file mode 100644 index 0000000000000000000000000000000000000000..b497ebd54abd420d6ad527e45cf61be55170e944 GIT binary patch literal 417 zcmV;S0bc%zP)=wlnx)<^8N0A$6XFU?l;N(8Q}Zq)nMgnHnL@z8KSBRn@Z&a%{xn|-d2Q4 zMH9;98$s8LZzsrcY-m~$XFnviYhEiADa-Lkz!&I><>UW8(|7X;y57kb#}^N300000 LNkvXXu0mjfTqdux literal 0 HcmV?d00001 diff --git a/client/icons/stream_add.png b/client/icons/stream_add.png new file mode 100644 index 0000000000000000000000000000000000000000..04f22badca1ff91737468581b5a24295bd0814fa GIT binary patch literal 814 zcmV+}1JV46P)2z8@H#eso9vK+4F-h&nJZ&{G7+WHR>s{e4_qTwrf+4t zo}Sk7`8;yD9400vG!kEtGboCJ$;nB0ydu)MsC zrluyXzP`StsD;JFMHe4lUth<{$_gY&LO2{oe}6wa0=0$N*;!HDc=xP zGnYF%JCJ1=$z&2vr!(Ey*l1{NZ8iA){`CC(ya4fcpU-#ccDs+;+S+6tiPf{SGhvr2 zQ;--M8bW(}yWzS@cXzjeG60KH`i!KUM1jQ>oB#e%Zg6L7WWGu8f3f0;{|@fi^gbbu zMx!mm!^7J4_O=l7bf|2?RSyLh4Jr*XM+s*`=%WZM^9Z{oocaIl!k@|JwX(9!VVt1xutof=Wt6k zLhSxrQ|#b+5}?d#wU#zFH+9wmSwoOxbVANu8-ICvC9OZP{@IRIMx}06RoYSO|-wdx|%W=3>I87B3X;u?cVu^ z;VyxF2;9b|J!~>#$>nkxsI*$GOl#-o=X+S&e!t&$gfL`&i~u zsRYGh5fnus!hPJgpcSsMv2k#EdU}ko0zHtGOC%EHg^{A!Y!*3=Bk!t;!{MNHk@g~y z2m}IwDw1%=pitc_W_G{D{G&il8C{Xwocj8wwNOO=jZ1qtXAtNDN$f_3b9yBRcuLaf+-$^4woBr_S;YlEx^y^MLD~>^I9dCo11%s zD&sf-J3c;EC!nGep|SJt`oQ_@73jlX0pi~POgA7c*kE&E`L}uxFarexVtT!vE)|5s z;XF=Y=;`TUL;&dnsI%Aso($J=5#CyXS6Exkg4gTyWipxP7|vlsL&N?0`ufe@-d?(u zkQ{#`KYZH9i_y_eG49s=LNp*;OMt7gCr{Rxm*rXsT4${yX7A% zfy$qf9&)?}vKa=y;!H;A_w0Y4^U%=H0D}AJh#6!4Va@lZeCFUKFEg9WSL2BK@OYsz Z`4?5=&N;mrg`ofd002ovPDHLkV1fozjIRIy literal 0 HcmV?d00001 diff --git a/client/icons/stream_edit.png b/client/icons/stream_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..47b75a456a4bb1487dac02c60b7e2e9cb5e210a6 GIT binary patch literal 865 zcmV-n1D^beP)GR@vSHz5C(pPxHny(nM!6aSI^7R#-{J~?A^0H*YCdW>wX><0M=1!YHEsWHk&65 z2EzpTxW}DK*f^ce)R~!?WFk%?;`Pu5C{Y@ z9*YwPJjH96dcf=xJG z*kl}##L?N=83%;ar!Pg^cVqOf0lN#g5Vlp~vzQCln=Feu@%+Ain zAxsXvy}hQ%p)0kKIRWUX89RYeM1w`x^47xBl|kR;=6}n}%d;PbNXFDkg2d$HB$&Tm z{utC0|DU)7(XWO0;TB^4`9-wVaC#H&fkYyy8yXslc|4xD*f81w?^q4!T|J^pT>J`N z!zOX^g^2B+#!yvN6)P_<|3AiofdL_tJahBjw(;Om)xxQMf{?WUJ4;0fJMO^QaUmuX zzldkm(9nR~++1P8J!ouf?5?h^rbixT09(uOy~>BS_9Toi+4ykpEG-e7Pv>wrR8CF~ z&1SQ^k9 +#include "mainwindow.h" + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + MainWindow mainWin; + + mainWin.show(); + return app.exec(); +} diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp new file mode 100644 index 0000000..7eef2f3 --- /dev/null +++ b/client/mainwindow.cpp @@ -0,0 +1,30 @@ +#include +#include "mainwindow.h" +#include "portswindow.h" +#include "portstatswindow.h" +#include "portgrouplist.h" + +PortGroupList *pgl; + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow (parent) +{ + pgl = new PortGroupList; + + PortsWindow *portsWindow = new PortsWindow(pgl, this); + PortStatsWindow *statsWindow = new PortStatsWindow(pgl, this); + QDockWidget *dock = new QDockWidget(tr("Ports"), this); + QDockWidget *dock2 = new QDockWidget(tr("Stats"), this); + + setupUi(this); + + dock->setWidget(portsWindow); + addDockWidget(Qt::TopDockWidgetArea, dock); + dock2->setWidget(statsWindow); + addDockWidget(Qt::BottomDockWidgetArea, dock2); +} + +void MainWindow::on_actionPreferences_triggered() +{ +} + diff --git a/client/mainwindow.h b/client/mainwindow.h new file mode 100644 index 0000000..da412ec --- /dev/null +++ b/client/mainwindow.h @@ -0,0 +1,18 @@ +#ifndef _MAIN_WINDOW_H +#define _MAIN_WINDOW_H + +#include +#include "ui_mainwindow.h" + +class MainWindow : public QMainWindow, private Ui::MainWindow +{ + Q_OBJECT +public: + MainWindow(QWidget *parent = 0); + +public slots: + void on_actionPreferences_triggered(); +}; + +#endif + diff --git a/client/mainwindow.ui b/client/mainwindow.ui new file mode 100644 index 0000000..5d43edb --- /dev/null +++ b/client/mainwindow.ui @@ -0,0 +1,159 @@ + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 0 + 0 + 800 + 21 + + + + + File + + + + + + View + + + + + + Window + + + + + + + + + + + + Help + + + + + + + + + + + + Open Config + + + + + Save Config + + + + + Save Config As ... + + + + + Open Capture + + + + + Save Capture + + + + + Save Capture As ... + + + + + E&xit + + + + + Copy Port Config + + + + + Paste Port Config + + + + + Preferences + + + + + Minimize + + + + + Maximize/Restore + + + + + Minimize All + + + + + Maximize/Restoe All + + + + + Arrange All - Cascade + + + + + Arrange All - Tile + + + + + Dock + + + + + Help + + + + + About + + + + + + diff --git a/client/modeltest.cpp b/client/modeltest.cpp new file mode 100644 index 0000000..58685b0 --- /dev/null +++ b/client/modeltest.cpp @@ -0,0 +1,542 @@ +/**************************************************************************** +** +** Copyright (C) 2007 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Concurrent project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.trolltech.com/products/qt/opensource.html +** +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://www.trolltech.com/products/qt/licensing.html or contact the +** sales department at sales@trolltech.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include + +#include "modeltest.h" + +Q_DECLARE_METATYPE(QModelIndex) + +/*! + Connect to all of the models signals. Whenever anything happens recheck everything. +*/ +ModelTest::ModelTest(QAbstractItemModel *_model, QObject *parent) : QObject(parent), model(_model), fetchingMore(false) +{ + Q_ASSERT(model); + + connect(model, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)), + this, SLOT(runAllTests())); + connect(model, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), + this, SLOT(runAllTests())); + connect(model, SIGNAL(columnsInserted(const QModelIndex &, int, int)), + this, SLOT(runAllTests())); + connect(model, SIGNAL(columnsRemoved(const QModelIndex &, int, int)), + this, SLOT(runAllTests())); + connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(runAllTests())); + connect(model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)), + this, SLOT(runAllTests())); + connect(model, SIGNAL(layoutAboutToBeChanged ()), this, SLOT(runAllTests())); + connect(model, SIGNAL(layoutChanged ()), this, SLOT(runAllTests())); + connect(model, SIGNAL(modelReset ()), this, SLOT(runAllTests())); + connect(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), + this, SLOT(runAllTests())); + connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), + this, SLOT(runAllTests())); + connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(runAllTests())); + connect(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(runAllTests())); + + // Special checks for inserting/removing + connect(model, SIGNAL(layoutAboutToBeChanged()), + this, SLOT(layoutAboutToBeChanged())); + connect(model, SIGNAL(layoutChanged()), + this, SLOT(layoutChanged())); + + connect(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), + this, SLOT(rowsAboutToBeInserted(const QModelIndex &, int, int))); + connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), + this, SLOT(rowsAboutToBeRemoved(const QModelIndex &, int, int))); + connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(rowsInserted(const QModelIndex &, int, int))); + connect(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(rowsRemoved(const QModelIndex &, int, int))); + + runAllTests(); +} + +void ModelTest::runAllTests() +{ + if (fetchingMore) + return; + nonDestructiveBasicTest(); + rowCount(); + columnCount(); + hasIndex(); + index(); + parent(); + data(); +} + +/*! + nonDestructiveBasicTest tries to call a number of the basic functions (not all) + to make sure the model doesn't outright segfault, testing the functions that makes sense. +*/ +void ModelTest::nonDestructiveBasicTest() +{ + Q_ASSERT(model->buddy(QModelIndex()) == QModelIndex()); + model->canFetchMore(QModelIndex()); + Q_ASSERT(model->columnCount(QModelIndex()) >= 0); + Q_ASSERT(model->data(QModelIndex()) == QVariant()); + fetchingMore = true; + model->fetchMore(QModelIndex()); + fetchingMore = false; + Qt::ItemFlags flags = model->flags(QModelIndex()); + Q_ASSERT(flags == Qt::ItemIsDropEnabled || flags == 0); + model->hasChildren(QModelIndex()); + model->hasIndex(0, 0); + model->headerData(0, Qt::Horizontal); + model->index(0, 0); + Q_ASSERT(model->index(-1, -1) == QModelIndex()); + model->itemData(QModelIndex()); + QVariant cache; + model->match(QModelIndex(), -1, cache); + model->mimeTypes(); + Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); + Q_ASSERT(model->rowCount() >= 0); + QVariant variant; + model->setData(QModelIndex(), variant, -1); + model->setHeaderData(-1, Qt::Horizontal, QVariant()); + model->setHeaderData(0, Qt::Horizontal, QVariant()); + model->setHeaderData(999999, Qt::Horizontal, QVariant()); + QMap roles; + model->sibling(0, 0, QModelIndex()); + model->span(QModelIndex()); + model->supportedDropActions(); +} + +/*! + Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren() + + Models that are dynamically populated are not as fully tested here. + */ +void ModelTest::rowCount() +{ + // check top row + QModelIndex topIndex = model->index(0, 0, QModelIndex()); + int rows = model->rowCount(topIndex); + Q_ASSERT(rows >= 0); + if (rows > 0) + Q_ASSERT(model->hasChildren(topIndex) == true); + + QModelIndex secondLevelIndex = model->index(0, 0, topIndex); + if (secondLevelIndex.isValid()) { // not the top level + // check a row count where parent is valid + rows = model->rowCount(secondLevelIndex); + Q_ASSERT(rows >= 0); + if (rows > 0) + Q_ASSERT(model->hasChildren(secondLevelIndex) == true); + } + + // The models rowCount() is tested more extensively in checkChildren(), + // but this catches the big mistakes +} + +/*! + Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren() + */ +void ModelTest::columnCount() +{ + // check top row + QModelIndex topIndex = model->index(0, 0, QModelIndex()); + Q_ASSERT(model->columnCount(topIndex) >= 0); + + // check a column count where parent is valid + QModelIndex childIndex = model->index(0, 0, topIndex); + if (childIndex.isValid()) + Q_ASSERT(model->columnCount(childIndex) >= 0); + + // columnCount() is tested more extensively in checkChildren(), + // but this catches the big mistakes +} + +/*! + Tests model's implementation of QAbstractItemModel::hasIndex() + */ +void ModelTest::hasIndex() +{ + // Make sure that invalid values returns an invalid index + Q_ASSERT(model->hasIndex(-2, -2) == false); + Q_ASSERT(model->hasIndex(-2, 0) == false); + Q_ASSERT(model->hasIndex(0, -2) == false); + + int rows = model->rowCount(); + int columns = model->columnCount(); + + // check out of bounds + Q_ASSERT(model->hasIndex(rows, columns) == false); + Q_ASSERT(model->hasIndex(rows + 1, columns + 1) == false); + + if (rows > 0) + Q_ASSERT(model->hasIndex(0, 0) == true); + + // hasIndex() is tested more extensively in checkChildren(), + // but this catches the big mistakes +} + +/*! + Tests model's implementation of QAbstractItemModel::index() + */ +void ModelTest::index() +{ + // Make sure that invalid values returns an invalid index + Q_ASSERT(model->index(-2, -2) == QModelIndex()); + Q_ASSERT(model->index(-2, 0) == QModelIndex()); + Q_ASSERT(model->index(0, -2) == QModelIndex()); + + int rows = model->rowCount(); + int columns = model->columnCount(); + + if (rows == 0) + return; + + // Catch off by one errors + Q_ASSERT(model->index(rows, columns) == QModelIndex()); + Q_ASSERT(model->index(0, 0).isValid() == true); + + // Make sure that the same index is *always* returned + QModelIndex a = model->index(0, 0); + QModelIndex b = model->index(0, 0); + Q_ASSERT(a == b); + + // index() is tested more extensively in checkChildren(), + // but this catches the big mistakes +} + +/*! + Tests model's implementation of QAbstractItemModel::parent() + */ +void ModelTest::parent() +{ + // Make sure the model wont crash and will return an invalid QModelIndex + // when asked for the parent of an invalid index. + Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); + + if (model->rowCount() == 0) + return; + + // Column 0 | Column 1 | + // QModelIndex() | | + // \- topIndex | topIndex1 | + // \- childIndex | childIndex1 | + + // Common error test #1, make sure that a top level index has a parent + // that is a invalid QModelIndex. + QModelIndex topIndex = model->index(0, 0, QModelIndex()); + Q_ASSERT(model->parent(topIndex) == QModelIndex()); + + // Common error test #2, make sure that a second level index has a parent + // that is the first level index. + if (model->rowCount(topIndex) > 0) { + QModelIndex childIndex = model->index(0, 0, topIndex); + qDebug("topIndex RCI %x %x %llx", topIndex.row(), topIndex.column(), topIndex.internalId()); + qDebug("topIndex I %llx", topIndex.internalId()); + qDebug("childIndex RCI %x %x %llx", childIndex.row(), childIndex.column(), childIndex.internalId()); + Q_ASSERT(model->parent(childIndex) == topIndex); + } + + // Common error test #3, the second column should NOT have the same children + // as the first column in a row. + // Usually the second column shouldn't have children. + QModelIndex topIndex1 = model->index(0, 1, QModelIndex()); + if (model->rowCount(topIndex1) > 0) { + QModelIndex childIndex = model->index(0, 0, topIndex); + QModelIndex childIndex1 = model->index(0, 0, topIndex1); + Q_ASSERT(childIndex != childIndex1); + } + + // Full test, walk n levels deep through the model making sure that all + // parent's children correctly specify their parent. + checkChildren(QModelIndex()); +} + +/*! + Called from the parent() test. + + A model that returns an index of parent X should also return X when asking + for the parent of the index. + + This recursive function does pretty extensive testing on the whole model in an + effort to catch edge cases. + + This function assumes that rowCount(), columnCount() and index() already work. + If they have a bug it will point it out, but the above tests should have already + found the basic bugs because it is easier to figure out the problem in + those tests then this one. + */ +void ModelTest::checkChildren(const QModelIndex &parent, int currentDepth) +{ + // First just try walking back up the tree. + QModelIndex p = parent; + while (p.isValid()) + p = p.parent(); + + // For models that are dynamically populated + if (model->canFetchMore(parent)) { + fetchingMore = true; + model->fetchMore(parent); + fetchingMore = false; + } + + int rows = model->rowCount(parent); + int columns = model->columnCount(parent); + + if (rows > 0) + Q_ASSERT(model->hasChildren(parent)); + + // Some further testing against rows(), columns(), and hasChildren() + Q_ASSERT(rows >= 0); + Q_ASSERT(columns >= 0); + if (rows > 0) + Q_ASSERT(model->hasChildren(parent) == true); + + //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows + // << "columns:" << columns << "parent column:" << parent.column(); + + Q_ASSERT(model->hasIndex(rows + 1, 0, parent) == false); + for (int r = 0; r < rows; ++r) { + if (model->canFetchMore(parent)) { + fetchingMore = true; + model->fetchMore(parent); + fetchingMore = false; + } + Q_ASSERT(model->hasIndex(r, columns + 1, parent) == false); + for (int c = 0; c < columns; ++c) { + Q_ASSERT(model->hasIndex(r, c, parent) == true); + QModelIndex index = model->index(r, c, parent); + // rowCount() and columnCount() said that it existed... + Q_ASSERT(index.isValid() == true); + + // index() should always return the same index when called twice in a row + QModelIndex modifiedIndex = model->index(r, c, parent); + Q_ASSERT(index == modifiedIndex); + + // Make sure we get the same index if we request it twice in a row + QModelIndex a = model->index(r, c, parent); + QModelIndex b = model->index(r, c, parent); + Q_ASSERT(a == b); + + // Some basic checking on the index that is returned + Q_ASSERT(index.model() == model); + Q_ASSERT(index.row() == r); + Q_ASSERT(index.column() == c); + // While you can technically return a QVariant usually this is a sign + // of an bug in data() Disable if this really is ok in your model. + //Q_ASSERT(model->data(index, Qt::DisplayRole).isValid() == true); + + // If the next test fails here is some somewhat useful debug you play with. + /* + if (model->parent(index) != parent) { + qDebug() << r << c << currentDepth << model->data(index).toString() + << model->data(parent).toString(); + qDebug() << index << parent << model->parent(index); + // And a view that you can even use to show the model. + //QTreeView view; + //view.setModel(model); + //view.show(); + }*/ + + // Check that we can get back our real parent. + QModelIndex p = model->parent(index); + //qDebug() << "child:" << index; + //qDebug() << p; + //qDebug() << parent; + Q_ASSERT(model->parent(index) == parent); + + // recursively go down the children + if (model->hasChildren(index) && currentDepth < 10 ) { + //qDebug() << r << c << "has children" << model->rowCount(index); + checkChildren(index, ++currentDepth); + }/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/ + + // make sure that after testing the children that the index doesn't change. + QModelIndex newerIndex = model->index(r, c, parent); + Q_ASSERT(index == newerIndex); + } + } +} + +/*! + Tests model's implementation of QAbstractItemModel::data() + */ +void ModelTest::data() +{ + // Invalid index should return an invalid qvariant + Q_ASSERT(!model->data(QModelIndex()).isValid()); + + if (model->rowCount() == 0) + return; + + // A valid index should have a valid QVariant data + Q_ASSERT(model->index(0, 0).isValid()); + + // shouldn't be able to set data on an invalid index + Q_ASSERT(model->setData(QModelIndex(), QLatin1String("foo"), Qt::DisplayRole) == false); + + // General Purpose roles that should return a QString + QVariant variant = model->data(model->index(0, 0), Qt::ToolTipRole); + if (variant.isValid()) { + Q_ASSERT(qVariantCanConvert(variant)); + } + variant = model->data(model->index(0, 0), Qt::StatusTipRole); + if (variant.isValid()) { + Q_ASSERT(qVariantCanConvert(variant)); + } + variant = model->data(model->index(0, 0), Qt::WhatsThisRole); + if (variant.isValid()) { + Q_ASSERT(qVariantCanConvert(variant)); + } + + // General Purpose roles that should return a QSize + variant = model->data(model->index(0, 0), Qt::SizeHintRole); + if (variant.isValid()) { + Q_ASSERT(qVariantCanConvert(variant)); + } + + // General Purpose roles that should return a QFont + QVariant fontVariant = model->data(model->index(0, 0), Qt::FontRole); + if (fontVariant.isValid()) { + Q_ASSERT(qVariantCanConvert(fontVariant)); + } + + // Check that the alignment is one we know about + QVariant textAlignmentVariant = model->data(model->index(0, 0), Qt::TextAlignmentRole); + if (textAlignmentVariant.isValid()) { + int alignment = textAlignmentVariant.toInt(); + Q_ASSERT(alignment == Qt::AlignLeft || + alignment == Qt::AlignRight || + alignment == Qt::AlignHCenter || + alignment == Qt::AlignJustify || + alignment == Qt::AlignTop || + alignment == Qt::AlignBottom || + alignment == Qt::AlignVCenter || + alignment == Qt::AlignCenter || + alignment == Qt::AlignAbsolute || + alignment == Qt::AlignLeading || + alignment == Qt::AlignTrailing); + } + + // General Purpose roles that should return a QColor + QVariant colorVariant = model->data(model->index(0, 0), Qt::BackgroundColorRole); + if (colorVariant.isValid()) { + Q_ASSERT(qVariantCanConvert(colorVariant)); + } + + colorVariant = model->data(model->index(0, 0), Qt::TextColorRole); + if (colorVariant.isValid()) { + Q_ASSERT(qVariantCanConvert(colorVariant)); + } + + // Check that the "check state" is one we know about. + QVariant checkStateVariant = model->data(model->index(0, 0), Qt::CheckStateRole); + if (checkStateVariant.isValid()) { + int state = checkStateVariant.toInt(); + Q_ASSERT(state == Qt::Unchecked || + state == Qt::PartiallyChecked || + state == Qt::Checked); + } +} + +/*! + Store what is about to be inserted to make sure it actually happens + + \sa rowsInserted() + */ +void ModelTest::rowsAboutToBeInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(end); + Changing c; + c.parent = parent; + c.oldSize = model->rowCount(parent); + c.last = model->data(model->index(start - 1, 0, parent)); + c.next = model->data(model->index(start, 0, parent)); + insert.push(c); +} + +/*! + Confirm that what was said was going to happen actually did + + \sa rowsAboutToBeInserted() + */ +void ModelTest::rowsInserted(const QModelIndex & parent, int start, int end) +{ + Changing c = insert.pop(); + Q_ASSERT(c.parent == parent); + Q_ASSERT(c.oldSize + (end - start + 1) == model->rowCount(parent)); + Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); + /* + if (c.next != model->data(model->index(end + 1, 0, c.parent))) { + qDebug() << start << end; + for (int i=0; i < model->rowCount(); ++i) + qDebug() << model->index(i, 0).data().toString(); + qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent)); + } + */ + Q_ASSERT(c.next == model->data(model->index(end + 1, 0, c.parent))); +} + +void ModelTest::layoutAboutToBeChanged() +{ + for (int i = 0; i < qBound(0, model->rowCount(), 100); ++i) + changing.append(QPersistentModelIndex(model->index(i, 0))); +} + +void ModelTest::layoutChanged() +{ + for (int i = 0; i < changing.count(); ++i) { + QPersistentModelIndex p = changing[i]; + Q_ASSERT(p == model->index(p.row(), p.column(), p.parent())); + } + changing.clear(); +} + +/*! + Store what is about to be inserted to make sure it actually happens + + \sa rowsRemoved() + */ +void ModelTest::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + Changing c; + c.parent = parent; + c.oldSize = model->rowCount(parent); + c.last = model->data(model->index(start - 1, 0, parent)); + c.next = model->data(model->index(end + 1, 0, parent)); + remove.push(c); +} + +/*! + Confirm that what was said was going to happen actually did + + \sa rowsAboutToBeRemoved() + */ +void ModelTest::rowsRemoved(const QModelIndex & parent, int start, int end) +{ + Changing c = remove.pop(); + Q_ASSERT(c.parent == parent); + Q_ASSERT(c.oldSize - (end - start + 1) == model->rowCount(parent)); + Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); + Q_ASSERT(c.next == model->data(model->index(start, 0, c.parent))); +} + diff --git a/client/modeltest.h b/client/modeltest.h new file mode 100644 index 0000000..38b6b2b --- /dev/null +++ b/client/modeltest.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2007 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Concurrent project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.trolltech.com/products/qt/opensource.html +** +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://www.trolltech.com/products/qt/licensing.html or contact the +** sales department at sales@trolltech.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef MODELTEST_H +#define MODELTEST_H + +#include +#include +#include + +class ModelTest : public QObject +{ + Q_OBJECT + +public: + ModelTest(QAbstractItemModel *model, QObject *parent = 0); + +private Q_SLOTS: + void nonDestructiveBasicTest(); + void rowCount(); + void columnCount(); + void hasIndex(); + void index(); + void parent(); + void data(); + +protected Q_SLOTS: + void runAllTests(); + void layoutAboutToBeChanged(); + void layoutChanged(); + void rowsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void rowsInserted(const QModelIndex & parent, int start, int end); + void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void rowsRemoved(const QModelIndex & parent, int start, int end); + +private: + void checkChildren(const QModelIndex &parent, int currentDepth = 0); + + QAbstractItemModel *model; + + struct Changing + { + QModelIndex parent; + int oldSize; + QVariant last; + QVariant next; + }; + QStack insert; + QStack remove; + + bool fetchingMore; + + QList changing; +}; + +#endif diff --git a/client/modeltest.pri b/client/modeltest.pri new file mode 100644 index 0000000..358a077 --- /dev/null +++ b/client/modeltest.pri @@ -0,0 +1,4 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +SOURCES += $$PWD/modeltest.cpp +HEADERS += $$PWD/modeltest.h diff --git a/client/mythread.cpp b/client/mythread.cpp new file mode 100644 index 0000000..69fe660 --- /dev/null +++ b/client/mythread.cpp @@ -0,0 +1,24 @@ +#include "mythread.h" + + void MyThread::run() + { + int i, j; + + for (i=0; i + +#define NumPorts 2 +#define NumStats 8 + + class MyThread : public QThread + { + Q_OBJECT + + public: + void run(); + + signals: + void portStatsUpdate(int port, void *stats); + + private: + int stats[2][8]; + }; + +#endif diff --git a/client/ostinato.pro b/client/ostinato.pro new file mode 100644 index 0000000..3d27500 --- /dev/null +++ b/client/ostinato.pro @@ -0,0 +1,42 @@ +TEMPLATE = app +CONFIG += qt debug +QT += network +RESOURCES += ostinato.qrc +HEADERS += \ + hexlineedit.h \ + mainwindow.h \ + mythread.h \ + port.h \ + portgroup.h \ + portgrouplist.h \ + portmodel.h \ + portstatsmodel.h \ + portstatswindow.h \ + portswindow.h \ + streamconfigdialog.h \ + streammodel.h + +FORMS += \ + mainwindow.ui \ + portstatswindow.ui \ + portswindow.ui \ + streamconfigdialog.ui + +SOURCES += \ + stream.cpp \ + hexlineedit.cpp \ + main.cpp \ + mainwindow.cpp \ + mythread.cpp \ + port.cpp \ + portgroup.cpp \ + portgrouplist.cpp \ + portmodel.cpp \ + portstatsmodel.cpp \ + portstatswindow.cpp \ + portswindow.cpp \ + streamconfigdialog.cpp \ + streammodel.cpp + +# TODO(LOW): Test only +include(modeltest.pri) diff --git a/client/ostinato.qrc b/client/ostinato.qrc new file mode 100644 index 0000000..59f4930 --- /dev/null +++ b/client/ostinato.qrc @@ -0,0 +1,21 @@ + + + icons/bullet_error.png + icons/bullet_green.png + icons/bullet_orange.png + icons/bullet_red.png + icons/bullet_yellow.png + icons/control_play.png + icons/control_stop.png + icons/magnifier.png + icons/portgroup_add.png + icons/portgroup_connect.png + icons/portgroup_delete.png + icons/portgroup_disconnect.png + icons/sound_mute.png + icons/sound_none.png + icons/stream_add.png + icons/stream_delete.png + icons/stream_edit.png + + diff --git a/client/port.cpp b/client/port.cpp new file mode 100644 index 0000000..755e52e --- /dev/null +++ b/client/port.cpp @@ -0,0 +1,24 @@ +#include "port.h" + +Port::Port(quint32 id, quint32 portGroupId) +{ + mPortId = id; + mPortGroupId = portGroupId; + + mAdminStatus = AdminDisable; + mOperStatus = OperDown; + mControlMode = ControlShared; + + // FIXME(HI): TEST only + for(int i = 0; i < 10; i++) + mPortStats[i] = mPortGroupId*10000+mPortId*100+i; +} + +void Port::insertDummyStreams() +{ + mStreams.append(*(new Stream)); + mStreams[0].setName(QString("%1:%2:0").arg(portGroupId()).arg(id())); + mStreams.append(*(new Stream)); + mStreams[1].setName(QString("%1:%2:1").arg(portGroupId()).arg(id())); +} + diff --git a/client/port.h b/client/port.h new file mode 100644 index 0000000..13795ff --- /dev/null +++ b/client/port.h @@ -0,0 +1,55 @@ +#ifndef _PORT_H +#define _PORT_H + +#include +#include +#include +#include "stream.h" + +class Port { + + friend class StreamModel; + friend class PortStatsModel; + +public: + enum AdminStatus { AdminDisable, AdminEnable }; + enum OperStatus { OperDown, OperUp }; + enum ControlMode { ControlShared, ControlExclusive }; + +private: + quint32 mPortId; + quint32 mPortGroupId; + QList mStreams; + QString mName; + QString mDescription; + QString mUserAlias; // user defined + AdminStatus mAdminStatus; + OperStatus mOperStatus; + ControlMode mControlMode; + + quint32 mPortStats[10]; // FIXME(HI):Hardcoding + +public: + // FIXME(HIGH): default args is a hack for QList operations on Port + Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF); + + quint32 id() const { return mPortId; } + quint32 portGroupId() const { return mPortGroupId; } + const QString& name() const { return mName; } + const QString& description() const { return mDescription; } + const QString& userAlias() const { return mUserAlias; } + + void setName(QString &name) { mName = name; } + void setName(const char* name) { mName = QString(name); } + void setDescription(QString &description) { mDescription = description; } + void setDescription(const char *description) + { mDescription = QString(description); } + + //void setAdminEnable(AdminStatus status) { mAdminStatus = status; } + void setAlias(QString &alias) { mUserAlias = alias; } + //void setExclusive(bool flag); + // FIXME(HIGH): Only for testing + void insertDummyStreams(); +}; + +#endif diff --git a/client/portgroup.cpp b/client/portgroup.cpp new file mode 100644 index 0000000..b7f8eb3 --- /dev/null +++ b/client/portgroup.cpp @@ -0,0 +1,169 @@ +#include "portgroup.h" +#include "../common/protocol.h" + +quint32 PortGroup::mPortGroupAllocId = 0; + +PortGroup::PortGroup(QHostAddress ip, quint16 port) +{ + // Allocate an id for self + mPortGroupId = PortGroup::mPortGroupAllocId++; + + // Init attributes for which we values were passed to us + mServerAddress = ip; + mServerPort = port; + + // Init remaining attributes with defaults + mpSocket = new QTcpSocket(this); + + // TODO: consider using QT's signal-slot autoconnect + connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(on_mpSocket_stateChanged())); + connect(mpSocket, SIGNAL(connected()), this, SLOT(when_connected())); + connect(mpSocket, SIGNAL(disconnected()), this, SLOT(when_disconnected())); + connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(when_error(QAbstractSocket::SocketError))); + connect(mpSocket, SIGNAL(readyRead()), this, SLOT(when_dataAvail())); +} + +PortGroup::~PortGroup() +{ + qDebug("PortGroup Destructor"); + // Disconnect and free TCP mpSocketet etc. + PortGroup::disconnectFromHost(); + delete mpSocket; +} + +void PortGroup::connectToHost(QHostAddress ip, quint16 port) +{ + mServerAddress = ip; + mServerPort = port; + + PortGroup::connectToHost(); +} + +void PortGroup::connectToHost() +{ + qDebug("PortGroup::connectToHost()"); + mpSocket->connectToHost(mServerAddress, mServerPort); +} + +void PortGroup::disconnectFromHost() +{ + mpSocket->disconnectFromHost(); +} + +// -------------------------------------------- +// Private Methods +// -------------------------------------------- +void PortGroup::ProcessMsg(const char *msg, quint32 size) +{ + tCommHdr *hdr; + // TODO: For now, assuming we'll get a complete msg + // but need to fix this as this is a TCP stream + + hdr = (tCommHdr*) msg; + + if (hdr->ver != 1) // FIXME:hardcoding + { + qDebug("Rcvd msg with invalid version %d\n", hdr->ver); + goto _exit; + } + + qDebug("msgType - %x\n", NTOHS(hdr->msgType)); + switch (NTOHS(hdr->msgType)) + { + case e_MT_CapabilityInfo: + ProcessCapabilityInfo(msg+sizeof(tCommHdr), + NTOHS(hdr->msgLen)-sizeof(tCommHdr)); + break; + + default: + qDebug("Rcvd msg with unrecognized msgType %d\n", NTOHS(hdr->msgType)); + } + +_exit: + return; +} + +void PortGroup::ProcessCapabilityInfo(const char *msg, qint32 size) +{ + tTlvPortCapability *cap = (tTlvPortCapability*) msg; + Port *p; + + emit portListAboutToBeChanged(mPortGroupId); + + while (size) + { + qDebug("size = %d, tlvType = %d, tlvLen = %d\n", + size, NTOHS(cap->tlvType), NTOHS(cap->tlvLen)); + if (NTOHS(cap->tlvType) != e_TT_PortCapability) + { + qDebug("Unrecognized TLV Type %d\n", NTOHS(cap->tlvType)); + goto _next; + } + + p = new Port(NTOHL(cap->port), mPortGroupId); + p->setName(cap->name); + p->setDescription(cap->desc); + p->insertDummyStreams(); // FIXME: only for testing + qDebug("before port append\n"); + mPorts.append(*p); + +_next: + size -= NTOHS(cap->tlvLen); + cap = (tTlvPortCapability*)((char *)(cap) + NTOHS(cap->tlvLen)); + } + + emit portListChanged(mPortGroupId); + + return; +} + +// ------------------------------------------------ +// Slots +// ------------------------------------------------ +void PortGroup::on_mpSocket_stateChanged() +{ + qDebug("state changed"); + emit portGroupDataChanged(this); +} + +void PortGroup::when_connected() +{ + qDebug("connected\n"); + + emit portGroupDataChanged(this); + + // Ask for Port Capability + tCommHdr pkt; + pkt.ver = 1; + pkt.resv1 = 0; + pkt.resv2 = 0; + pkt.msgType = HTONS(e_MT_CapabilityReq); + pkt.msgLen = HTONS(8); + + mpSocket->write((char*) &pkt, sizeof(pkt)); +} + +void PortGroup::when_disconnected() +{ + qDebug("disconnected\n"); + emit portListAboutToBeChanged(mPortGroupId); + mPorts.clear(); + emit portListChanged(mPortGroupId); + emit portGroupDataChanged(this); +} + +void PortGroup::when_error(QAbstractSocket::SocketError socketError) +{ + qDebug("error\n"); + emit portGroupDataChanged(this); +} + +void PortGroup::when_dataAvail() +{ + qDebug("dataAvail\n"); + + QByteArray msg = mpSocket->read(1024); // FIXME: hardcoding + ProcessMsg(msg.constData(), msg.size()); +} + + diff --git a/client/portgroup.h b/client/portgroup.h new file mode 100644 index 0000000..8f5c1e3 --- /dev/null +++ b/client/portgroup.h @@ -0,0 +1,66 @@ +#ifndef _PORT_GROUP_H +#define _PORT_GROUP_H + +#include "port.h" +#include +#include + +/* TODO +HIGH +MED +LOW +- Allow hostnames in addition to IP Address as "server address" +*/ + +#define DEFAULT_SERVER_PORT 7878 + +class PortGroup : public QObject { + Q_OBJECT + +private: + quint32 mPortGroupId; + static quint32 mPortGroupAllocId; + QString mUserAlias; // user defined + + QTcpSocket *mpSocket; + QHostAddress mServerAddress; + quint16 mServerPort; +public: // FIXME(HIGH): member access + QList mPorts; + +public: + PortGroup(QHostAddress ip = QHostAddress::LocalHost, + quint16 port = DEFAULT_SERVER_PORT); + ~PortGroup(); + + void connectToHost(); + void connectToHost(QHostAddress ip, quint16 port); + void disconnectFromHost(); + + int numPorts() const { return mPorts.size(); } + quint32 id() const { return mPortGroupId; } + const QHostAddress& serverAddress() const { return mServerAddress; } + quint16 serverPort() const { return mServerPort; } + const QString& userAlias() const { return mUserAlias; } + QAbstractSocket::SocketState state() const { return mpSocket->state(); } + + void setUserAlias(QString alias) { mUserAlias = alias; }; + +signals: + void portGroupDataChanged(PortGroup* portGroup); + void portListAboutToBeChanged(quint32 portGroupId); + void portListChanged(quint32 portGroupId); + +private slots: + void on_mpSocket_stateChanged(); + void when_connected(); + void when_disconnected(); + void when_error(QAbstractSocket::SocketError socketError); + void when_dataAvail(); + +private: + void ProcessCapabilityInfo(const char *msg, qint32 size); + void ProcessMsg(const char *msg, quint32 size); +}; + +#endif diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp new file mode 100644 index 0000000..06df02d --- /dev/null +++ b/client/portgrouplist.cpp @@ -0,0 +1,108 @@ +#include "portgrouplist.h" + +// TODO(LOW): Remove +#include + +PortGroupList::PortGroupList() + : mPortGroupListModel(this), + mStreamListModel(this), + mPortStatsModel(this, this) +{ + PortGroup *pg; + + // TODO(LOW): Remove + new ModelTest(getStreamModel()); + new ModelTest(getPortModel()); + new ModelTest(getPortStatsModel()); + + // Add the "Local" Port Group + pg = new PortGroup; + addPortGroup(*pg); +} + +bool PortGroupList::isPortGroup(const QModelIndex& index) +{ + return mPortGroupListModel.isPortGroup(index); +} + +bool PortGroupList::isPort(const QModelIndex& index) +{ + return mPortGroupListModel.isPort(index); +} + +PortGroup& PortGroupList::portGroup(const QModelIndex& index) +{ + if (mPortGroupListModel.isPortGroup(index)) + { + //return *(mPortGroups[mPortGroupListModel.portGroupId(index)]); + return *(mPortGroups[index.row()]); + } +#if 0 // FIXME(MED) + else + return NULL; +#endif +} + +Port& PortGroupList::port(const QModelIndex& index) +{ + if (mPortGroupListModel.isPort(index)) + { + return (mPortGroups.at(index.parent().row())-> + mPorts[index.row()]); + } +#if 0 // FIXME(MED) + else + return NULL; +#endif +} + +void PortGroupList::addPortGroup(PortGroup &portGroup) +{ + mPortGroupListModel.portGroupAboutToBeAppended(); + + connect(&portGroup, SIGNAL(portGroupDataChanged(PortGroup*)), + &mPortGroupListModel, SLOT(when_portGroupDataChanged(PortGroup*))); +#if 0 + connect(&portGroup, SIGNAL(portListAboutToBeChanged(quint32)), + &mPortGroupListModel, SLOT(triggerLayoutAboutToBeChanged())); + connect(&portGroup, SIGNAL(portListChanged(quint32)), + &mPortGroupListModel, SLOT(triggerLayoutChanged())); +#endif + connect(&portGroup, SIGNAL(portListChanged(quint32)), + &mPortGroupListModel, SLOT(when_portListChanged())); + + connect(&portGroup, SIGNAL(portListChanged(quint32)), + &mPortStatsModel, SLOT(when_portListChanged())); + + mPortGroups.append(&portGroup); + portGroup.connectToHost(); + + mPortGroupListModel.portGroupAppended(); + + mPortStatsModel.when_portListChanged(); +} + +void PortGroupList::removePortGroup(PortGroup &portGroup) +{ + mPortGroupListModel.portGroupAboutToBeRemoved(&portGroup); + + PortGroup* pg = mPortGroups.takeAt(mPortGroups.indexOf(&portGroup)); + qDebug("after takeAt()"); + mPortGroupListModel.portGroupRemoved(); + + delete pg; + + mPortStatsModel.when_portListChanged(); +} + +//.................... +// Private Methods +//.................... +int PortGroupList::indexOfPortGroup(quint32 portGroupId) +{ + for (int i = 0; i < mPortGroups.size(); i++) { + if (mPortGroups.value(i)->id() == portGroupId) + return i; + } + return -1; +} diff --git a/client/portgrouplist.h b/client/portgrouplist.h new file mode 100644 index 0000000..1e5add9 --- /dev/null +++ b/client/portgrouplist.h @@ -0,0 +1,47 @@ +#ifndef _PORT_GROUP_LIST_H +#define _PORT_GROUP_LIST_H + +#include "portgroup.h" +#include +#include +#include "portmodel.h" +#include "streammodel.h" +#include "portstatsmodel.h" + +class PortModel; +class StreamModel; + +class PortGroupList : public QObject { + + Q_OBJECT + + friend class PortModel; + friend class StreamModel; + friend class PortStatsModel; + + QList mPortGroups; + PortModel mPortGroupListModel; + StreamModel mStreamListModel; + PortStatsModel mPortStatsModel; + +// Methods +public: + PortGroupList::PortGroupList(); + + PortModel* getPortModel() { return &mPortGroupListModel; } + PortStatsModel* getPortStatsModel() { return &mPortStatsModel; } + StreamModel* getStreamModel() { return &mStreamListModel; } + bool isPortGroup(const QModelIndex& index); + bool isPort(const QModelIndex& index); + PortGroup& portGroup(const QModelIndex& index); + Port& port(const QModelIndex& index); + + void addPortGroup(PortGroup &portGroup); + void removePortGroup(PortGroup &portGroup); + +private: + int indexOfPortGroup(quint32 portGroupId); + +}; + +#endif diff --git a/client/portgrouplistmodel.h b/client/portgrouplistmodel.h new file mode 100644 index 0000000..4242539 --- /dev/null +++ b/client/portgrouplistmodel.h @@ -0,0 +1,55 @@ +#ifndef _PORT_GROUP_LIST_H +#define _PORT_GROUP_LIST_H + +#include "portgroup.h" +#include + +/* ----------------------------------------------------------- +** NOTE: FILE NOT USED 'COZ MOC DOESN'T SUPPORT NESTED CLASSES +*-------------------------------------------------------------*/ + + +class PortGroupList; + +class PortGroupList : public QObject { + + Q_OBJECT + + class PortListModel : public QAbstractItemModel + { + // This is currently a read only model + Q_OBJECT + + PortGroupList *pgl; // FIXME(HIGH): rename member + + public: + PortListModel(PortGroupList *p, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; + QModelIndex parent(const QModelIndex &index) const; + + friend class PortGroupList; // FIXME(MED): Review need for friend + }; + + friend class PortListModel; + + QList mPortGroups; + PortListModel mPortGroupListModel; + +// Methods +public: + PortGroupList::PortGroupList(); + QAbstractItemModel* getModel(); + int addPortGroup(PortGroup &portGroup); + int removePortGroup(PortGroup &portGroup); + +private slots: + void when_portlist_dataChanged(); +}; + +#endif diff --git a/client/portlistmodel.cpp b/client/portlistmodel.cpp new file mode 100644 index 0000000..df53fb9 --- /dev/null +++ b/client/portlistmodel.cpp @@ -0,0 +1,191 @@ +#include "portlistmodel.h" + +----------------------- +This file is not used +----------------------- + +PortListModel::PortListModel(QObject *parent) + : QAbstractItemModel(parent) +{ + portList = new QList; + +#if 0 // FIXME: Dummy data only for testing; to be removed + PortGroup pg; + + pg.name = "A"; + pg.isLocal = TRUE; + pg.numPorts = 3; + pg.port = new Port[pg.numPorts]; + pg.port[0].portId = 0; + pg.port[0].name = "A0"; + pg.port[0].desc = "a0a0a0a0a0a0"; + pg.port[1].portId = 1; + pg.port[1].name = "A1"; + pg.port[1].desc = "a1a1a1a1a1a1"; + pg.port[2].portId = 2; + pg.port[2].name = "A2"; + pg.port[2].desc = "a2a2a2a2a2a2"; + + portList->append(pg); + + pg.name = "B"; + pg.isLocal = FALSE; + pg.numPorts = 2; + pg.port = new Port[pg.numPorts]; + pg.port[0].portId = 0; + pg.port[0].name = "B0"; + pg.port[0].desc = "b0b0b0b0b0b0"; + pg.port[1].portId = 1; + pg.port[1].name = "B1"; + pg.port[1].desc = "b1b1b1b1b1b1"; + + portList->append(pg); +#endif + // Do I need to do anything here? +} + +int PortListModel::rowCount(const QModelIndex &parent) const +{ + // qDebug("RowCount Enter\n"); + if (!parent.isValid()) + { + // Top Level Item + // qDebug("RowCount top\n"); + // qDebug("RowCount Exit: %d\n", portList->size()); + return portList->size(); + } + // qDebug("RowCount non top %d, %d, %llx\n", + // parent.row(), parent.column(), parent.internalId()); + + quint16 p = parent.internalId() & 0xFFFF; + if (p == 0xFFFF) + { + // qDebug("RowCount Exit: %d\n", portList->at(parent.row()).numPorts); + return portList->at(parent.row()).numPorts; + } + else + { + // Leaf Item + return 0; + } +} + +int PortListModel::columnCount(const QModelIndex &parent ) const +{ + return 1; // FIXME: hardcoding +} + +Qt::ItemFlags PortListModel::flags(const QModelIndex &index) const +{ + return QAbstractItemModel::flags(index); // FIXME: no need for this func +} +QVariant PortListModel::data(const QModelIndex &index, int role) const +{ + //qDebug("Enter PortListModel data\n"); + // Check for a valid index + if (!index.isValid()) + return QVariant(); + + + // Check role + if ((role == Qt::DisplayRole)) + { +#if 0 // Only for debug + qDebug("Exit PortListModel data\n"); + return "Testing"; // FIXME: for dbg only +#endif + + QModelIndex parent = index.parent(); + + if (!parent.isValid()) + { + // Top Level Item + return QString("%1 (%2) [%3]"). + arg(portList->at(index.row()).name). + arg(portList->at(index.row()).isLocal == TRUE? "LOCAL" : "REMOTE"). + arg(portList->at(index.row()).numPorts); + } + return QString("%1: %2 (%3)"). + arg(portList->at(parent.row()).port[index.row()].portId). + arg(portList->at(parent.row()).port[index.row()].name). + arg(portList->at(parent.row()).port[index.row()].desc); + } + else + return QVariant(); +} + +QVariant PortListModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QVariant(); + else + return QString("%1").arg(section+1); +} + +QModelIndex PortListModel::index (int row, int col, + const QModelIndex & parent) const +{ +#if 0 + if (!hasIndex(row, col, parent)) + return QModelIndex(); +#endif + + //qDebug("index: R=%d, C=%d, PR=%d, PC=%d, PID=%llx\n", + // row, col, parent.row(), parent.column(), parent.internalId()); + + if (!parent.isValid()) + { + // Top Level Item + quint16 pg = row, p = 0xFFFF; + quint32 id = (pg << 16) | p; + //qDebug("index (top) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); + + return createIndex(row, col, id); + } + else + { + quint16 pg = parent.row(), p = row; + quint32 id = (pg << 16) | p; + //qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); + + return createIndex(row, col, id); + } +} + +QModelIndex PortListModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + //qDebug("parent: R=%d, C=%d ID=%llx\n", + // index.row(), index.column(), index.internalId()); + + quint16 pg = index.internalId() >> 16; + quint16 p = index.internalId() & 0x0000FFFF; + + //qDebug("parent dbg: PG=%d, P=%d\n", pg, p); + + if (p == 0xFFFF) + { + //qDebug("parent ret: NULL\n"); + // Top Level Item - PG + return QModelIndex(); + } + + quint32 id = (pg << 16) | 0xFFFF; + //qDebug("parent ret: R=%d, C=%d, ID=%x\n", + // pg, 0, id); + + return createIndex(pg, 0, id); + +} + +void PortListModel::doRefresh() +{ + emit layoutChanged(); +} + + diff --git a/client/portlistmodel.h b/client/portlistmodel.h new file mode 100644 index 0000000..45a07bc --- /dev/null +++ b/client/portlistmodel.h @@ -0,0 +1,37 @@ +#ifndef _PORT_LIST_MODEL_H +#define _PORT_LIST_MODEL_H + + + ----------------- + This file is not used + ------------------ + +#include +#include +#include "portgroup.h" + +static QStringList PortListCols = (QStringList() + << "Name" +); + +class PortListModel : public QAbstractItemModel +{ + Q_OBJECT + + public: + //PortListModel(QObject *parent = 0) : QAbstractItemModel(parent) {} + PortListModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; + QModelIndex parent(const QModelIndex &index) const; + + void doRefresh(); // FIXME: temp till model exports functions to insert rows + QList *portList; // FIXME: this shd be private +}; + +#endif diff --git a/client/portmodel.cpp b/client/portmodel.cpp new file mode 100644 index 0000000..61f9be8 --- /dev/null +++ b/client/portmodel.cpp @@ -0,0 +1,314 @@ +#include "portmodel.h" +#include "portgrouplist.h" +#include + +#if 0 +#define DBG0(x) qDebug(x) +#define DBG1(x, p1) qDebug(x, (p1)) +#else +#define DBG0(x) {} +#define DBG1(x, p1) {} +#endif + +PortModel::PortModel(PortGroupList *p, QObject *parent) + : QAbstractItemModel(parent) +{ + pgl = p; +} + +int PortModel::rowCount(const QModelIndex &parent) const +{ + // qDebug("RowCount Enter\n"); + if (!parent.isValid()) + { + // Top Level Item + //qDebug("RowCount (Top) Exit: %d\n", pgl->mPortGroups.size()); + return pgl->mPortGroups.size(); + } + // qDebug("RowCount non top %d, %d, %llx\n", + // parent.row(), parent.column(), parent.internalId()); + + quint16 pg = (parent.internalId() >> 16) & 0xFFFF; + quint16 p = parent.internalId() & 0xFFFF; + if (p == 0xFFFF) + { +#if 0 // wrong code? + int count = 0; + foreach(PortGroup *pg, pgl->mPortGroups) + { + count += pg->numPorts(); + } + //qDebug("RowCount (Mid) Exit: %d\n", count); + return count; +#endif + if (parent.column() == 0) + return pgl->mPortGroups.value(pgl->indexOfPortGroup(pg))->numPorts(); + else + return 0; + } + else + { + // Leaf Item + return 0; + } +} + +int PortModel::columnCount(const QModelIndex &parent ) const +{ + return 1; // FIXME: hardcoding +} + +Qt::ItemFlags PortModel::flags(const QModelIndex &index) const +{ + return QAbstractItemModel::flags(index); // FIXME: no need for this func +} +QVariant PortModel::data(const QModelIndex &index, int role) const +{ + + DBG0("Enter PortModel data\n"); + + // Check for a valid index + if (!index.isValid()) + return QVariant(); + + DBG1("PortModel::data(index).row = %d", index.row()); + DBG1("PortModel::data(index).column = %0d", index.column()); + DBG1("PortModel::data(index).internalId = %08llx", index.internalId()); + + QModelIndex parent = index.parent(); + + if (!parent.isValid()) + { + // Top Level Item - PortGroup + if ((role == Qt::DisplayRole)) + { + DBG0("Exit PortModel data 1\n"); + return QString("Port Group %1: %2 [%3:%4] (%5)"). + arg(pgl->mPortGroups.at(index.row())->id()). + arg(pgl->mPortGroups.at(index.row())->userAlias()). + arg(pgl->mPortGroups.at(index.row())->serverAddress().toString()). + arg(pgl->mPortGroups.at(index.row())->serverPort()). + arg(pgl->mPortGroups.value(index.row())->numPorts()); + } + else if ((role == Qt::DecorationRole)) + { + DBG0("Exit PortModel data 2\n"); + switch(pgl->mPortGroups.at(index.row())->state()) + { + case QAbstractSocket::UnconnectedState: + return QIcon(":/icons/bullet_red.png"); + + case QAbstractSocket::HostLookupState: + return QIcon(":/icons/bullet_yellow.png"); + + case QAbstractSocket::ConnectingState: + case QAbstractSocket::ClosingState: + return QIcon(":/icons/bullet_orange.png"); + + case QAbstractSocket::ConnectedState: + return QIcon(":/icons/bullet_green.png"); + + + case QAbstractSocket::BoundState: + case QAbstractSocket::ListeningState: + default: + return QIcon(":/icons/bullet_error.png"); + } + } + else + { + DBG0("Exit PortModel data 3\n"); + return QVariant(); + } + } + else + { + // Non Top Level - Port + if ((role == Qt::DisplayRole)) + { + DBG0("Exit PortModel data 4\n"); + if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) + return QVariant(); + + return QString("Port %1: %2 [%3] (%4)"). + arg(pgl->mPortGroups.at( + parent.row())->mPorts[index.row()].id()). + arg(pgl->mPortGroups.at( + parent.row())->mPorts[index.row()].name()). + arg(QHostAddress("0.0.0.0").toString()). // FIXME(LOW) + arg(pgl->mPortGroups.at( + parent.row())->mPorts[index.row()].description()); + } + else if ((role == Qt::DecorationRole)) + { + DBG0("Exit PortModel data 5\n"); + if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) + return QVariant(); + return QIcon(":/icons/bullet_green.png"); + } + else + { + DBG0("Exit PortModel data 6\n"); + return QVariant(); + } + } +} + +QVariant PortModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QVariant(); + else + return QString("Name"); +} + +QModelIndex PortModel::index (int row, int col, + const QModelIndex & parent) const +{ + if (!hasIndex(row, col, parent)) + return QModelIndex(); + + //qDebug("index: R=%d, C=%d, PR=%d, PC=%d, PID=%llx\n", + // row, col, parent.row(), parent.column(), parent.internalId()); + + if (!parent.isValid()) + { + // Top Level Item + quint16 pg = pgl->mPortGroups.value(row)->id(), p = 0xFFFF; + quint32 id = (pg << 16) | p; + //qDebug("index (top) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); + + return createIndex(row, col, id); + } + else + { + quint16 pg = parent.internalId() >> 16; + quint16 p = pgl->mPortGroups.value(parent.row())->mPorts.value(row).id(); + quint32 id = (pg << 16) | p; + //qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); + + return createIndex(row, col, id); + } +} + +QModelIndex PortModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + //qDebug("parent: R=%d, C=%d ID=%llx\n", + // index.row(), index.column(), index.internalId()); + + quint16 pg = index.internalId() >> 16; + quint16 p = index.internalId() & 0x0000FFFF; + + //qDebug("parent dbg: PG=%d, P=%d\n", pg, p); + + if (p == 0xFFFF) + { + //qDebug("parent ret: NULL\n"); + // Top Level Item - PG + return QModelIndex(); + } + + quint32 id = (pg << 16) | 0xFFFF; + //qDebug("parent ret: R=%d, C=%d, ID=%x\n", pg, 0, id); + + return createIndex(pgl->indexOfPortGroup(pg), 0, id); + +} + +bool PortModel::isPortGroup(const QModelIndex& index) +{ + if ((index.internalId() & 0xFFFF) == 0xFFFF) + return true; + else + return false; +} + +bool PortModel::isPort(const QModelIndex& index) +{ + if ((index.internalId() & 0xFFFF) != 0xFFFF) + return true; + else + return false; +} + +quint32 PortModel::portGroupId(const QModelIndex& index) +{ + return (index.internalId()) >> 16 & 0xFFFF; +} + +quint32 PortModel::portId(const QModelIndex& index) +{ + return (index.internalId()) & 0xFFFF; +} + + + +// ---------------------------------------------- +// Slots +// ---------------------------------------------- +void PortModel::when_portGroupDataChanged(PortGroup* portGroup) +{ + QModelIndex index; + + if (!pgl->mPortGroups.contains(portGroup)) + { + qDebug("when_portGroupDataChanged(): pg not in list - do nothing"); + return; + } + + qDebug("when_portGroupDataChanged pgid = %d", portGroup->id()); + qDebug("when_portGroupDataChanged idx = %d", pgl->mPortGroups.indexOf(portGroup)); + + index = createIndex(pgl->mPortGroups.indexOf(portGroup), 0, + (portGroup->id() << 16) | 0xFFFF); + emit dataChanged(index, index); +} + +void PortModel::portGroupAboutToBeAppended() +{ + int row; + + row = pgl->mPortGroups.size(); + beginInsertRows(QModelIndex(), row, row); +} + +void PortModel::portGroupAppended() +{ + endInsertRows(); +} + +void PortModel::portGroupAboutToBeRemoved(PortGroup *portGroup) +{ + int row; + + row = pgl->mPortGroups.indexOf(portGroup); + beginRemoveRows(QModelIndex(), row, row); +} + +void PortModel::portGroupRemoved() +{ + endRemoveRows(); +} + +#if 0 +void PortModel::triggerLayoutAboutToBeChanged() +{ + emit layoutAboutToBeChanged(); +} + +void PortModel::triggerLayoutChanged() +{ + emit layoutChanged(); +} +#endif + +void PortModel::when_portListChanged() +{ + reset(); +} diff --git a/client/portmodel.h b/client/portmodel.h new file mode 100644 index 0000000..b68acdc --- /dev/null +++ b/client/portmodel.h @@ -0,0 +1,51 @@ +#ifndef _PORT_MODEL_H +#define _PORT_MODEL_H + +#include + +class PortGroupList; +class PortGroup; + +class PortModel : public QAbstractItemModel +{ + Q_OBJECT + + friend class PortGroupList; + + PortGroupList *pgl; + + public: + PortModel(PortGroupList *p, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; + QModelIndex parent(const QModelIndex &index) const; + + bool isPortGroup(const QModelIndex& index); + bool isPort(const QModelIndex& index); + quint32 portGroupId(const QModelIndex& index); + quint32 portId(const QModelIndex& index); + + +private slots: + void when_portGroupDataChanged(PortGroup *portGroup); + + void portGroupAboutToBeAppended(); + void portGroupAppended(); + void portGroupAboutToBeRemoved(PortGroup *portGroup); + void portGroupRemoved(); + + void when_portListChanged(); + +#if 0 + void triggerLayoutAboutToBeChanged(); + void triggerLayoutChanged(); +#endif + +}; + +#endif diff --git a/client/portstatsfilter.ui b/client/portstatsfilter.ui new file mode 100644 index 0000000..3dae66d --- /dev/null +++ b/client/portstatsfilter.ui @@ -0,0 +1,124 @@ + + Dialog + + + + 0 + 0 + 402 + 275 + + + + Dialog + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + > + + + + + + + < + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok + + + + + + + lvAllPorts + tbFilterIn + tbFilterOut + lvFilteredPorts + buttonBox + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/client/portstatsfilterdialog.cpp b/client/portstatsfilterdialog.cpp new file mode 100644 index 0000000..8845dd2 --- /dev/null +++ b/client/portstatsfilterdialog.cpp @@ -0,0 +1,9 @@ +#include "portstatsfilterdialog.h" + +PortStatsFilterDialog::PortStatsFilterDialog(AbstractItemModel *allPortsModel, + QWidget *parent) +{ + setupUi(this); + + lvAllPorts->setModel(allPortsModel); +} diff --git a/client/portstatsfilterdialog.h b/client/portstatsfilterdialog.h new file mode 100644 index 0000000..c180f34 --- /dev/null +++ b/client/portstatsfilterdialog.h @@ -0,0 +1,19 @@ +#ifndef _PORT_STATS_FILTER_DIALOG_H +#define _PORT_STATS_FILTER_DIALOG_H + +#include +#include +#include "ui_portstatsfilterdialog.h" +#include "portgrouplist.h" + +class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog +{ + Q_OBJECT + +public: + PortStatsFilterDialog(AbstractItemModel *allPortsModel, + QWidget *parent = 0); +}; + +#endif + diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp new file mode 100644 index 0000000..c67c7e4 --- /dev/null +++ b/client/portstatsmodel.cpp @@ -0,0 +1,119 @@ +#include "portstatsmodel.h" +#include "portgrouplist.h" + +PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent) + : QAbstractTableModel(parent) +{ + pgl = p; +} + +int PortStatsModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + if (numPorts.isEmpty()) + return 0; + + if (numPorts.last() == 0) + return 0; + + return (int) e_STAT_MAX; +} + +int PortStatsModel::columnCount(const QModelIndex &parent ) const +{ + if (parent.isValid()) + return 0; + else + if (numPorts.isEmpty()) + return 0; + else + return numPorts.last(); +} + +QVariant PortStatsModel::data(const QModelIndex &index, int role) const +{ + int pgidx, pidx, portNum; + + // Check for a valid index + if (!index.isValid()) + return QVariant(); + + // Check for row/column limits + if (index.row() >= e_STAT_MAX) + return QVariant(); + + if (numPorts.isEmpty()) + return QVariant(); + + if (index.column() >= (numPorts.last())) + return QVariant(); + + // TODO(LOW): Optimize using binary search: see qLowerBound() + portNum = index.column() + 1; + for (pgidx = 0; pgidx < numPorts.size(); pgidx++) + if (portNum <= numPorts.at(pgidx)) + break; + + if (pgidx) + { + if (numPorts.at(pgidx -1)) + pidx = (portNum - 1) % numPorts.at(pgidx - 1); + else + pidx = portNum - 1; + } + else + pidx = portNum - 1; + + //qDebug("PSM: %d - %d, %d", index.column(), pgidx, pidx); + + // Check role + if (role == Qt::DisplayRole) + return pgl->mPortGroups.at(pgidx)->mPorts.at(pidx).mPortStats[index.row()]; + else + return QVariant(); + +} + +QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QString("Port %1").arg(section); + else + return PortStatName.at(section); +} + +// +// Slots +// +void PortStatsModel::when_portListChanged() +{ + int i, count = 0; + + // recalc numPorts + while (numPorts.size()) + numPorts.removeFirst(); + + for (i = 0; i < pgl->mPortGroups.size(); i++) + { + count += pgl->mPortGroups.at(i)->numPorts(); + numPorts.append(count); + } + + reset(); +} + +void PortStatsModel::on_portStatsUpdate(int port, void*stats) +{ + // FIXME(MED): update only the changed port not all + QModelIndex topLeft = index(port, 0, QModelIndex()); + QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex()); + + emit dataChanged(topLeft, bottomRight); +} + + diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h new file mode 100644 index 0000000..6bf5c5a --- /dev/null +++ b/client/portstatsmodel.h @@ -0,0 +1,59 @@ +#ifndef _PORT_STATS_MODEL_H +#define _PORT_STATS_MODEL_H + +#include +#include + +typedef enum { + e_STAT_FRAMES_RCVD = 0, + e_STAT_FRAMES_SENT, + e_STAT_FRAME_SEND_RATE, + e_STAT_FRAME_RECV_RATE, + e_STAT_BYTES_RCVD, + e_STAT_BYTES_SENT, + e_STAT_BYTE_SEND_RATE, + e_STAT_BYTE_RECV_RATE, + e_STAT_MAX +} PortStat; + +static QStringList PortStatName = (QStringList() + << "Frames Received" + << "Frames Sent" + << "Frame Send Rate (fps)" + << "Frame Receive Rate (fps)" + << "Bytes Received" + << "Bytes Sent" + << "Byte Send Rate (Bps)" + << "Byte Receive Rate (Bps)" +); + +class PortGroupList; + +class PortStatsModel : public QAbstractTableModel +{ + Q_OBJECT + + PortGroupList *pgl; + + public: + PortStatsModel(PortGroupList *p, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + public slots: + void when_portListChanged(); + void on_portStatsUpdate(int port, void*stats); + + private: + // numPorts stores the num of ports per portgroup + // in the same order as the portgroups are index in the pgl + // Also it stores them as cumulative totals + QList numPorts; + +}; + +#endif diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp new file mode 100644 index 0000000..594209e --- /dev/null +++ b/client/portstatswindow.cpp @@ -0,0 +1,15 @@ +#include "portstatswindow.h" +#include "portstatsmodel.h" + +//PortStatsWindow::PortStatsWindow(QWidget *parent) : QDialog (parent) +PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent) +{ + setupUi(this); + + tvPortStats->setModel(pgl->getPortStatsModel()); + +} + +PortStatsWindow::~PortStatsWindow() +{ +} diff --git a/client/portstatswindow.h b/client/portstatswindow.h new file mode 100644 index 0000000..2cec09a --- /dev/null +++ b/client/portstatswindow.h @@ -0,0 +1,21 @@ +#ifndef _PORT_STATS_WINDOW_H +#define _PORT_STATS_WINDOW_H + +#include +#include +#include "ui_portstatswindow.h" +#include "portgrouplist.h" + +class PortStatsWindow : public QDialog, public Ui::PortStatsWindow +{ + Q_OBJECT + +public: + PortStatsWindow(PortGroupList *pgl, QWidget *parent = 0); + ~PortStatsWindow(); +private: + QAbstractItemModel *model; +}; + +#endif + diff --git a/client/portstatswindow.ui b/client/portstatswindow.ui new file mode 100644 index 0000000..f3dff15 --- /dev/null +++ b/client/portstatswindow.ui @@ -0,0 +1,133 @@ + + PortStatsWindow + + + + 0 + 0 + 502 + 415 + + + + Form + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Start Transmit + + + Stop Transmit + + + Start Transmit + + + :/icons/control_play.png + + + + + + + Stop Transmit + + + Stop Transmit + + + Stop Trasmit + + + :/icons/control_stop.png + + + + + + + Clear + + + + + + + Clear All + + + + + + + Start Capture + + + :/icons/sound_none.png + + + + + + + Stop Capture + + + :/icons/sound_mute.png + + + + + + + View Capture + + + :/icons/magnifier.png + + + + + + + Qt::Vertical + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + diff --git a/client/portswindow.cpp b/client/portswindow.cpp new file mode 100644 index 0000000..c316b0d --- /dev/null +++ b/client/portswindow.cpp @@ -0,0 +1,320 @@ +#include "portswindow.h" +#include "streamlistmodel.h" +#include "streamconfigdialog.h" +#include +#include + +PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) +{ + //slm = new StreamListModel(); + //plm = new PortGroupList(); + plm = pgl; + + setupUi(this); + + tvPortList->addAction(actionNew_Port_Group); + tvPortList->addAction(actionDelete_Port_Group); + tvPortList->addAction(actionConnect_Port_Group); + tvPortList->addAction(actionDisconnect_Port_Group); + + tvStreamList->addAction(actionNew_Stream); + tvStreamList->addAction(actionDelete_Stream); + + tvStreamList->setModel(plm->getStreamModel()); + tvPortList->setModel(plm->getPortModel()); + + connect( plm->getPortModel(), + SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_portModel_dataChanged(const QModelIndex&, + const QModelIndex&))); + connect( tvPortList->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_portView_currentChanged(const QModelIndex&, + const QModelIndex&))); + connect( tvStreamList->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_streamView_currentChanged(const QModelIndex&, + const QModelIndex&))); + connect( tvStreamList->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, SLOT(when_streamView_selectionChanged())); + connect( tvPortList->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&))); +} + +PortsWindow::~PortsWindow() +{ + delete plm; +} + +void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) +{ + StreamConfigDialog *scd; + + if (!index.isValid()) + { + qDebug("%s: invalid index", __FUNCTION__); + return; + } + // FIXME(MED): This way of passing params must be changed + scd = new StreamConfigDialog(plm->getStreamModel()->currentPortStreamList(), + (uint) index.row(), this); + qDebug("stream list activated\n"); + scd->exec(); // TODO: chk retval + delete scd; +} + +void PortsWindow::when_portView_currentChanged(const QModelIndex& current, + const QModelIndex& previous) +{ + updatePortViewActions(current); + + if (!current.isValid()) + { + qDebug("setting stacked widget to blank page"); + swDetail->setCurrentIndex(2); // blank page + } + else + { + if (plm->isPortGroup(current)) + { + swDetail->setCurrentIndex(1); // portGroup detail page + } + else if (plm->isPort(current)) + { + swDetail->setCurrentIndex(0); // port detail page + } + } +} + +void PortsWindow::when_streamView_currentChanged(const QModelIndex& current, + const QModelIndex& previous) +{ + qDebug("stream view current changed"); + updateStreamViewActions(); +} + +void PortsWindow::when_streamView_selectionChanged() +{ + qDebug("stream view selection changed"); + updateStreamViewActions(); +} + +void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ +#if 0 // not sure why the >= <= operators are not overloaded in QModelIndex + if ((tvPortList->currentIndex() >= topLeft) && + (tvPortList->currentIndex() <= bottomRight)) +#endif + if ((topLeft < tvPortList->currentIndex()) || + (topLeft == tvPortList->currentIndex()) && + ((tvPortList->currentIndex() < bottomRight)) || + (tvPortList->currentIndex() == bottomRight)) + { + updatePortViewActions(tvPortList->currentIndex()); + } + +} + +#if 0 +void PortsWindow::updateStreamViewActions(const QModelIndex& current) +{ + if (current.isValid()) + actionDelete_Stream->setEnabled(true); + else + actionDelete_Stream->setDisabled(true); +} +#endif + +void PortsWindow::updateStreamViewActions() +{ + if (tvStreamList->selectionModel()->hasSelection()) + { + qDebug("Has selection %d", + tvStreamList->selectionModel()->selection().size()); + // If more than one non-contiguous ranges selected, disable "New" + if (tvStreamList->selectionModel()->selection().size() > 1) + actionNew_Stream->setDisabled(true); + else + actionNew_Stream->setEnabled(true); + + // Delete is always enabled as long as we have a selection + actionDelete_Stream->setEnabled(true); + } + else + { + qDebug("No selection"); + actionNew_Stream->setEnabled(true); + actionDelete_Stream->setDisabled(true); + } +} + +void PortsWindow::updatePortViewActions(const QModelIndex& current) +{ + if (!current.isValid()) + { + qDebug("current is now invalid"); + actionDelete_Port_Group->setDisabled(true); + actionConnect_Port_Group->setDisabled(true); + actionDisconnect_Port_Group->setDisabled(true); + + goto _EXIT; + } + + qDebug("currentChanged %llx", current.internalId()); + + if (plm->isPortGroup(current)) + { + actionDelete_Port_Group->setEnabled(true); + switch(plm->portGroup(current).state()) + { + case QAbstractSocket::UnconnectedState: + case QAbstractSocket::ClosingState: + qDebug("state = unconnected|closing"); + actionConnect_Port_Group->setEnabled(true); + actionDisconnect_Port_Group->setDisabled(true); + break; + + case QAbstractSocket::HostLookupState: + case QAbstractSocket::ConnectingState: + case QAbstractSocket::ConnectedState: + qDebug("state = lookup|connecting|connected"); + actionConnect_Port_Group->setDisabled(true); + actionDisconnect_Port_Group->setEnabled(true); + break; + + + case QAbstractSocket::BoundState: + case QAbstractSocket::ListeningState: + default: + // FIXME(LOW): indicate error + qDebug("unexpected state"); + break; + } + } + else if (plm->isPort(current)) + { + actionDelete_Port_Group->setEnabled(false); + actionConnect_Port_Group->setEnabled(false); + actionDisconnect_Port_Group->setEnabled(false); + } + +_EXIT: + return; +} + +void PortsWindow::on_pbApply_clicked() +{ +{ + // TODO (LOW): This block is for testing only + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + + if (current.isValid()) + qDebug("current = %llx", current.internalId()); + else + qDebug("current is invalid"); +} +} + +void PortsWindow::on_actionNew_Port_Group_triggered() +{ + bool ok; + QString text = QInputDialog::getText(this, + "Add Port Group", "Port Group Address (IP[:Port])", + QLineEdit::Normal, lastNewPortGroup, &ok); + + if (ok) + { + QStringList addr = text.split(":"); + if (addr.size() == 1) // Port unspecified + addr.append(QString().setNum(DEFAULT_SERVER_PORT)); + PortGroup *pg = new PortGroup(QHostAddress(addr[0]),addr[1].toUShort()); + plm->addPortGroup(*pg); + lastNewPortGroup = text; + } +} + +void PortsWindow::on_actionDelete_Port_Group_triggered() +{ + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + + if (current.isValid()) + plm->removePortGroup(plm->portGroup(current)); +} + +void PortsWindow::on_actionConnect_Port_Group_triggered() +{ + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + + if (current.isValid()) + plm->portGroup(current).connectToHost(); +} + +void PortsWindow::on_actionDisconnect_Port_Group_triggered() +{ + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + + if (current.isValid()) + plm->portGroup(current).disconnectFromHost(); +} +#if 0 +void PortsWindow::on_actionNew_Stream_triggered() +{ + qDebug("New Stream Action"); + + int row = 0; + + if (tvStreamList->currentIndex().isValid()) + row = tvStreamList->currentIndex().row(); + plm->getStreamModel()->insertRows(row, 1); +} + +void PortsWindow::on_actionDelete_Stream_triggered() +{ + qDebug("Delete Stream Action"); + if (tvStreamList->currentIndex().isValid()) + plm->getStreamModel()->removeRows(tvStreamList->currentIndex().row(), 1); +} +#endif + +void PortsWindow::on_actionNew_Stream_triggered() +{ + qDebug("New Stream Action"); + + // In case nothing is selected, insert 1 row at the top + int row = 0, count = 1; + + // In case we have a single range selected; insert as many rows as + // in the singe selected range before the top of the selected range + if (tvStreamList->selectionModel()->selection().size() == 1) + { + row = tvStreamList->selectionModel()->selection().at(0).top(); + count = tvStreamList->selectionModel()->selection().at(0).height(); + } + + plm->getStreamModel()->insertRows(row, count); +} + +void PortsWindow::on_actionDelete_Stream_triggered() +{ + qDebug("Delete Stream Action"); + + QModelIndex index; + + if (tvStreamList->selectionModel()->hasSelection()) + { + qDebug("SelectedIndexes %d", + tvStreamList->selectionModel()->selectedRows().size()); + while(tvStreamList->selectionModel()->selectedRows().size()) + { + index = tvStreamList->selectionModel()->selectedRows().at(0); + plm->getStreamModel()->removeRows(index.row(), 1); + } + } + else + qDebug("No selection"); +} + + diff --git a/client/portswindow.h b/client/portswindow.h new file mode 100644 index 0000000..2a26c2b --- /dev/null +++ b/client/portswindow.h @@ -0,0 +1,56 @@ +#ifndef _PORTS_WINDOW_H +#define _PORTS_WINDOW_H + +#include +#include +#include "ui_portswindow.h" +#include "portgrouplist.h" + +/* TODO +HIGH +MED +LOW +*/ + + +class PortsWindow : public QWidget, private Ui::PortsWindow +{ + Q_OBJECT + + //QAbstractItemModel *slm; // stream list model + PortGroupList *plm; + +public: + PortsWindow(PortGroupList *pgl, QWidget *parent = 0); + ~PortsWindow(); + +private: + QString lastNewPortGroup; + + void updatePortViewActions(const QModelIndex& current); + //void updateStreamViewActions(const QModelIndex& current); + void updateStreamViewActions(); + +private slots: + void on_tvStreamList_activated(const QModelIndex & index); + void when_portView_currentChanged(const QModelIndex& current, + const QModelIndex& previous); + void when_streamView_currentChanged(const QModelIndex& current, + const QModelIndex& previous); + void when_streamView_selectionChanged(); + void when_portModel_dataChanged(const QModelIndex& topLeft, + const QModelIndex& bottomRight); + + void on_pbApply_clicked(); + + void on_actionNew_Port_Group_triggered(); + void on_actionDelete_Port_Group_triggered(); + void on_actionConnect_Port_Group_triggered(); + void on_actionDisconnect_Port_Group_triggered(); + + void on_actionNew_Stream_triggered(); + void on_actionDelete_Stream_triggered(); +}; + +#endif + diff --git a/client/portswindow.ui b/client/portswindow.ui new file mode 100644 index 0000000..04349d2 --- /dev/null +++ b/client/portswindow.ui @@ -0,0 +1,214 @@ + + PortsWindow + + + + 0 + 0 + 689 + 320 + + + + Form + + + + + + Qt::Horizontal + + + + Qt::ActionsContextMenu + + + QAbstractItemView::SingleSelection + + + + + 0 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Apply + + + + + + + + + + + Qt::Horizontal + + + + 31 + 41 + + + + + + + + Capacity + + + + + + + + + + Aggr fps + + + + + + + + + + % age + + + + + + + + + + Aggr bps + + + + + + + + + + + + 0 + + + + Control + + + + + + Qt::ActionsContextMenu + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + + + + + + + + + + + + + Port Group Detail + + + + + + + + + + + + + :/icons/portgroup_add.png + + + New Port Group + + + + + :/icons/portgroup_delete.png + + + Delete Port Group + + + + + :/icons/portgroup_connect.png + + + Connect Port Group + + + + + :/icons/portgroup_disconnect.png + + + Disconnect Port Group + + + + + :/icons/stream_add.png + + + New Stream + + + + + :/icons/stream_delete.png + + + Delete Stream + + + + + + + + diff --git a/client/stream.cpp b/client/stream.cpp new file mode 100644 index 0000000..980d26c --- /dev/null +++ b/client/stream.cpp @@ -0,0 +1,123 @@ +#include + +Stream::Stream() +{ + // Default constructor + InitDefaultMeta(); + InitDefaultProto(); + InitDefaultL2(); + InitDefaultL3(); + InitDefaultL4(); +} + +void Stream::InitDefaultMeta() +{ + // TODO(LOW): Use #defines + meta.patternMode = e_dp_fixed; + meta.pattern = 0x00000000; + meta.dataStartOfs = 0; // FIXME(HIGH): this has to calculated + meta.lenMode = e_fl_fixed; + meta.frameLen = 64; + meta.frameLenMin = 64; + meta.frameLenMax = 1518; +} + +void Stream::InitDefaultProto() +{ + // TODO(LOW): Use #defines + proto.ft = e_ft_eth_2; + proto.dsap = 0x00; + proto.ssap = 0x00; + proto.ctl = 0x00; + proto.ouiMsb = 0x00; + proto.ouiLshw = 0x0000; + + proto.protoMask = PM_L3_PROTO_NONE | PM_L4_PROTO_NONE; + proto.etherType = ETH_TYP_IP; + proto.ipProto = IP_PROTO_TCP; +} + + +void Stream::InitDefaultL2() +{ + // TODO(LOW): Use #defines + l2.eth.dstMacMshw = 0x0000; + l2.eth.dstMacLsw = 0x00000001; + l2.eth.dstMacMode = e_mm_fixed; + l2.eth.dstMacCount = 16; + l2.eth.dstMacStep = 1; + + l2.eth.srcMacMshw = 0x0000; + l2.eth.srcMacLsw = 0x00000002; + l2.eth.srcMacMode = e_mm_fixed; + l2.eth.srcMacCount = 16; + l2.eth.srcMacStep = 1; + + l2.eth.vlanMask = VM_UNTAGGED; + l2.eth.ctpid = 0x8100; + l2.eth.cvlanPrio = 0; + l2.eth.cvlanCfi = 0; + l2.eth.cvlanId = 2; + l2.eth.stpid = 0x88a8; + l2.eth.svlanPrio = 0; + l2.eth.svlanCfi = 0; + l2.eth.svlanId = 2; +} + +void Stream::InitDefaultL3() +{ + InitDefaultL3Ip(); +} + +void Stream::InitDefaultL3Ip() +{ + l3.ip.ipMask = STREAM_DEF_IP_MASK; + l3.ip.ver = STREAM_DEF_L3_IP_VER; + l3.ip.hdrLen = STREAM_DEF_L3_IP_HDR_LEN; + l3.ip.tos = STREAM_DEF_L3_IP_TOS; + l3.ip.totLen = STREAM_DEF_L3_IP_TOT_LEN; + l3.ip.id = STREAM_DEF_L3_IP_ID; + l3.ip.flags = STREAM_DEF_L3_IP_FLAGS; + l3.ip.fragOfs = STREAM_DEF_L3_IP_FRAG_OFS; + l3.ip.ttl = STREAM_DEF_L3_IP_TTL; + l3.ip.proto = STREAM_DEF_L3_IP_PROTO; + l3.ip.cksum = STREAM_DEF_L3_IP_CKSUM; + l3.ip.srcIp = STREAM_DEF_L3_IP_SRC_IP; + l3.ip.srcIpMode = STREAM_DEF_L3_IP_SRC_IP_MODE; + l3.ip.srcIpCount = STREAM_DEF_L3_IP_SRC_IP_COUNT; + l3.ip.srcIpMask = STREAM_DEF_L3_IP_SRC_IP_MASK; + l3.ip.dstIp = STREAM_DEF_L3_IP_DST_IP; + l3.ip.dstIpMode = STREAM_DEF_L3_IP_DST_IP_MODE; + l3.ip.dstIpCount = STREAM_DEF_L3_IP_DST_IP_COUNT; + l3.ip.dstIpMask = STREAM_DEF_L3_IP_DST_IP_MASK; +} + +void Stream::InitDefaultL4() +{ + InitDefaultL4Tcp(); + InitDefaultL4Udp(); +} + +void Stream::InitDefaultL4Tcp() +{ + l4.tcp.tcpMask = STREAM_DEF_L4_TCP_TCP_MASK; + l4.tcp.srcPort = STREAM_DEF_L4_TCP_SRC_PORT; + l4.tcp.dstPort = STREAM_DEF_L4_TCP_DST_PORT; + l4.tcp.seqNum = STREAM_DEF_L4_TCP_SEQ_NUM; + l4.tcp.ackNum = STREAM_DEF_L4_TCP_ACK_NUM; + l4.tcp.hdrLen = STREAM_DEF_L4_TCP_HDR_LEN; + l4.tcp.rsvd = STREAM_DEF_L4_TCP_RSVD; + l4.tcp.flags = STREAM_DEF_L4_TCP_FLAGS; + l4.tcp.window = STREAM_DEF_L4_TCP_WINDOW; + l4.tcp.cksum = STREAM_DEF_L4_TCP_CKSUM; + l4.tcp.urgPtr = STREAM_DEF_L4_TCP_URG_PTR; +} + +void Stream::InitDefaultL4Udp() +{ + l4.udp.udpMask = STREAM_DEF_L4_UDP_UDP_MASK; + l4.udp.srcPort = STREAM_DEF_L4_UDP_SRC_PORT; + l4.udp.dstPort = STREAM_DEF_L4_UDP_DST_PORT; + l4.udp.totLen = STREAM_DEF_L4_UDP_TOT_LEN; + l4.udp.cksum = STREAM_DEF_L4_UDP_CKSUM; +} diff --git a/client/stream.h b/client/stream.h new file mode 100644 index 0000000..c1f9d5f --- /dev/null +++ b/client/stream.h @@ -0,0 +1,307 @@ +#ifndef _STREAM_H +#define _STREAM_H + +#include +#include + +class StreamConfigDialog; +class StreamModel; + +class Stream { + + friend class StreamConfigDialog; + friend class StreamModel; + + enum FrameType { + e_ft_none, + e_ft_eth_2, + e_ft_802_3_raw, + e_ft_802_3_llc, + e_ft_snap + }; + + enum DataPatternMode { + e_dp_fixed, + e_dp_inc, + e_dp_dec, + e_dp_random + }; + + enum FrameLengthMode { + e_fl_fixed, + e_fl_inc, + e_fl_dec, + e_fl_random + }; + + enum MacAddrMode { + e_mm_fixed, + e_mm_inc, + e_mm_dec, + }; + + enum IpAddrMode { + e_im_fixed, + e_im_inc_host, + e_im_dec_host, + e_im_random_host + }; + + // Meta Data + struct { + // Data Pattern + DataPatternMode patternMode; + quint32 pattern; + quint16 dataStartOfs; + + // Frame Length (includes CRC) + FrameLengthMode lenMode; + quint16 frameLen; + quint16 frameLenMin; + quint16 frameLenMax; + } meta; + + // Protocols + struct { + FrameType ft; + + quint8 dsap; + quint8 ssap; + quint8 ctl; + quint8 ouiMsb; + quint16 ouiLshw; + + quint16 protoMask; +#define PM_L3_PROTO_NONE 0x0001 +#define PM_L3_PROTO_OTHER 0x0002 +#define PM_L4_PROTO_NONE 0x0004 +#define PM_L4_PROTO_OTHER 0x0008 + + quint16 etherType; +#define ETH_TYP_IP 0x0800 +#define ETH_TYP_ARP 0x0806 + + quint16 ipProto; +#define IP_PROTO_ICMP 0x01 +#define IP_PROTO_IGMP 0x02 +#define IP_PROTO_TCP 0x06 +#define IP_PROTO_UDP 0x11 + } proto; + + // L2 + struct { + // Ethernet + struct { + // Dst Mac + quint16 dstMacMshw; + quint32 dstMacLsw; + MacAddrMode dstMacMode; + quint16 dstMacCount; + quint16 dstMacStep; + + // srcMac + quint16 srcMacMshw; + quint32 srcMacLsw; + MacAddrMode srcMacMode; + quint16 srcMacCount; + quint16 srcMacStep; + + + quint16 vlanMask; +#define VM_UNTAGGED 0x0000 +#define VM_CVLAN_TAGGED 0x0001 +#define VM_CVLAN_TPID_OVERRIDE 0x0002 +#define VM_SVLAN_TAGGED 0x0100 +#define VM_SVLAN_TPID_OVERRIDE 0x0200 + + quint16 ctpid; + quint16 cvlanPrio : 3; + quint16 cvlanCfi : 1; + quint16 cvlanId : 13; + quint16 stpid; + quint16 svlanPrio : 3; + quint16 svlanCfi : 1; + quint16 svlanId : 13; + } eth; + } l2; + + struct { + // IP + struct { + quint8 ipMask; +#define IM_OVERRIDE_VERSION 0x01 +#define IM_OVERRIDE_HDRLEN 0x02 +#define IM_OVERRIDE_TOTLEN 0x04 +#define IM_OVERRIDE_CKSUM 0x08 +#define STREAM_DEF_IP_MASK 0x00 + + quint8 ver : 4; +#define STREAM_DEF_L3_IP_VER 0x4 + + quint8 hdrLen : 4; +#define STREAM_DEF_L3_IP_HDR_LEN 0x5 + + quint8 tos; +#define STREAM_DEF_L3_IP_TOS 0x00 + + quint16 totLen; +#define STREAM_DEF_L3_IP_TOT_LEN 0x00 + + quint16 id; +#define STREAM_DEF_L3_IP_ID 0x1234 + + quint16 flags : 3; +#define IP_FLAG_UNUSED 0x1 +#define IP_FLAG_DF 0x2 +#define IP_FLAG_MF 0x4 +#define STREAM_DEF_L3_IP_FLAGS 0x00 + + quint16 fragOfs : 13; +#define STREAM_DEF_L3_IP_FRAG_OFS 0x0000 + + quint8 ttl; +#define STREAM_DEF_L3_IP_TTL 0x7F + + quint8 proto; +#define STREAM_DEF_L3_IP_PROTO 0x00 + + quint16 cksum; +#define STREAM_DEF_L3_IP_CKSUM 0x0000 + + // Source IP + quint32 srcIp; +#define STREAM_DEF_L3_IP_SRC_IP 0x02020202 + + IpAddrMode srcIpMode; +#define STREAM_DEF_L3_IP_SRC_IP_MODE e_im_fixed + + quint16 srcIpCount; +#define STREAM_DEF_L3_IP_SRC_IP_COUNT 16 + + quint32 srcIpMask; +#define STREAM_DEF_L3_IP_SRC_IP_MASK 0xFFFFFFFF + + // Destination IP + quint32 dstIp; +#define STREAM_DEF_L3_IP_DST_IP 0x01010101 + + IpAddrMode dstIpMode; +#define STREAM_DEF_L3_IP_DST_IP_MODE e_im_fixed + + quint16 dstIpCount; +#define STREAM_DEF_L3_IP_DST_IP_COUNT 16 + + quint32 dstIpMask; +#define STREAM_DEF_L3_IP_DST_IP_MASK 0xFFFFFFFF + + // TODO: Options + } ip; + + // TODO: ARP + struct { + } arp; + } l3; + + // L4 + struct { + // TCP + struct { + quint32 tcpMask; +#define TM_OVERRIDE_HDRLEN 0x1 +#define TM_OVERRIDE_CKSUM 0x2 +#define STREAM_DEF_L4_TCP_TCP_MASK 0x00; + + quint16 srcPort; +#define STREAM_DEF_L4_TCP_SRC_PORT 8902; + + quint16 dstPort; +#define STREAM_DEF_L4_TCP_DST_PORT 80 + + quint32 seqNum; +#define STREAM_DEF_L4_TCP_SEQ_NUM 129018 + + quint32 ackNum; +#define STREAM_DEF_L4_TCP_ACK_NUM 98223 + + quint8 hdrLen : 4; +#define STREAM_DEF_L4_TCP_HDR_LEN 0x5 + + quint8 rsvd : 4; +#define STREAM_DEF_L4_TCP_RSVD 0x0 + + quint8 flags; +#define TCP_FLAG_URG 0x01 +#define TCP_FLAG_ACK 0x02 +#define TCP_FLAG_PSH 0x04 +#define TCP_FLAG_RST 0x08 +#define TCP_FLAG_SYN 0x10 +#define TCP_FLAG_FIN 0x20 +#define STREAM_DEF_L4_TCP_FLAGS 0x00 + + + quint16 window; +#define STREAM_DEF_L4_TCP_WINDOW 1024 + + quint16 cksum; +#define STREAM_DEF_L4_TCP_CKSUM 0x0000 + + quint16 urgPtr; +#define STREAM_DEF_L4_TCP_URG_PTR 0x0000 + } tcp; + + // UDP + struct { + quint32 udpMask; +#define UM_OVERRIDE_TOTLEN 0x01 +#define UM_OVERRIDE_CKSUM 0x02 +#define STREAM_DEF_L4_UDP_UDP_MASK 0x00 + + quint16 srcPort; +#define STREAM_DEF_L4_UDP_SRC_PORT 8902 + + quint16 dstPort; +#define STREAM_DEF_L4_UDP_DST_PORT 80 + + quint16 totLen; +#define STREAM_DEF_L4_UDP_TOT_LEN 0x0000 + + quint16 cksum; +#define STREAM_DEF_L4_UDP_CKSUM 0x0000 + } udp; + + // TODO: ICMP + struct { + } icmp; + + // TODO: IGMP + struct { + } igmp; + } l4; + + QString mName; + bool mIsEnabled; + +// ------------------------------------------------------- +// Methods +// ------------------------------------------------------- +public: + Stream(); + int enable(bool flag); + const QString& name() const { return mName; } + bool isEnabled() const { return mIsEnabled; } + + void setName(QString name) { mName = name; } + void setEnabled(bool isEnabled) { mIsEnabled = isEnabled; } + +private: + void InitDefaultMeta(); + void InitDefaultProto(); + void InitDefaultL2(); + void InitDefaultL3(); + void InitDefaultL3Ip(); + void InitDefaultL4(); + void InitDefaultL4Tcp(); + void InitDefaultL4Udp(); +}; + +#endif diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp new file mode 100644 index 0000000..f29592f --- /dev/null +++ b/client/streamconfigdialog.cpp @@ -0,0 +1,677 @@ +#include +#include "streamconfigdialog.h" +#include "stream.h" + +StreamConfigDialog::StreamConfigDialog(QList *streamList, + uint streamIndex, QWidget *parent) : QDialog (parent) +{ + setupUi(this); + setupUiExtra(); + + // FIXME(MED): Assumption that streamlist and streamIndex are valid + mpStreamList = streamList; + mCurrentStreamIndex = streamIndex; + LoadCurrentStream(); + + qDebug("stream %p %d/%d loaded", + mpStreamList, mCurrentStreamIndex, mpStreamList->size()); + +// FIXME(MED): Enable this navigation +#if 0 + pbPrev->setDisabled((currStreamIdx == 0)); + pbNext->setDisabled((currStreamIdx == 2)); +#endif +} + +void StreamConfigDialog::setupUiExtra() +{ + QRegExp reHex2B("[0-9,a-f,A-F]{1,4}"); + QRegExp reHex4B("[0-9,a-f,A-F]{1,8}"); + QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); + + // Setup default stuff that cannot be done in designer + twProto->setTabEnabled(2, FALSE); + twProto->setTabEnabled(3, FALSE); + + /* + ** Setup Validators + */ + // Meta Data + lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); + + // L2 Ethernet + leDstMac->setValidator(new QRegExpValidator(reMac, this)); + leSrcMac->setValidator(new QRegExpValidator(reMac, this)); + leDstMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); + leSrcMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); + leCvlanTpid->setValidator(new QRegExpValidator(reHex2B, this)); + leSvlanTpid->setValidator(new QRegExpValidator(reHex2B, this)); + //leEtherType->setValidator(new QRegExpValidator(reHex2B, this)); + + /* + ** Setup Connections + */ + connect(rbSendPackets, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + connect(rbSendBursts, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + connect(rbModeFixed, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + connect(rbModeContinuous, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + + // Show "Packet Config" page by default + twTopLevel->setCurrentIndex(0); +} + +StreamConfigDialog::~StreamConfigDialog() +{ +} + +void StreamConfigDialog::on_cmbDstMacMode_currentIndexChanged(QString mode) +{ + if (mode == "Fixed") + leDstMacCount->setEnabled(FALSE); + else + leDstMacCount->setEnabled(TRUE); +} + +void StreamConfigDialog::on_pbPrev_clicked() +{ +#if 0 + StoreCurrentStream(currStreamIdx); + currStreamIdx--; + LoadCurrentStream(currStreamIdx); + + pbPrev->setDisabled((currStreamIdx == 0)); + pbNext->setDisabled((currStreamIdx == 2)); +#endif +} + +void StreamConfigDialog::on_pbNext_clicked() +{ +#if 0 + StoreCurrentStream(currStreamIdx); + currStreamIdx++; + LoadCurrentStream(currStreamIdx); + + pbPrev->setDisabled((currStreamIdx == 0)); + pbNext->setDisabled((currStreamIdx == 2)); +#endif +} + +void StreamConfigDialog::on_rbFtLlcSnap_toggled(bool checked) +{ + if (checked) + { + leDsap->setText("AA"); + leSsap->setText("AA"); + leControl->setText("03"); + } +} + +void StreamConfigDialog::on_rbL3Ipv4_toggled(bool checked) +{ + if (checked) + { + swL3Proto->setCurrentIndex(0); + twProto->setTabEnabled(2, TRUE); + twProto->setTabText(2, "L3 (IPv4)"); + leType->setText("08 00"); + } + else + { + twProto->setTabEnabled(2, FALSE); + twProto->setTabText(2, "L3"); + } +} + +void StreamConfigDialog::on_rbL3Arp_toggled(bool checked) +{ + if (checked) + { + swL3Proto->setCurrentIndex(1); + twProto->setTabEnabled(2, TRUE); + twProto->setTabText(2, "L3 (ARP)"); + leType->setText("08 06"); + } + else + { + twProto->setTabEnabled(2, FALSE); + twProto->setTabText(2, "L3"); + } +} + +void StreamConfigDialog::on_rbL4Icmp_toggled(bool checked) +{ + QString str; + + if (checked) + { + swL4Proto->setCurrentIndex(2); + twProto->setTabEnabled(3, TRUE); + twProto->setTabText(3, "L4 (ICMP)"); + leIpProto->setText(uintToHexStr(IP_PROTO_ICMP, str, 1)); + } + else + { + twProto->setTabEnabled(3, FALSE); + twProto->setTabText(3, "L4"); + } +} + +void StreamConfigDialog::on_rbL4Igmp_toggled(bool checked) +{ + QString str; + + if (checked) + { + swL4Proto->setCurrentIndex(3); + twProto->setTabEnabled(3, TRUE); + twProto->setTabText(3, "L4 (IGMP)"); + leIpProto->setText(uintToHexStr(IP_PROTO_IGMP, str, 1)); + } + else + { + twProto->setTabEnabled(3, FALSE); + twProto->setTabText(3, "L4"); + } +} + +void StreamConfigDialog::on_rbL4Tcp_toggled(bool checked) +{ + QString str; + + if (checked) + { + swL4Proto->setCurrentIndex(0); + twProto->setTabEnabled(3, TRUE); + twProto->setTabText(3, "L4 (TCP)"); + leIpProto->setText(uintToHexStr(IP_PROTO_TCP, str, 1)); + } + else + { + twProto->setTabEnabled(3, FALSE); + twProto->setTabText(3, "L4"); + } +} + +void StreamConfigDialog::on_rbL4Udp_toggled(bool checked) +{ + QString str; + + if (checked) + { + swL4Proto->setCurrentIndex(1); + twProto->setTabEnabled(3, TRUE); + twProto->setTabText(3, "L4 (UDP)"); + leIpProto->setText(uintToHexStr(IP_PROTO_UDP, str, 1)); + } + else + { + twProto->setTabEnabled(3, FALSE); + twProto->setTabText(3, "L4"); + } +} + +void StreamConfigDialog::on_rbL4Other_toggled(bool checked) +{ + if (checked) + leIpProto->setEnabled(true); + else + leIpProto->setEnabled(false); +} + +void StreamConfigDialog::update_NumPacketsAndNumBursts() +{ + if (rbSendPackets->isChecked() && rbModeFixed->isChecked()) + leNumPackets->setEnabled(true); + else + leNumPackets->setEnabled(false); + + if (rbSendBursts->isChecked() && rbModeFixed->isChecked()) + leNumBursts->setEnabled(true); + else + leNumBursts->setEnabled(false); +} + +QString & uintToHexStr(quint32 num, QString &hexStr, quint8 octets) +{ + int i; + QChar zero('0'); + + hexStr = ""; + + for (i = octets; i > 0; i--) + { + ushort byte; + QString str1 = "%1"; + QString str; + + byte = num & 0xff; + str = str1.arg(byte, 2, 16, zero).append(' '); + hexStr.prepend(str); + num = num >> 8; + } + + return hexStr; +} + +#if 0 +void StreamConfigDialog::on_lePattern_editingFinished() +{ + ulong num = 0; + bool isOk; + QString str; + + num = lePattern->text().remove(QChar(' ')).toULong(&isOk, 16); + qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); + lePattern->setText(uintToHexStr(num, str, 4)); + qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); +} +#endif + +void StreamConfigDialog::LoadCurrentStream() +{ + Stream *pStream = &((*mpStreamList)[mCurrentStreamIndex]); + QString str; + + qDebug("loading pStream %p", pStream); + + // Meta Data + { + cmbPatternMode->setCurrentIndex(pStream->meta.patternMode); + lePattern->setText(uintToHexStr(pStream->meta.pattern, str, 4)); + + cmbPktLenMode->setCurrentIndex(pStream->meta.lenMode); + lePktLen->setText(str.setNum(pStream->meta.frameLen)); + lePktLenMin->setText(str.setNum(pStream->meta.frameLenMin)); + lePktLenMax->setText(str.setNum(pStream->meta.frameLenMax)); + } + + // Protocols + { + qDebug("ft = %d\n", pStream->proto.ft); + switch(pStream->proto.ft) + { + case Stream::e_ft_none: + rbFtNone->setChecked(TRUE); + break; + case Stream::e_ft_eth_2: + rbFtEthernet2->setChecked(TRUE); + break; + case Stream::e_ft_802_3_raw: + rbFt802Dot3Raw->setChecked(TRUE); + break; + case Stream::e_ft_802_3_llc: + rbFt802Dot3Llc->setChecked(TRUE); + break; + case Stream::e_ft_snap: + rbFtLlcSnap->setChecked(TRUE); + break; + } + leDsap->setText(uintToHexStr(pStream->proto.dsap, str, 1)); + leSsap->setText(uintToHexStr(pStream->proto.ssap, str, 1)); + leControl->setText(uintToHexStr(pStream->proto.ctl, str, 1)); + leOui->setText(uintToHexStr((pStream->proto.ouiMsb << 16 + pStream->proto.ouiLshw), str, 3)); + + leType->setText(uintToHexStr(pStream->proto.etherType, str, 2)); + + // Check for specific supported protocols first ... + if (pStream->proto.etherType == ETH_TYP_IP) + rbL3Ipv4->setChecked(TRUE); + else if (pStream->proto.etherType == ETH_TYP_ARP) + rbL3Arp->setChecked(TRUE); + + // ... then for None/Other + rbL3None->setChecked((pStream->proto.protoMask & PM_L3_PROTO_NONE) > 0); + rbL3Other->setChecked((pStream->proto.protoMask & PM_L3_PROTO_OTHER) > 0); + + // Check for specific supported protocols first ... + if (pStream->proto.ipProto == IP_PROTO_ICMP) + rbL4Icmp->setChecked(TRUE); + else if (pStream->proto.ipProto == IP_PROTO_IGMP) + rbL4Igmp->setChecked(TRUE); + else if (pStream->proto.ipProto == IP_PROTO_TCP) + rbL4Tcp->setChecked(TRUE); + else if (pStream->proto.ipProto == IP_PROTO_UDP) + rbL4Udp->setChecked(TRUE); + + // ... then for None/Other + rbL4None->setChecked((pStream->proto.protoMask & PM_L4_PROTO_NONE) > 0); + rbL4Other->setChecked((pStream->proto.protoMask & PM_L4_PROTO_OTHER) > 0); + } + + // L2 + { + // L2 | Ethernet + { + leDstMac->setText(uintToHexStr(pStream->l2.eth.dstMacMshw, str, 2) + + uintToHexStr(pStream->l2.eth.dstMacLsw, str, 4)); + cmbDstMacMode->setCurrentIndex(pStream->l2.eth.dstMacMode); + leDstMacCount->setText(str.setNum(pStream->l2.eth.dstMacCount)); + leDstMacStep->setText(str.setNum(pStream->l2.eth.dstMacStep)); + + leSrcMac->setText(uintToHexStr(pStream->l2.eth.srcMacMshw, str, 2) + + uintToHexStr(pStream->l2.eth.srcMacLsw, str, 4)); + cmbSrcMacMode->setCurrentIndex(pStream->l2.eth.srcMacMode); + leSrcMacCount->setText(str.setNum(pStream->l2.eth.srcMacCount)); + leSrcMacStep->setText(str.setNum(pStream->l2.eth.srcMacStep)); + + cmbCvlanPrio->setCurrentIndex(pStream->l2.eth.cvlanPrio); + cmbCvlanCfi->setCurrentIndex(pStream->l2.eth.cvlanCfi); + leCvlanId->setText(str.setNum(pStream->l2.eth.cvlanId)); + leCvlanTpid->setText(str.setNum(pStream->l2.eth.ctpid)); + cbCvlanTpidOverride->setChecked((pStream->l2.eth.vlanMask & VM_CVLAN_TPID_OVERRIDE) > 0); + gbCvlan->setChecked((pStream->l2.eth.vlanMask & VM_CVLAN_TAGGED) > 0); + + cmbSvlanPrio->setCurrentIndex(pStream->l2.eth.svlanPrio); + cmbSvlanCfi->setCurrentIndex(pStream->l2.eth.svlanCfi); + leSvlanId->setText(str.setNum(pStream->l2.eth.svlanId)); + leSvlanTpid->setText(str.setNum(pStream->l2.eth.stpid)); + cbSvlanTpidOverride->setChecked((pStream->l2.eth.vlanMask & VM_SVLAN_TPID_OVERRIDE) > 0); + gbSvlan->setChecked((pStream->l2.eth.vlanMask & VM_SVLAN_TAGGED) > 0); + } + } + + // L3 + { + // L3 | IP + { + leIpVersion->setText(str.setNum(pStream->l3.ip.ver)); + cbIpVersionOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_VERSION) > 0); + leIpHdrLen->setText(str.setNum(pStream->l3.ip.hdrLen)); + cbIpHdrLenOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_HDRLEN) > 0); + + leIpTos->setText(uintToHexStr(pStream->l3.ip.tos, str, 1)); + + leIpLength->setText(str.setNum(pStream->l3.ip.totLen)); + cbIpLengthOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_TOTLEN) > 0); + + leIpId->setText(uintToHexStr(pStream->l3.ip.id, str, 2)); + leIpFragOfs->setText(str.setNum(pStream->l3.ip.fragOfs)); + cbIpFlagsDf->setChecked((pStream->l3.ip.flags & IP_FLAG_DF) > 0); + cbIpFlagsMf->setChecked((pStream->l3.ip.flags & IP_FLAG_MF) > 0); + + leIpTtl->setText(str.setNum(pStream->l3.ip.ttl)); + leIpProto->setText(uintToHexStr(pStream->l3.ip.proto, str, 1)); + + leIpCksum->setText(uintToHexStr(pStream->l3.ip.cksum, str, 2)); + cbIpCksumOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_CKSUM) > 0); + + leIpSrcAddr->setText(QHostAddress(pStream->l3.ip.srcIp).toString()); + cmbIpSrcAddrMode->setCurrentIndex(pStream->l3.ip.srcIpMode); + leIpSrcAddrCount->setText(str.setNum(pStream->l3.ip.srcIpCount)); + leIpSrcAddrMask->setText(QHostAddress(pStream->l3.ip.srcIpMask).toString()); + + leIpDstAddr->setText(QHostAddress(pStream->l3.ip.dstIp).toString()); + cmbIpDstAddrMode->setCurrentIndex(pStream->l3.ip.dstIpMode); + leIpDstAddrCount->setText(str.setNum(pStream->l3.ip.dstIpCount)); + leIpDstAddrMask->setText(QHostAddress(pStream->l3.ip.dstIpMask).toString()); + } + + // L3 | ARP + { + // TODO + } + } + + // L4 + { + // L4 | TCP + { + leTcpSrcPort->setText(str.setNum(pStream->l4.tcp.srcPort)); + leTcpDstPort->setText(str.setNum(pStream->l4.tcp.dstPort)); + + leTcpSeqNum->setText(str.setNum(pStream->l4.tcp.seqNum)); + leTcpAckNum->setText(str.setNum(pStream->l4.tcp.ackNum)); + + leTcpHdrLen->setText(str.setNum(pStream->l4.tcp.hdrLen)); + cbTcpHdrLenOverride->setChecked((pStream->l4.tcp.tcpMask & TM_OVERRIDE_HDRLEN) > 0); + + leTcpWindow->setText(str.setNum(pStream->l4.tcp.window)); + + leTcpCksum->setText(str.setNum(pStream->l4.tcp.cksum)); + cbTcpCksumOverride->setChecked((pStream->l4.tcp.tcpMask & TM_OVERRIDE_CKSUM) > 0); + + leTcpUrgentPointer->setText(str.setNum(pStream->l4.tcp.urgPtr)); + + cbTcpFlagsUrg->setChecked((pStream->l4.tcp.flags & TCP_FLAG_URG) > 0); + cbTcpFlagsAck->setChecked((pStream->l4.tcp.flags & TCP_FLAG_ACK) > 0); + cbTcpFlagsPsh->setChecked((pStream->l4.tcp.flags & TCP_FLAG_PSH) > 0); + cbTcpFlagsRst->setChecked((pStream->l4.tcp.flags & TCP_FLAG_RST) > 0); + cbTcpFlagsSyn->setChecked((pStream->l4.tcp.flags & TCP_FLAG_SYN) > 0); + cbTcpFlagsFin->setChecked((pStream->l4.tcp.flags & TCP_FLAG_FIN) > 0); + } + + // L4 | UDP + { + leUdpSrcPort->setText(str.setNum(pStream->l4.udp.srcPort)); + leUdpDstPort->setText(str.setNum(pStream->l4.udp.dstPort)); + + leUdpLength->setText(str.setNum(pStream->l4.udp.totLen)); + cbUdpLengthOverride->setChecked((pStream->l4.udp.udpMask & UM_OVERRIDE_TOTLEN) > 0); + + leUdpCksum->setText(str.setNum(pStream->l4.udp.cksum)); + cbUdpCksumOverride->setChecked((pStream->l4.udp.udpMask & UM_OVERRIDE_CKSUM) > 0); + } + + // L4 | ICMP + { + // TODO + } + + // L4 | IGMP + { + // TODO + } + } +} + +void StreamConfigDialog::StoreCurrentStream() +{ + Stream *pStream = &(*mpStreamList)[mCurrentStreamIndex]; + QString str; + bool isOk; + + qDebug("storing pStream %p", pStream); + + // Meta Data + pStream->meta.patternMode = (Stream::DataPatternMode) cmbPatternMode->currentIndex(); + pStream->meta.pattern = lePattern->text().remove(QChar(' ')).toULong(&isOk, 16); + + pStream->meta.lenMode = (Stream::FrameLengthMode) cmbPktLenMode->currentIndex(); + pStream->meta.frameLen = lePktLen->text().toULong(&isOk); + pStream->meta.frameLenMin = lePktLenMin->text().toULong(&isOk); + pStream->meta.frameLenMax = lePktLenMax->text().toULong(&isOk); + + // Protocols + { + if (rbFtNone->isChecked()) + pStream->proto.ft = Stream::e_ft_none; + else if (rbFtEthernet2->isChecked()) + pStream->proto.ft = Stream::e_ft_eth_2; + else if (rbFt802Dot3Raw->isChecked()) + pStream->proto.ft = Stream::e_ft_802_3_raw; + else if (rbFt802Dot3Llc->isChecked()) + pStream->proto.ft = Stream::e_ft_802_3_llc; + else if (rbFtLlcSnap->isChecked()) + pStream->proto.ft = Stream::e_ft_snap; + + qDebug("store ft = %d\n", pStream->proto.ft); + + pStream->proto.dsap = leDsap->text().remove(QChar(' ')).toULong(&isOk, 16); + pStream->proto.ssap = leSsap->text().remove(QChar(' ')).toULong(&isOk, 16); + pStream->proto.ctl = leControl->text().remove(QChar(' ')).toULong(&isOk, 16); + pStream->proto.ouiMsb = leOui->text().remove(QChar(' ')).toULong(&isOk, 16) >> 16; + pStream->proto.ouiLshw = 0x0000FFFF & leOui->text().remove(QChar(' ')).toULong(&isOk, 16); + pStream->proto.etherType = leType->text().remove(QChar(' ')).toULong(&isOk, 16); + + pStream->proto.ipProto = leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16); + + // Just check for None/Other - no need to do anything for specific supported protocols + pStream->proto.protoMask = 0; + if (rbL3None->isChecked()) + pStream->proto.protoMask |= PM_L3_PROTO_NONE; + else if (rbL3Other->isChecked()) + pStream->proto.protoMask |= PM_L3_PROTO_OTHER; + + if (rbL4None->isChecked()) + pStream->proto.protoMask |= PM_L4_PROTO_NONE; + else if (rbL4Other->isChecked()) + pStream->proto.protoMask |= PM_L4_PROTO_OTHER; + } + + // L2 + { + // L2 | Ethernet + { + pStream->l2.eth.dstMacMshw = leDstMac->text().remove(QChar(' ')).left(4).toULong(&isOk, 16); + pStream->l2.eth.dstMacLsw = leDstMac->text().remove(QChar(' ')).right(8).toULong(&isOk, 16); + pStream->l2.eth.dstMacMode = (Stream::MacAddrMode) cmbDstMacMode->currentIndex(); + pStream->l2.eth.dstMacCount = leDstMacCount->text().toULong(&isOk); + pStream->l2.eth.dstMacStep = leDstMacStep->text().toULong(&isOk); + + pStream->l2.eth.srcMacMshw = leSrcMac->text().remove(QChar(' ')).left(4).toULong(&isOk, 16); + pStream->l2.eth.srcMacLsw = leSrcMac->text().remove(QChar(' ')).right(8).toULong(&isOk, 16); + pStream->l2.eth.srcMacMode = (Stream::MacAddrMode) cmbSrcMacMode->currentIndex(); + pStream->l2.eth.srcMacCount = leSrcMacCount->text().toULong(&isOk); + pStream->l2.eth.srcMacStep = leSrcMacStep->text().toULong(&isOk); + + pStream->l2.eth.vlanMask = 0; + + pStream->l2.eth.cvlanPrio = cmbCvlanPrio->currentIndex(); + pStream->l2.eth.cvlanCfi = cmbCvlanCfi->currentIndex(); + pStream->l2.eth.cvlanId = leCvlanId->text().toULong(&isOk); + pStream->l2.eth.ctpid = leCvlanTpid->text().remove(QChar(' ')).toULong(&isOk); + if (cbCvlanTpidOverride->isChecked()) + pStream->l2.eth.vlanMask |= VM_CVLAN_TPID_OVERRIDE; + if (gbCvlan->isChecked()) + pStream->l2.eth.vlanMask |= VM_CVLAN_TAGGED; + + pStream->l2.eth.svlanPrio = cmbSvlanPrio->currentIndex(); + pStream->l2.eth.svlanCfi = cmbSvlanCfi->currentIndex(); + pStream->l2.eth.svlanId = leSvlanId->text().toULong(&isOk); + pStream->l2.eth.stpid = leSvlanTpid->text().remove(QChar(' ')).toULong(&isOk); + if (cbSvlanTpidOverride->isChecked()) + pStream->l2.eth.vlanMask |= VM_SVLAN_TPID_OVERRIDE; + if (gbSvlan->isChecked()) + pStream->l2.eth.vlanMask |= VM_SVLAN_TAGGED; + } + } + + // L3 + { + // L3 | IP + { + pStream->l3.ip.ipMask = 0; + + pStream->l3.ip.ver = leIpVersion->text().toULong(&isOk); + if (cbIpVersionOverride->isChecked()) + pStream->l3.ip.ipMask |= IM_OVERRIDE_VERSION; + pStream->l3.ip.hdrLen = leIpHdrLen->text().toULong(&isOk); + if (cbIpHdrLenOverride->isChecked()) + pStream->l3.ip.ipMask |= IM_OVERRIDE_HDRLEN; + + pStream->l3.ip.tos = leIpTos->text().toULong(&isOk, 16); + + pStream->l3.ip.totLen = leIpLength->text().toULong(&isOk); + if (cbIpLengthOverride->isChecked()) + pStream->l3.ip.ipMask |= IM_OVERRIDE_TOTLEN; + + pStream->l3.ip.id = leIpId->text().remove(QChar(' ')).toULong(&isOk, 16); + pStream->l3.ip.fragOfs = leIpFragOfs->text().toULong(&isOk); + if (cbIpFlagsDf->isChecked()) pStream->l3.ip.ipMask |= IP_FLAG_DF; + if (cbIpFlagsMf->isChecked()) pStream->l3.ip.ipMask |= IP_FLAG_MF; + + pStream->l3.ip.ttl = leIpTtl->text().toULong(&isOk); + pStream->l3.ip.proto = leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16); + + pStream->l3.ip.cksum = leIpCksum->text().remove(QChar(' ')).toULong(&isOk); + if (cbIpCksumOverride->isChecked()) + pStream->l3.ip.ipMask |= IM_OVERRIDE_CKSUM; + + pStream->l3.ip.srcIp = QHostAddress(leIpSrcAddr->text()).toIPv4Address(); + pStream->l3.ip.srcIpMode = (Stream::IpAddrMode) cmbIpSrcAddrMode->currentIndex(); + pStream->l3.ip.srcIpCount = leIpSrcAddrCount->text().toULong(&isOk); + pStream->l3.ip.srcIpMask = QHostAddress(leIpSrcAddrMask->text()).toIPv4Address(); + + pStream->l3.ip.dstIp = QHostAddress(leIpDstAddr->text()).toIPv4Address(); + pStream->l3.ip.dstIpMode = (Stream::IpAddrMode) cmbIpDstAddrMode->currentIndex(); + pStream->l3.ip.dstIpCount = leIpDstAddrCount->text().toULong(&isOk); + pStream->l3.ip.dstIpMask = QHostAddress(leIpDstAddrMask->text()).toIPv4Address(); + } + + // L3 | ARP + { + // TODO + } + } + + // L4 + { + // L4 | TCP + { + pStream->l4.tcp.tcpMask = 0; + + pStream->l4.tcp.srcPort = leTcpSrcPort->text().toULong(&isOk); + pStream->l4.tcp.dstPort = leTcpDstPort->text().toULong(&isOk); + + pStream->l4.tcp.seqNum = leTcpSeqNum->text().toULong(&isOk); + pStream->l4.tcp.ackNum = leTcpAckNum->text().toULong(&isOk); + + pStream->l4.tcp.hdrLen = leTcpHdrLen->text().toULong(&isOk); + if (cbTcpHdrLenOverride->isChecked()) + pStream->l4.tcp.tcpMask |= TM_OVERRIDE_HDRLEN; + + pStream->l4.tcp.window = leTcpWindow->text().toULong(&isOk); + + pStream->l4.tcp.cksum = leTcpCksum->text().remove(QChar(' ')).toULong(&isOk); + if (cbTcpCksumOverride->isChecked()) + pStream->l4.tcp.tcpMask |= TM_OVERRIDE_CKSUM; + + pStream->l4.tcp.urgPtr = leTcpUrgentPointer->text().toULong(&isOk); + + pStream->l4.tcp.flags = 0; + if (cbTcpFlagsUrg->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_URG; + if (cbTcpFlagsAck->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_ACK; + if (cbTcpFlagsPsh->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_PSH; + if (cbTcpFlagsRst->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_RST; + if (cbTcpFlagsSyn->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_SYN; + if (cbTcpFlagsFin->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_FIN; + } + + // L4 | UDP + { + pStream->l4.udp.udpMask = 0; + + pStream->l4.udp.srcPort = leUdpSrcPort->text().toULong(&isOk); + pStream->l4.udp.dstPort = leUdpDstPort->text().toULong(&isOk); + + pStream->l4.udp.totLen = leUdpLength->text().toULong(&isOk); + if (cbUdpLengthOverride->isChecked()) pStream->l4.udp.udpMask |= UM_OVERRIDE_TOTLEN; + + pStream->l4.udp.cksum = leUdpCksum->text().remove(QChar(' ')).toULong(&isOk); + if (cbUdpCksumOverride->isChecked()) pStream->l4.udp.udpMask |= UM_OVERRIDE_CKSUM; + } + + // L4 | ICMP + { + // TODO + } + + // L4 | IGMP + { + // TODO + } + } +} +void StreamConfigDialog::on_pbOk_clicked() +{ + // Store dialog contents into stream + StoreCurrentStream(); + qDebug("stream stored"); +} + +//Junk Line for introducing a compiler error + diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h new file mode 100644 index 0000000..95e7380 --- /dev/null +++ b/client/streamconfigdialog.h @@ -0,0 +1,58 @@ +#ifndef _STREAM_CONFIG_DIALOG_H +#define _STREAM_CONFIG_DIALOG_H + +#include +#include "ui_streamconfigdialog.h" +#include + +#define MAX_MAC_ITER_COUNT 256 +#define MIN_PKT_LEN 64 +#define MAX_PKT_LEN 1522 + +/* +** TODO +** - Improve HexStr handling +** +*/ + +class StreamConfigDialog : public QDialog, public Ui::StreamConfigDialog +{ + Q_OBJECT +public: + StreamConfigDialog(QList *streamList, uint streamIndex, + QWidget *parent = 0); + ~StreamConfigDialog(); + +private: + QList *mpStreamList; + uint mCurrentStreamIndex; + + void setupUiExtra(); + void LoadCurrentStream(); + void StoreCurrentStream(); + +private slots: + void on_cmbDstMacMode_currentIndexChanged(QString mode); + void on_pbPrev_clicked(); + void on_pbNext_clicked(); + + void on_rbFtLlcSnap_toggled(bool checked); + + void on_rbL3Ipv4_toggled(bool checked); + void on_rbL3Arp_toggled(bool checked); + + void on_rbL4Icmp_toggled(bool checked); + void on_rbL4Igmp_toggled(bool checked); + void on_rbL4Tcp_toggled(bool checked); + void on_rbL4Udp_toggled(bool checked); + void on_rbL4Other_toggled(bool checked); + + void update_NumPacketsAndNumBursts(); + + void on_pbOk_clicked(); +}; + +QString & uintToHexStr(quint32 num, QString &hexStr, quint8 octets); + +#endif + diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui new file mode 100644 index 0000000..85f29e3 --- /dev/null +++ b/client/streamconfigdialog.ui @@ -0,0 +1,3224 @@ + + StreamConfigDialog + + + Qt::ApplicationModal + + + + 0 + 0 + 554 + 521 + + + + Dialog + + + QLineEdit:enabled[inputMask = "HH; "], +QLineEdit:enabled[inputMask = "HH HH; "], +QLineEdit:enabled[inputMask = "HH HH HH; "], +QLineEdit:enabled[inputMask = "HH HH HH HH; "], +QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff } + + + + true + + + + + + + + + 0 + + + + Packet Config + + + + + + Qt::Horizontal + + + + 171 + 20 + + + + + + + + Data Pattern + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + Random + + + + + + + + HH HH HH HH; + + + + + + 11 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Frame Length (including CRC) + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + Random + + + + + + + + Min + + + + + + + 64 + + + 32767 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 64 + + + 32767 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Max + + + + + + + 64 + + + 32767 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 2 + + + + Protocols + + + + + + Frame Type + + + + + + + + + + None + + + false + + + + + + + Ethernet II + + + false + + + + + + + 802.3 Raw + + + + + + + 802.3 LLC + + + true + + + + + + + LLC SNAP + + + + + + + + + Qt::Vertical + + + + + + + + + DSAP + + + + + + + true + + + HH; + + + + + + + SSAP + + + + + + + true + + + HH; + + + + + + + Control + + + + + + + true + + + HH; + + + + + + + OUI + + + + + + + true + + + HH HH HH; + + + + + + + Type + + + + + + + true + + + HH HH; + + + + + + + + + + + + + + L3 + + + + + + None + + + true + + + + + + + IPv4 + + + false + + + + + + + ARP + + + + + + + Other + + + + + + + + + + L4 + + + + + + None + + + true + + + + + + + false + + + ICMP + + + + + + + false + + + IGMP + + + + + + + false + + + TCP + + + + + + + false + + + UDP + + + + + + + false + + + Other + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + L2 + + + + + + Ethernet + + + + + + Destination + + + + + + + HH HH HH HH HH HH; + + + + + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + + + + Count + + + + + + + false + + + 1 + + + 1 + + + + + + + Step + + + + + + + false + + + 1 + + + 1 + + + + + + + Source + + + + + + + HH HH HH HH HH HH; + + + + + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + + + + Count + + + + + + + false + + + 1 + + + + + + + Step + + + + + + + false + + + 1 + + + 1 + + + + + + + + + + VLAN/CVLAN + + + true + + + false + + + + + + Priority + + + + + + + CFI + + + + + + + VLAN + + + + + + + false + + + Override TPID + + + + + + + false + + + + 0 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + + + + false + + + + 0 + + + + + 1 + + + + + + + + false + + + 0 + + + + + + + false + + + HH HH; + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + SVLAN + + + true + + + false + + + + + + Priority + + + + + + + CFI + + + + + + + VLAN + + + + + + + false + + + Override TPID + + + + + + + false + + + + 0 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + + + + false + + + + 0 + + + + + 1 + + + + + + + + false + + + 0 + + + + + + + false + + + HH HH; + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + L3 + + + + + + 0 + + + + + + + + + Override Version + + + + + + + false + + + 4 + + + + + + + Override Header Length + + + + + + + false + + + 5 + + + + + + + TOS/DSCP + + + + + + + HH; + + + + + + + + + + false + + + ... + + + + + + + Override Length + + + + + + + false + + + + + + + Identification + + + + + + + HH HH; + + + + + + + + + Qt::Vertical + + + + + + + + + Fragment Offset + + + + + + + + + + Don't Fragment + + + + + + + More Fragments + + + + + + + Time To Live (TTL) + + + + + + + 64 + + + + + + + Protocol + + + + + + + false + + + + + + + + + + Override Checksum + + + + + + + false + + + HH HH; + + + + + + + + + + + + false + + + + + + Mode + + + + + + + Count + + + + + + + Mask + + + + + + + Source + + + + + + + 009.009.009.009; + + + ... + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment Host + + + + + Decrement Host + + + + + Random Host + + + + + + + + + + + + + + + 255.255.255.255 + + + + + + + Destination + + + + + + + 000.000.000.000; + + + ... + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment Host + + + + + Decrement Host + + + + + Random Host + + + + + + + + + + + + + + + 255.255.255.255 + + + + + + + + + + + + Options + + + + + + + false + + + TODO + + + + + + + false + + + ... + + + + + + + + + Qt::Vertical + + + + 470 + 16 + + + + + + + + + + + 105 + 100 + 296 + 76 + + + + ARP : TODO + + + Qt::AlignCenter + + + + + + + + + + L4 + + + + + + 1 + + + + + + + + + Source Port + + + + + + + + + + Destination Port + + + + + + + + + + Sequence Number + + + + + + + + + + Acknowledgement Number + + + + + + + + + + Override Header Length (x4) + + + + + + + false + + + + + + + Window + + + + + + + + + + Override Checksum + + + + + + + false + + + HH HH; + + + + + + + Urgent Pointer + + + + + + + + + + + + Qt::Vertical + + + + + + + Flags + + + + + + URG + + + + + + + ACK + + + + + + + PSH + + + + + + + RST + + + + + + + SYN + + + + + + + FIN + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 181 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Source Port + + + + + + + + + + Destination Port + + + + + + + + + + Override Length + + + + + + + false + + + + + + + Override Checksum + + + + + + + false + + + HH HH; + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + ICMP: TODO + + + + + + + + + + + IGMP: TODO + + + + + + + + + + + + + + + + Stream Control + + + + + + Send + + + + + + Packets + + + true + + + + + + + Bursts + + + + + + + + + + Numbers + + + + + + Number of Packets + + + leNumPackets + + + + + + + 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Number of Bursts + + + leNumPackets + + + + + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Packets per Burst + + + leNumPackets + + + + + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + After this stream + + + + + + Stop + + + + + + + Goto Next Stream + + + true + + + + + + + Goto Stream + + + + + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Mode + + + + + + Fixed + + + true + + + + + + + Continuous + + + + + + + + + + Qt::Horizontal + + + + 41 + 20 + + + + + + + + Qt::Horizontal + + + + + + + Rate + + + false + + + false + + + + + + Packets/Sec + + + leNumPackets + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Bursts/Sec + + + leNumPackets + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + true + + + Gaps + + + false + + + false + + + + + + + + + icons/gaps.png + + + + + + + ISG + + + leNumPackets + + + + + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + IPG + + + leNumPackets + + + + + + + IBG + + + leNumPackets + + + + + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Packet View + + + + + + Qt::Vertical + + + + true + + + + New Column + + + + + Ethernet + + + + DstMac: 00:00:00:00:00:00 + + + + + SrcMac: 00:00:00:00:00:00 + + + + + EtherType: IP (0800) + + + + + + IP + + + + Version: 4 + + + + + Header Length: 20 + + + + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;">0004 00 00 00 00 00 00</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> + + + + + + + + + + + + + + Prev + + + + + + + Next + + + + + + + Qt::Horizontal + + + + 191 + 20 + + + + + + + + OK + + + true + + + + + + + Cancel + + + + + + + + + + HexLineEdit + QLineEdit +
hexlineedit.h
+
+
+ + twTopLevel + cmbPatternMode + lePattern + cmbPktLenMode + lePktLen + lePktLenMin + lePktLenMax + twProto + leDstMac + cmbDstMacMode + leDstMacCount + leDstMacStep + leSrcMac + cmbSrcMacMode + leSrcMacCount + leSrcMacStep + gbCvlan + cmbCvlanPrio + cmbCvlanCfi + leCvlanId + cbCvlanTpidOverride + leCvlanTpid + gbSvlan + cmbSvlanPrio + cmbSvlanCfi + leSvlanId + cbSvlanTpidOverride + leSvlanTpid + + + + + + + cbCvlanTpidOverride + toggled(bool) + leCvlanTpid + setEnabled(bool) + + + 147 + 238 + + + 147 + 238 + + + + + cbSvlanTpidOverride + toggled(bool) + leSvlanTpid + setEnabled(bool) + + + 147 + 238 + + + 147 + 238 + + + + + gbCvlan + toggled(bool) + cmbCvlanPrio + setEnabled(bool) + + + 101 + 238 + + + 101 + 238 + + + + + gbCvlan + toggled(bool) + cmbCvlanCfi + setEnabled(bool) + + + 101 + 238 + + + 101 + 238 + + + + + gbCvlan + toggled(bool) + leCvlanId + setEnabled(bool) + + + 101 + 238 + + + 133 + 238 + + + + + gbCvlan + toggled(bool) + cbCvlanTpidOverride + setEnabled(bool) + + + 101 + 238 + + + 147 + 238 + + + + + gbSvlan + toggled(bool) + cmbSvlanPrio + setEnabled(bool) + + + 101 + 238 + + + 101 + 238 + + + + + gbSvlan + toggled(bool) + leSvlanId + setEnabled(bool) + + + 101 + 238 + + + 101 + 238 + + + + + gbSvlan + toggled(bool) + cbSvlanTpidOverride + setEnabled(bool) + + + 101 + 238 + + + 147 + 238 + + + + + gbSvlan + toggled(bool) + cmbSvlanCfi + setEnabled(bool) + + + 101 + 238 + + + 101 + 238 + + + + + cbUdpLengthOverride + toggled(bool) + leUdpLength + setEnabled(bool) + + + 79 + 247 + + + 99 + 247 + + + + + cbUdpCksumOverride + toggled(bool) + leUdpCksum + setEnabled(bool) + + + 79 + 247 + + + 99 + 247 + + + + + cbIpVersionOverride + toggled(bool) + leIpVersion + setEnabled(bool) + + + 42 + 171 + + + 232 + 170 + + + + + cbIpHdrLenOverride + toggled(bool) + leIpHdrLen + setEnabled(bool) + + + 42 + 197 + + + 232 + 196 + + + + + cbIpLengthOverride + toggled(bool) + leIpLength + setEnabled(bool) + + + 42 + 252 + + + 232 + 251 + + + + + cbIpCksumOverride + toggled(bool) + leIpCksum + setEnabled(bool) + + + 383 + 274 + + + 506 + 274 + + + + + cbTcpHdrLenOverride + toggled(bool) + leTcpHdrLen + setEnabled(bool) + + + 79 + 247 + + + 99 + 247 + + + + + cbTcpCksumOverride + toggled(bool) + leTcpCksum + setEnabled(bool) + + + 79 + 247 + + + 99 + 247 + + + + + rbFtNone + toggled(bool) + lblDsap + setHidden(bool) + + + 43 + 186 + + + 137 + 185 + + + + + rbFtNone + toggled(bool) + leDsap + setHidden(bool) + + + 43 + 186 + + + 178 + 185 + + + + + rbFtNone + toggled(bool) + lblSsap + setHidden(bool) + + + 43 + 186 + + + 137 + 211 + + + + + rbFtNone + toggled(bool) + leSsap + setHidden(bool) + + + 43 + 186 + + + 178 + 211 + + + + + rbFtNone + toggled(bool) + lblControl + setHidden(bool) + + + 43 + 186 + + + 137 + 237 + + + + + rbFtNone + toggled(bool) + leControl + setHidden(bool) + + + 43 + 186 + + + 178 + 237 + + + + + rbFtNone + toggled(bool) + lblOui + setHidden(bool) + + + 43 + 186 + + + 137 + 263 + + + + + rbFtNone + toggled(bool) + leOui + setHidden(bool) + + + 43 + 186 + + + 178 + 263 + + + + + rbFtNone + toggled(bool) + lblTpe + setHidden(bool) + + + 43 + 186 + + + 137 + 289 + + + + + rbFtNone + toggled(bool) + leType + setHidden(bool) + + + 43 + 186 + + + 178 + 289 + + + + + rbFtEthernet2 + toggled(bool) + lblDsap + setHidden(bool) + + + 43 + 211 + + + 137 + 185 + + + + + rbFtEthernet2 + toggled(bool) + leDsap + setHidden(bool) + + + 43 + 211 + + + 178 + 185 + + + + + rbFtEthernet2 + toggled(bool) + lblSsap + setHidden(bool) + + + 43 + 211 + + + 137 + 211 + + + + + rbFtEthernet2 + toggled(bool) + leSsap + setHidden(bool) + + + 43 + 211 + + + 178 + 211 + + + + + rbFt802Dot3Raw + toggled(bool) + lblControl + setHidden(bool) + + + 43 + 236 + + + 137 + 237 + + + + + rbFt802Dot3Raw + toggled(bool) + leControl + setHidden(bool) + + + 43 + 236 + + + 178 + 237 + + + + + rbFtEthernet2 + toggled(bool) + lblControl + setHidden(bool) + + + 43 + 211 + + + 137 + 237 + + + + + rbFtEthernet2 + toggled(bool) + leControl + setHidden(bool) + + + 43 + 211 + + + 178 + 237 + + + + + rbFtEthernet2 + toggled(bool) + lblOui + setHidden(bool) + + + 43 + 211 + + + 137 + 263 + + + + + rbFtEthernet2 + toggled(bool) + leOui + setHidden(bool) + + + 43 + 211 + + + 178 + 263 + + + + + rbFt802Dot3Raw + toggled(bool) + lblDsap + setHidden(bool) + + + 43 + 236 + + + 137 + 185 + + + + + rbFt802Dot3Raw + toggled(bool) + leDsap + setHidden(bool) + + + 43 + 236 + + + 178 + 185 + + + + + rbFt802Dot3Raw + toggled(bool) + lblSsap + setHidden(bool) + + + 43 + 236 + + + 137 + 211 + + + + + rbFt802Dot3Raw + toggled(bool) + leSsap + setHidden(bool) + + + 43 + 236 + + + 178 + 211 + + + + + rbFt802Dot3Raw + toggled(bool) + lblControl + setHidden(bool) + + + 43 + 236 + + + 137 + 237 + + + + + rbFt802Dot3Raw + toggled(bool) + leControl + setHidden(bool) + + + 43 + 236 + + + 178 + 237 + + + + + rbFt802Dot3Raw + toggled(bool) + lblOui + setHidden(bool) + + + 43 + 236 + + + 137 + 263 + + + + + rbFt802Dot3Raw + toggled(bool) + leOui + setHidden(bool) + + + 43 + 236 + + + 178 + 263 + + + + + rbFt802Dot3Raw + toggled(bool) + lblTpe + setHidden(bool) + + + 43 + 236 + + + 137 + 289 + + + + + rbFt802Dot3Raw + toggled(bool) + leType + setHidden(bool) + + + 43 + 236 + + + 178 + 289 + + + + + pbOk + clicked() + StreamConfigDialog + accept() + + + 460 + 510 + + + 565 + 433 + + + + + pbCancel + clicked() + StreamConfigDialog + reject() + + + 543 + 510 + + + 561 + 466 + + + + + rbFtLlcSnap + toggled(bool) + leDsap + setDisabled(bool) + + + 43 + 286 + + + 178 + 185 + + + + + rbFtLlcSnap + toggled(bool) + leSsap + setDisabled(bool) + + + 43 + 286 + + + 178 + 211 + + + + + rbFtLlcSnap + toggled(bool) + leControl + setDisabled(bool) + + + 43 + 286 + + + 178 + 237 + + + + + rbL3Ipv4 + toggled(bool) + rbL4Tcp + setEnabled(bool) + + + 355 + 196 + + + 300 + 291 + + + + + rbL3Ipv4 + toggled(bool) + rbL4Udp + setEnabled(bool) + + + 355 + 196 + + + 372 + 291 + + + + + rbL3Ipv4 + toggled(bool) + rbL4Other + setEnabled(bool) + + + 355 + 196 + + + 443 + 291 + + + + + rbL3Ipv4 + toggled(bool) + rbL4Icmp + setEnabled(bool) + + + 355 + 196 + + + 372 + 267 + + + + + rbL3Ipv4 + toggled(bool) + rbL4Igmp + setEnabled(bool) + + + 355 + 196 + + + 443 + 267 + + + + + rbL3None + clicked() + rbL4None + click() + + + 300 + 196 + + + 300 + 267 + + + + + rbL3Arp + clicked() + rbL4None + click() + + + 407 + 196 + + + 300 + 267 + + + + + rbL3Other + clicked() + rbL4None + click() + + + 457 + 196 + + + 300 + 267 + + + + + rbActionGotoStream + toggled(bool) + leStreamId + setEnabled(bool) + + + 334 + 147 + + + 411 + 177 + + + + + rbSendPackets + toggled(bool) + lePacketsPerSec + setEnabled(bool) + + + 38 + 73 + + + 180 + 284 + + + + + rbSendBursts + toggled(bool) + leBurstsPerSec + setEnabled(bool) + + + 46 + 98 + + + 162 + 313 + + + + + rbSendBursts + toggled(bool) + lePacketsPerBurst + setEnabled(bool) + + + 73 + 108 + + + 225 + 184 + + + + +
diff --git a/client/streamlistmodel.cpp b/client/streamlistmodel.cpp new file mode 100644 index 0000000..9812720 --- /dev/null +++ b/client/streamlistmodel.cpp @@ -0,0 +1,119 @@ +#include "streamlistmodel.h" + +StreamListModel::StreamListModel(QObject *parent) + : QAbstractTableModel(parent) +{ + uint i; + + // Enable all streams by default + for (i=0; i= MAX_ROWS) + return QVariant(); + + if (index.column() >= MAX_COLS) + return QVariant(); + + // Check role + if (index.column() == 0) // Icon + { + if ((role == Qt::DisplayRole)) + return QString("EDIT"); + else + return QVariant(); + } + else if (index.column() == 1) // Name + { + if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) + return streamList[index.row()].streamName; + else + return QVariant(); + } + else if (index.column() == 2) // Enabled? + { + //if ((role == Qt::CheckStateRole) || (role == Qt::EditRole)) + // return streamList[index.row()].isEnabled ? Qt::Checked : Qt::Unchecked; + if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) + return streamList[index.row()].isEnabled; + else + return QVariant(); + } +} + +bool StreamListModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (index.isValid() && role == Qt::EditRole) + { + if (index.column() == 1) // Name + streamList[index.row()].streamName = value.toString(); + else if (index.column() == 2) // Enabled? + streamList[index.row()].isEnabled = value.toBool(); + else + return false; + + return true; + } + return false; +} + +QVariant StreamListModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return StreamListCols.at(section); + else + return QString("%1").arg(section+1); +} + +#if 0 +// QModelIndex StreamListModel::index (int portNum, PortStat stat, const QModelIndex & parent = QModelIndex() ) const + +void StreamListModel::on_portStatsUpdate(int port, void*stats) +{ + int i; + QModelIndex topLeft = index(port, 0, QModelIndex()); + QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex()); + + for (i = 0; i < e_STAT_MAX; i++) + dummyStats[port][i] = ((int *)stats)[i]; + + emit dataChanged(topLeft, bottomRight); +} + +#endif diff --git a/client/streamlistmodel.h b/client/streamlistmodel.h new file mode 100644 index 0000000..54c222b --- /dev/null +++ b/client/streamlistmodel.h @@ -0,0 +1,46 @@ +#ifndef _STREAM_LIST_MODEL_H +#define _STREAM_LIST_MODEL_H + +#include +#include + +static QStringList StreamListCols = (QStringList() + << "Icon" + << "Name" + << "Enable" +); + +#define MAX_ROWS 5 +#define MAX_COLS 3 + +class StreamListModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + //StreamListModel(QObject *parent = 0) : QAbstractTableModel(parent) {} + StreamListModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + // QModelIndex index (int portNum, PortStat stat, const QModelIndex & parent = QModelIndex() ) const; + + public slots: +// void on_portStatsUpdate(int port, void*stats); + + private: + // FIXME: temp +//#define NUM_PORTS 2 +// int dummyStats[NUM_PORTS][e_STAT_MAX]; + struct { + QString streamName; + bool isEnabled; + } streamList[MAX_ROWS]; + +}; + +#endif diff --git a/client/streammodel.cpp b/client/streammodel.cpp new file mode 100644 index 0000000..21588b7 --- /dev/null +++ b/client/streammodel.cpp @@ -0,0 +1,218 @@ +#include "streammodel.h" +#include "portgrouplist.h" +#include "qicon.h" + +StreamModel::StreamModel(PortGroupList *p, QObject *parent) + : QAbstractTableModel(parent) +{ + pgl = p; + mCurrentPort = NULL; +} + +int StreamModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + if (mCurrentPort) + return mCurrentPort->mStreams.size(); + else + return 0; +} + +int StreamModel::columnCount(const QModelIndex &parent ) const +{ + return (int) StreamMaxFields; +} + +Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + + + switch (index.column()) + { + case StreamIcon: + break; + case StreamName: + flags |= Qt::ItemIsEditable; + break; + case StreamStatus: + flags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable; + break; + default: + break; + } + + return flags; +} +QVariant StreamModel::data(const QModelIndex &index, int role) const +{ + // Check for a valid index + if (!index.isValid()) + return QVariant(); + + // Check for row/column limits + if (index.row() >= mCurrentPort->mStreams.size()) + return QVariant(); + + if (index.column() >= StreamMaxFields) + return QVariant(); + + if (mCurrentPort == NULL) + return QVariant(); + + // Return data based on field and role + switch(index.column()) + { + case StreamIcon: + { + if (role == Qt::DecorationRole) + return QIcon(":/icons/stream_edit.png"); +#if 0 + else if ((role == Qt::DisplayRole)) + return QString("EDIT"); +#endif + else + return QVariant(); + break; + } + case StreamName: + { + if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) + return mCurrentPort->mStreams[index.row()].name(); + else + return QVariant(); + break; + } + case StreamStatus: + { + #if 0 + if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) + return streamList[index.row()].isEnabled; + if ((role == Qt::DisplayRole) || (role == Qt::CheckStateRole) || + #endif + if ((role == Qt::CheckStateRole) || (role == Qt::EditRole)) + { + if (mCurrentPort->mStreams[index.row()].isEnabled()) + return Qt::Checked; + else + return Qt::Unchecked; + } + else + return QVariant(); + break; + } + default: + qDebug("-------------UNHANDLED STREAM FIELD----------------"); + } + + return QVariant(); +} + +bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (mCurrentPort == NULL) + return false; + + if (index.isValid() && role == Qt::EditRole) + { + // Edit Supported Fields + switch (index.column()) + { + case StreamName: + mCurrentPort->mStreams[index.row()].setName(value.toString()); + return true; + break; + case StreamStatus: + mCurrentPort->mStreams[index.row()].setEnabled(value.toBool()); + return true; + break; + + // Edit Not Supported Fields + case StreamIcon: + return false; + break; + + // Unhandled Stream Field + default: + qDebug("-------------UNHANDLED STREAM FIELD----------------"); + break; + } + } + return false; +} + +QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + { + switch(section) + { + case StreamIcon: + return QString("Icon"); + break; + case StreamName: + return QString("Name"); + break; + case StreamStatus: + return QString("Enabled"); + break; + default: + qDebug("-------------UNHANDLED STREAM FIELD----------------"); + break; + } + } + else + return QString("%1").arg(section+1); + + return QVariant(); +} + +bool StreamModel::insertRows(int row, int count, const QModelIndex &parent) +{ + qDebug("insertRows() row = %d", row); + qDebug("insertRows() count = %d", count); + beginInsertRows(QModelIndex(), row, row+count-1); + for (int i = 0; i < count; i++) + mCurrentPort->mStreams.insert(row, Stream()); + endInsertRows(); + + return true; +} + +bool StreamModel::removeRows(int row, int count, const QModelIndex &parent) +{ + qDebug("removeRows() row = %d", row); + qDebug("removeRows() count = %d", count); + beginRemoveRows(QModelIndex(), row, row+count-1); + for (int i = 0; i < count; i++) + { + // FIXME(HIGH): do we need to free the removed stream? + mCurrentPort->mStreams.removeAt(row); + } + endRemoveRows(); + + return true; +} + +// --------------------- SLOTS ------------------------ + +void StreamModel::setCurrentPortIndex(const QModelIndex ¤t) +{ + if (!current.isValid() || !pgl->isPort(current)) + { + qDebug("current is either invalid or not a port"); + mCurrentPort = NULL; + } + else + { + qDebug("change to valid port"); + quint16 pg = current.internalId() >> 16; + mCurrentPort = &pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()]; + } + reset(); +} diff --git a/client/streammodel.h b/client/streammodel.h new file mode 100644 index 0000000..de648a2 --- /dev/null +++ b/client/streammodel.h @@ -0,0 +1,49 @@ +#ifndef _STREAM_MODEL_H +#define _STREAM_MODEL_H + +#include +#include "port.h" + +class PortGroupList; + +class StreamModel : public QAbstractTableModel +{ + Q_OBJECT + + enum StreamFields { + StreamIcon = 0, + StreamName, + StreamStatus, + + StreamMaxFields + }; + + Port *mCurrentPort; + PortGroupList *pgl; + + public: + StreamModel(PortGroupList *p, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + bool insertRows (int row, int count, + const QModelIndex & parent = QModelIndex()); + bool removeRows (int row, int count, + const QModelIndex & parent = QModelIndex()); + + // FIXME(HIGH): This *is* like a kludge + QList* currentPortStreamList() + { return &mCurrentPort->mStreams; } + + public slots: + void setCurrentPortIndex(const QModelIndex ¤t); + +}; + +#endif diff --git a/common/protocol.h b/common/protocol.h new file mode 100644 index 0000000..f7c61dc --- /dev/null +++ b/common/protocol.h @@ -0,0 +1,53 @@ +#ifndef _PROTOCOL_H +#define _PROTOCOL_H + +#define UINT8 unsigned char +#define UINT16 unsigned short +#define UINT32 unsigned int + +#define BYTESWAP4(x) \ + (((x & 0xFF000000) >> 24) | \ + ((x & 0x00FF0000) >> 8) | \ + ((x & 0x0000FF00) << 8) | \ + ((x & 0x000000FF) << 24)) + +#define BYTESWAP2(x) \ + (((x & 0xFF00) >> 8) | \ + ((x & 0x00FF) << 8)) + +// TODO: portability +#define HTONL(x) BYTESWAP4(x) +#define NTOHL(x) BYTESWAP4(x) +#define HTONS(x) BYTESWAP2(x) +#define NTOHS(x) BYTESWAP2(x) + + +typedef struct { + UINT8 ver; + UINT8 resv1; + UINT16 resv2; + UINT16 msgType; + UINT16 msgLen; +} tCommHdr; + +typedef enum { + e_MT_CapabilityReq=1, + e_MT_CapabilityInfo +} eMsgType; + +typedef enum { + e_TT_PortCapability +} eTlvType; + +typedef struct { + UINT16 tlvType; + UINT16 tlvLen; + UINT32 port; + UINT32 speed; +#define TLV_MAX_PORT_NAME 64 +#define TLV_MAX_PORT_DESC 64 + char name[TLV_MAX_PORT_NAME]; + char desc[TLV_MAX_PORT_DESC]; +} tTlvPortCapability; + +#endif diff --git a/server/abstracthost.h b/server/abstracthost.h new file mode 100644 index 0000000..38e266c --- /dev/null +++ b/server/abstracthost.h @@ -0,0 +1,12 @@ +#ifndef _ABSTRACT_HOST +#define _ABSTRACT_HOST + +class AbstractHost +{ + public: + virtual void Log(const char* str) = 0; + virtual int SendMsg(const void* msg, int size) = 0; +}; + +#endif + diff --git a/server/drone.cpp b/server/drone.cpp new file mode 100644 index 0000000..54bf9cf --- /dev/null +++ b/server/drone.cpp @@ -0,0 +1,85 @@ +#include "drone.h" + +extern int myport; // FIXME(HIGH) + +Drone::Drone(QDialog *parent) + : QDialog(parent) +{ + ui.setupUi(this); + serverPortNum = DRONE_PORT; + clientSock = NULL; + + if (myport) + serverPortNum = myport; + + rxtx = new RxTx(this); + + server = new QTcpServer(this); + connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); + //if (!server->listen(QHostAddress("10.0.0.1"), serverPortNum)) + if (!server->listen(QHostAddress::Any, serverPortNum)) + LogInt(tr("Unable to start the server: %1").arg(server->errorString())); + else + LogInt(tr("The server is running on %1:%2").arg(server->serverAddress().toString()).arg(server->serverPort())); +} + +void Drone::Log(const char* str) +{ + ui.teLog->append(QString(str)); +} + +int Drone::SendMsg(const void* msg, int size) +{ + qDebug("Inside SendMsg\n"); + clientSock->write((char*) msg, size); +} + +void Drone::LogInt(const QString &str) +{ + ui.teLog->append(str); +} + +void Drone::when_newConnection() +{ + if (clientSock) + { + QTcpSocket *sock; + + LogInt(tr("already connected, no new connections will be accepted\n")); + sock = server->nextPendingConnection(); + // TODO: Send reason msg to client + sock->disconnectFromHost(); + goto _exit; + } + clientSock = server->nextPendingConnection(); + LogInt(tr("accepting new connection from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); + connect(clientSock, SIGNAL(readyRead()), + this, SLOT(when_dataAvail())); + connect(clientSock, SIGNAL(disconnected()), + this, SLOT(when_disconnected())); + connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(when_error(QAbstractSocket::SocketError))); + + +_exit: + return; +} + +void Drone::when_disconnected() +{ + LogInt(tr("closing connection from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); + clientSock->deleteLater(); + clientSock = NULL; +} + +void Drone::when_dataAvail() +{ + QByteArray msg = clientSock->read(1024); // FIXME: hardcoding + LogInt(QString(msg.toHex())); + rxtx->ProcessMsg(msg.constData(), msg.size()); +} + +void Drone::when_error(QAbstractSocket::SocketError socketError) +{ + LogInt(clientSock->errorString()); +} diff --git a/server/drone.h b/server/drone.h new file mode 100644 index 0000000..f99255b --- /dev/null +++ b/server/drone.h @@ -0,0 +1,36 @@ +#ifndef _DRONE_H +#define _DRONE_H + +#include +#include +#include "ui_drone.h" +#include "abstracthost.h" +#include "rxtx.h" + + +class Drone : public QDialog, AbstractHost +{ + Q_OBJECT + + public: + Drone(QDialog *parent = 0); + void Log(const char *msg); + int SendMsg(const void* msg, int msgLen); + + Ui::Drone ui; + private: + RxTx *rxtx; + QTcpServer *server; + QTcpSocket *clientSock; +#define DRONE_PORT 7878 + quint16 serverPortNum; + // Ui::Drone ui; + void LogInt(const QString &msg); + private slots: + void when_newConnection(); + void when_disconnected(); + void when_dataAvail(); + void when_error(QAbstractSocket::SocketError socketError); +}; +#endif + diff --git a/server/drone.pro b/server/drone.pro new file mode 100644 index 0000000..1fd8862 --- /dev/null +++ b/server/drone.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +CONFIG += qt +QT += network +DEFINES += HAVE_REMOTE +INCLUDEPATH += "C:\DevelLibs\WpdPack\Include" +LIBS += -L"C:\DevelLibs\WpdPack\Lib" -lwpcap +HEADERS += drone.h +FORMS += drone.ui +SOURCES += drone_main.cpp drone.cpp rxtx.cpp diff --git a/server/drone.ui b/server/drone.ui new file mode 100644 index 0000000..5caa184 --- /dev/null +++ b/server/drone.ui @@ -0,0 +1,126 @@ + + Drone + + + + 0 + 0 + 400 + 300 + + + + Drone + + + + + + 1 + + + + Status + + + + + 160 + 100 + 46 + 14 + + + + TODO + + + + + + Log + + + + + + true + + + false + + + + + + + + + + + + + Clear Log + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Exit + + + + + + + + + + + pushButton + clicked(bool) + Drone + accept() + + + 341 + 279 + + + 226 + 268 + + + + + pbClearLog + clicked() + teLog + clear() + + + 52 + 278 + + + 100 + 185 + + + + + diff --git a/server/drone_main.cpp b/server/drone_main.cpp new file mode 100644 index 0000000..5a66b6a --- /dev/null +++ b/server/drone_main.cpp @@ -0,0 +1,22 @@ +#include "drone.h" + +Drone *drone; + +//void FindDevList(void); + +int myport; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + // FIXME(HIGH) + if (argc > 1) + myport = atoi(argv[1]); + + drone = new Drone; + //FindDevList(); + drone->show(); + return app.exec(); +} + diff --git a/server/rxtx.cpp b/server/rxtx.cpp new file mode 100644 index 0000000..7c0be69 --- /dev/null +++ b/server/rxtx.cpp @@ -0,0 +1,147 @@ +#include "rxtx.h" +#include "../common/protocol.h" +#include "qtglobal" // FIXME: needed only for qdebug + +//#define LOG(...) drone->ui.teLOG->append(QString().sprintf( __VA_ARGS__)) +//#define LOG(...) drone->LOG(QString().sprintf( __VA_ARGS__)) +#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} + + +RxTx::RxTx(AbstractHost *host) +{ + pcap_if_t *d; + int i=0; + char errbuf[PCAP_ERRBUF_SIZE]; + + // Init Data + RxTx::host = host; + numPorts = 0; + alldevs = NULL; + + LOG("Retrieving the device list from the local machine\n"); + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + LOG("Error in pcap_findalldevs_ex: %s\n", errbuf); + goto _fail; + } + + /* Count number of local ports */ + for(d = alldevs; d != NULL; d = d->next) + numPorts++; + + portInfo = new PortInfo[numPorts]; + + /* Print the list */ + for(i=0, d=alldevs; d!=NULL; i++, d=d->next) + { + portInfo[i].portId = i; + portInfo[i].dev = d; +#if 1 + LOG("%d. %s", i, d->name); + if (d->description) + { + LOG(" (%s)\n", d->description); + } + else + LOG(" (No description available)\n"); +#endif + } + + if (i == 0) + { + LOG("\nNo interfaces found! Make sure WinPcap is installed.\n"); + goto _fail; + } + +_fail: + return; +} + +#if 0 +RxTx::LOG(char* fmt, ...) +{ + sprintf(logStr, fmt, _VA_ARGS_); + host->LOG(logStr); +} +#endif + +RxTx::~RxTx() +{ + pcap_freealldevs(alldevs); +} + +void RxTx::ProcessMsg(const char* msg, int len) +{ + tCommHdr *hdr; + // TODO: For now, assuming we'll get a complete msg + // but need to fix this as this is a TCP stream + + hdr = (tCommHdr*) msg; + + if (hdr->ver != 1) // FIXME:hardcoding + { + LOG("Rcvd msg with invalid version %d\n", hdr->ver); + goto _exit; + } + + qDebug("msgType - %x: %x\n", hdr->msgType, NTOHS(hdr->msgType)); + switch (NTOHS(hdr->msgType)) + { + case e_MT_CapabilityReq: + SendCapabilityInfo(); + break; + + default: + LOG("Rcvd msg with unrecognized msgType %d\n", NTOHS(hdr->msgType)); + } + +_exit: + return; +} + +void RxTx::SendCapabilityInfo(void) +{ + unsigned char *msg, *p; + unsigned int i, msgLen; + + p = msg = (unsigned char*) pktBuff; + ((tCommHdr*)(p))->ver = 1; + ((tCommHdr*)(p))->msgType = HTONS(e_MT_CapabilityInfo); + p += sizeof(tCommHdr); + + for (i = 0; i < numPorts; i++) + { + // TLV: Port Capability + ((tTlvPortCapability*)(p))->tlvType = HTONS(e_TT_PortCapability); + ((tTlvPortCapability*)(p))->tlvLen = HTONS(sizeof(tTlvPortCapability)); + ((tTlvPortCapability*)(p))->port = HTONL(portInfo[i].portId); + ((tTlvPortCapability*)(p))->speed = 0; // TODO +#if 0 + strncpy(((tTlvPortCapability*)(p))->name, + portInfo[i].dev->name, TLV_MAX_PORT_NAME); + ((tTlvPortCapability*)(p))->name[TLV_MAX_PORT_NAME-1] = 0; +#else + strcpy(((tTlvPortCapability*)(p))->name, "eth"); + //strcat(((tTlvPortCapability*)(p))->name, itoa(portInfo[i].portId, NULL, 10)); + itoa(portInfo[i].portId, &(((tTlvPortCapability*)(p))->name[3]), 10); +#endif + strncpy(((tTlvPortCapability*)(p))->desc, + portInfo[i].dev->description, TLV_MAX_PORT_DESC); + ((tTlvPortCapability*)(p))->desc[TLV_MAX_PORT_DESC -1] = 0; + p += sizeof(tTlvPortCapability); + } + msgLen = (p - msg); + ((tCommHdr*)(msg))->msgLen = HTONS(msgLen); + + logStr[0] = 0; + for (i = 0; i < msgLen >> 2; i++) + { + char word[10]; + + sprintf(word, "%08X ", HTONL(((unsigned int *)(msg))[i])); + strcat(logStr, word); + } + host->Log("Sending msg\n"); + host->Log(logStr); + host->SendMsg(pktBuff, msgLen); +} diff --git a/server/rxtx.h b/server/rxtx.h new file mode 100644 index 0000000..97eb2c3 --- /dev/null +++ b/server/rxtx.h @@ -0,0 +1,35 @@ +#ifndef _RXTX_H +#define _RXTX_H + +#include "pcap.h" +#include "abstracthost.h" + + +typedef struct +{ + unsigned int portId; + pcap_if_t *dev; +} PortInfo; + +class RxTx +{ + public: + RxTx(AbstractHost* host); + ~RxTx(); + void ProcessMsg(const char* msg, int len); + + private: + AbstractHost *host; + char logStr[1024]; + +#define MAX_PKT_SIZE 1024 + unsigned char pktBuff[MAX_PKT_SIZE]; + unsigned numPorts; + PortInfo *portInfo; + pcap_if_t *alldevs; + + //void Log(char *fmt, ...); + void SendCapabilityInfo(void); +}; + +#endif From 8251383351b6bfd0905f19d6ed1c4b7a198a8559 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 25 May 2008 11:30:30 +0000 Subject: [PATCH 02/98] - added PortStatsFilter - added PacketDump (test code) - added PacketTree (not complete) - Protocol stuff (not complete) --- client/dumpview.cpp | 175 +++++++++++ client/dumpview.h | 34 +++ client/icons/portstats_filter.png | Bin 0 -> 432 bytes client/ostinato.pro | 7 + client/ostinato.qrc | 1 + client/packetmodel.cpp | 440 +++++++++++++++++++++++++++ client/packetmodel.h | 52 ++++ client/port.cpp | 2 + client/portgroup.cpp | 8 +- client/portstatsfilter.ui | 32 +- client/portstatsfilterdialog.cpp | 81 ++++- client/portstatsfilterdialog.h | 20 +- client/portstatswindow.cpp | 26 +- client/portstatswindow.h | 3 + client/portstatswindow.ui | 325 ++++++++++++-------- client/stream.h | 9 + client/streamconfigdialog.cpp | 11 + client/streamconfigdialog.h | 6 +- client/streamconfigdialog.ui | 490 ++++++++++++++---------------- common/protocol.h | 130 +++++++- server/rxtx.cpp | 379 ++++++++++++++++++++++- server/rxtx.h | 41 +++ 22 files changed, 1832 insertions(+), 440 deletions(-) create mode 100644 client/dumpview.cpp create mode 100644 client/dumpview.h create mode 100644 client/icons/portstats_filter.png create mode 100644 client/packetmodel.cpp create mode 100644 client/packetmodel.h diff --git a/client/dumpview.cpp b/client/dumpview.cpp new file mode 100644 index 0000000..a238e95 --- /dev/null +++ b/client/dumpview.cpp @@ -0,0 +1,175 @@ +#include "dumpview.h" + +DumpView::DumpView(QWidget *parent) +{ + int w, h; + + data.resize(73); + + // NOTE: Monospaced fonts only !!!!!!!!!!! + setFont(QFont("Courier")); + w = fontMetrics().width('X'); + h = fontMetrics().height(); + + mLineHeight = h; + mCharWidth = w; + + mSelectedRow = mSelectedCol = -1; + + // calculate width for offset column and the whitespace that follows it + mOffsetPaneTopRect = QRect(0, 0, w*4, h); + mDumpPaneTopRect = QRect(mOffsetPaneTopRect.right()+w*3, 0, + w*((8*3-1)+2+(8*3-1)), h); + mAsciiPaneTopRect = QRect(mDumpPaneTopRect.right()+w*3, 0, + w*(8+1+8), h); + qDebug("DumpView::DumpView"); +} + +#if 0 +QSize DumpView::sizeHint() const +{ +} +#endif + +void DumpView::mousePressEvent(QMouseEvent *event) +{ + int x = event->x(); + int row, col; + + if (x > mAsciiPaneTopRect.left()) + { + col = (x - mAsciiPaneTopRect.left()) / mCharWidth; + if (col == 8) // don't select whitespace + goto _exit; + else if (col > 8) // adjust for whitespace + col--; + } + else if (x > mDumpPaneTopRect.left()) + { + col = (x - mDumpPaneTopRect.left()) / (mCharWidth*3); + } + row = event->y()/mLineHeight; + + if ((col < 16) && (row < ((data.size()+16)/16))) + { + mSelectedRow = row; + mSelectedCol = col; + } + else + goto _exit; + + // last row check col + if ((row == (((data.size()+16)/16) - 1)) && (col >= (data.size() % 16))) + goto _exit; + + qDebug("dumpview::selection(%d, %d)", mSelectedRow, mSelectedCol); + update(); + return; + +_exit: + // Clear existing selection + mSelectedRow = -1; + update(); +} + +void DumpView::paintEvent(QPaintEvent* event) +{ + QStylePainter painter(this); + QRect offsetRect = mOffsetPaneTopRect; + QRect dumpRect = mDumpPaneTopRect; + QRect asciiRect = mAsciiPaneTopRect; + QPalette pal = palette(); + QByteArray ba; + + //qDebug("dumpview::paintEvent"); + + // FIXME(LOW): unable to set the self widget's font in constructor + painter.setFont(QFont("Courier")); + + // set a white background + painter.fillRect(rect(), QBrush(QColor(Qt::white))); + + // display the offset, dump and ascii panes 8 + 8 bytes on a line + for (int i = 0; i < data.size(); i+=16) + { + QString dumpStr, asciiStr; + + ba = data.mid(i, 16); + + // display offset + painter.drawItemText(offsetRect, Qt::AlignLeft | Qt::AlignTop, pal, + true, QString("%1").arg(i, 4, 16, QChar('0')), QPalette::WindowText); + // construct the dumpStr and asciiStr + for (int j = i; (j < (i+16)) && (j < data.size()); j++) + { + unsigned char c = data.at(j); + + // extra space after 8 bytes + if (((j+8) % 16) == 0) + { + dumpStr.append(" "); + asciiStr.append(" "); + } + + dumpStr.append(QString("%1").arg((uint)c, 2, 16, QChar('0')). + toUpper()).append(" "); + + if (isPrintable(c)) + asciiStr.append(QChar(c)); + else + asciiStr.append(QChar('.')); + } + + // display dump + painter.drawItemText(dumpRect, Qt::AlignLeft | Qt::AlignTop, pal, + true, dumpStr, QPalette::WindowText); + + // display ascii + painter.drawItemText(asciiRect, Qt::AlignLeft | Qt::AlignTop, pal, + true, asciiStr, QPalette::WindowText); + + // overpaint selection (if any) + if ((i/16) == mSelectedRow) + { + QRect r; + unsigned char c = data.at(mSelectedRow*16+mSelectedCol); + QString selectedAsciiStr, selectedDumpStr; + + qDebug("dumpview::paintEvent - Highlighted"); + + selectedDumpStr.append(QString("%1").arg((uint) c, 2, 16, QChar('0')).toUpper()); + + if (isPrintable(c)) + selectedAsciiStr.append(QChar(c)); + else + selectedAsciiStr.append(QChar('.')); + + // display dump + r = dumpRect; + if (mSelectedCol < 8) + r.translate(mCharWidth*(mSelectedCol*3), 0); + else + r.translate(mCharWidth*(mSelectedCol*3+1), 0); + r.setWidth(mCharWidth*2); + painter.fillRect(r, pal.highlight()); + painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, + true, selectedDumpStr, QPalette::HighlightedText); + + // display ascii + r = asciiRect; + if (mSelectedCol < 8) + r.translate(mCharWidth*(mSelectedCol), 0); + else + r.translate(mCharWidth*(mSelectedCol+1), 0); + r.setWidth(mCharWidth); + painter.fillRect(r, pal.highlight()); + painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, + true, selectedAsciiStr, QPalette::HighlightedText); + } + + // move the rects down + offsetRect.translate(0, mLineHeight); + dumpRect.translate(0, mLineHeight); + asciiRect.translate(0, mLineHeight); + } +} diff --git a/client/dumpview.h b/client/dumpview.h new file mode 100644 index 0000000..4578a91 --- /dev/null +++ b/client/dumpview.h @@ -0,0 +1,34 @@ +#include // FIXME: High + +class DumpView: public QWidget // QAbstractItemView // FIXME +{ +public: + DumpView(QWidget *parent=0); + // bool setBase(uint base); // valid values: 16, 8, 10, 2 etc. + // void hideAsciiPane(void); + // void showAsciiPane(void); + // void hideOffsetPane(void); + // void showOffsetPane(void); + + + //QSize sizeHint() const; + +protected: + void mousePressEvent(QMouseEvent *event); + //void mouseMoveEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); + +private: + QString toAscii(QByteArray ba); + bool inline isPrintable(char c) + {if ((c > 48) && (c < 126)) return true; else return false; } + +private: + QRect mOffsetPaneTopRect; + QRect mDumpPaneTopRect; + QRect mAsciiPaneTopRect; + QByteArray data; + int mSelectedRow, mSelectedCol; + int mLineHeight; + int mCharWidth; +}; diff --git a/client/icons/portstats_filter.png b/client/icons/portstats_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..46060872cc1e32d6dc557e50d53a3d395e9916ea GIT binary patch literal 432 zcmV;h0Z;ykP)X1>|Jb)Dfc3=%9wAxt9|F z+d&sV7i|Riicons/portgroup_connect.png icons/portgroup_delete.png icons/portgroup_disconnect.png + icons/portstats_filter.png icons/sound_mute.png icons/sound_none.png icons/stream_add.png diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp new file mode 100644 index 0000000..4cbc92c --- /dev/null +++ b/client/packetmodel.cpp @@ -0,0 +1,440 @@ +#include "packetmodel.h" + + +PacketModel::PacketModel(Stream *pStream, QObject *parent) +{ + mpStream = pStream; +} + +int PacketModel::rowCount(const QModelIndex &parent) const +{ + // Parent - Invisible Root. + // Children - Top Level Items + if (!parent.isValid()) + { + int v = 0; + + if (mpStream->l2.eth.vlanMask & VM_SVLAN_TAGGED) + v++; + if (mpStream->l2.eth.vlanMask & VM_CVLAN_TAGGED) + v++; + + if (mpStream->proto.protoMask & PM_L3_PROTO_NONE) + return v+2; // L2, Data + if (mpStream->proto.protoMask & PM_L4_PROTO_NONE) + return v+3; // L2, L3, Data + else + return v+4; // L2, L3, L4, Data + } + + // Parent - Top Level Item (L2) + // Children(count) - Second Level Items (L2 fields) + if (isIndexL2Container(parent)) + { + switch(mpStream->proto.ft) + { + case Stream::e_ft_none: + return 2; // DstMac, SrcMac + break; + + case Stream::e_ft_eth_2: + case Stream::e_ft_802_3_raw: + return 3; // DstMac, SrcMac, Type/Len + break; + + case Stream::e_ft_802_3_llc: + case Stream::e_ft_snap: + return 5; // DstMac, SrcMac, Type, DSAP, SSAP, CTL, OUI, Type + break; + + default: + qDebug("%s: Unsupported frametype", __FUNCTION__); + return -1; + } + } + + // Parent - Top Level Item (SVLAN) + // Children(count) - Second Level Items (SVLAN fields) + if (isIndexSvlanContainer(parent)) + { + return 4; // TPID, PCP, DE, VlanId + } + + // Parent - Top Level Item (CVLAN) + // Children(count) - Second Level Items (CVLAN fields) + if (isIndexCvlanContainer(parent)) + { + return 4; // TPID, Prio, CFI, VlanId + } + + // Parent - Top Level Item (L3) + // Children(count) - Second Level Items (L3 fields) + if (isIndexL3Container(parent)) + { + // L3 cannot be "None" + Q_ASSERT(mpStream->proto.protoMask & PM_L3_PROTO_NONE); + + switch(mpStream->proto.etherType) + { + case ETH_TYP_IP: + return 12; // Ver, HdrLen, TOS, TotLen, Id, Flags, + // FragOfs, TTL, Proto, Cksum, SrcIp, DstIp + break; + case ETH_TYP_ARP: + return 0; // TODO(LOW) + break; + default: + qDebug("%s: Unsupported ethtype", __FUNCTION__); + return -1; + } + } + + // Parent - Top Level Item (L4) + // Children(count) - Second Level Items (L4 fields) + if (isIndexL4Container(parent)) + { + // L4 cannot be "None" + Q_ASSERT(mpStream->proto.protoMask & PM_L4_PROTO_NONE); + + switch(mpStream->proto.ipProto) + { + case IP_PROTO_TCP: + return 10; // SrcPort, DstPort, SeqNum, AckNum, HdrLen, + // Rsvd, Flags, Window, Cksum, UrgPtr, + break; + case IP_PROTO_UDP: + return 4; // SrcPort, DstPort, TotLen, Cksum + break; + case IP_PROTO_ICMP: + case IP_PROTO_IGMP: + return 0; // TODO(LOW) + break; + default: + qDebug("%s: Unsupported ethtype", __FUNCTION__); + return -1; + } + } + + // Parent - Second Level Item (L2 field) + // Children(count) - Third Level Items (L2 subfield) + if (isIndexL2Field(parent)) + { + return 0; // No subfields for any L2 field + } + + // Parent - Second Level Item (L3 field) + // Children(count) - Third Level Items (L3 subfield) + if (isIndexL3Field(parent)) + { + if (isIndexIpField(parent)) + return 0; // TODO (MED) + if (isIndexArpField(parent)) + return 0; // TODO (LOW) + + qDebug("%s: Unknown L3 Field", __FUNCTION__); + return 0; // catch all + } + + // Parent - Second Level Item (L4 field) + // Children(count) - Third Level Items (L4 subfield) + if (isIndexL4Field(parent)) + { + if (isIndexTcpField(parent)) + return 0; // TODO (MED) + if (isIndexUdpField(parent)) + return 0; // No subfields for any UDP fields + if (isIndexIcmpField(parent)) + return 0; // TODO (LOW) + if (isIndexIgmpField(parent)) + return 0; // TODO (LOW) + + qDebug("%s: Unknown L4 Field", __FUNCTION__); + return 0; // catch all + } + + //qDebug("%s: Catch all - need to investigate", __FUNCTION__); + return 0; // catch all +} + +int PacketModel::columnCount(const QModelIndex &parent) const +{ + return 1; +} + +QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) const +{ + QModelIndex index; + IndexId id, parentId; + uint vlanMask = mpStream->l2.eth.vlanMask; + + if (!hasIndex(row, col, parent)) + goto _exit; + + parentId.w = parent.internalId(); + + // Parent - Invisible Root + // Requested child - First/Top Level Item + if (parentId.ws.b2 == 0xFF) + { + Q_ASSERT(!parent.isValid()); + + if (mpStream->l2.eth.vlanMask & VM_UNTAGGED) + id.ws.b1 = row+2; // Only L2, L3, L4 + else if (VM_SINGLE_TAGGED(vlanMask)) + { + switch (row) + { + case 0: id.ws.b1 = 2; break; // L2 + case 1: id.ws.b1 = (vlanMask & VM_SVLAN_TAGGED)?0x88:0x81; break; + case 2: id.ws.b1 = 3; break; // L3 + case 3: id.ws.b1 = 4; break; // L4 + case 4: id.ws.b1 = 0; break; // Data + default: qWarning("%s: Unexpected row (%d)", __FUNCTION__, row); + } + } + else if (VM_DOUBLE_TAGGED(vlanMask)) + { + switch (row) + { + case 0: id.ws.b1 = 2; break; // L2 + case 1: id.ws.b1 = 0x88; break; // SVLAN + case 2: id.ws.b1 = 0x81; break; // CVLAN + case 3: id.ws.b1 = 3; break; // L3 + case 4: id.ws.b1 = 4; break; // L4 + case 5: id.ws.b1 = 0; break; // Data + default: qWarning("%s: Unexpected row (%d)", __FUNCTION__, row); + } + } + id.ws.b2 = 0xFF; + index = createIndex(row, col, id.w); + goto _exit; + } + + // Parent - First Level Item + // Requested child - Second Level Item + if (parentId.ws.b3 == 0xFF) + { + Q_ASSERT(parentId.ws.b1 != 0xFF); + Q_ASSERT(parentId.ws.b2 != 0xFF); + + id.ws.b1 = parentId.ws.b1; + id.ws.b2 = 0; // TODO(MED): Set Field Id for subfields + index = createIndex(row, col, id.w); + goto _exit; + } + + // Parent - Second Level Item (Field) + // Requested child - Third Level Item (Subfield) + // TODO(MED): Support subfields + // Till then we return an invalid index + +_exit: + return index; +} + +QModelIndex PacketModel::parent(const QModelIndex &index) const +{ + IndexId id, parentId; + + id.w = index.internalId(); + parentId = id; + + // 1st/Top Level Item - Protocol + // Requested Parent => Invisible Root + if (id.ws.b2 == 0xFF) + return QModelIndex(); + + // Second Level Item - Field + // Requested Parent => 1st Level Item (Protocol) + if (id.ws.b3 == 0xFF) + { + uint vlanMask = mpStream->l2.eth.vlanMask; + int row = -1; + + parentId.ws.b2 = 0xFF; + + if (vlanMask & VM_UNTAGGED) + { + row = parentId.ws.b1 - 2; + } + else if (VM_SINGLE_TAGGED(vlanMask)) + { + switch (parentId.ws.b1) + { + case 2: row = 0; break; // L2 + case 0x88: + case 0x81: row = 1; break; // SVlan/CVlan + case 3: row = 2; break; // L3 + case 4: row = 3; break; // L4 + case 0: row = 4; break; // Data + default: qWarning("%s: Unexpected b1 (%d)", __FUNCTION__, parentId.ws.b1); + } + } + else if (VM_DOUBLE_TAGGED(vlanMask)) + { + switch (parentId.ws.b1) + { + case 2: row = 0; break; // L2 + case 0x88: row = 1; break; // Svlan + case 0x81: row = 2; break; // CVlan + case 3: row = 3; break; // L3 + case 4: row = 4; break; // L4 + case 0: row = 5; break; // Data + default: qWarning("%s: Unexpected b1 (%d)", __FUNCTION__, parentId.ws.b1); + } + } + else + qWarning("%s: Unhandled leg", __FUNCTION__); + + return createIndex(row, 0, parentId.w); + } + + // Third Level Item - Subfield + // Requested Parent => 2nd Level Item (Field) + // TODO(Med) + qWarning("%s: Unexpected leg", __FUNCTION__); + return QModelIndex(); +} + +QVariant PacketModel::data(const QModelIndex &index, int role) const +{ + IndexId id; + + id.w = index.internalId(); + + if (id.ws.b2 == 0xFF) + return QString("Protocol Header"); + else + return QString("Field: Value"); +} + + +/* +** --------------- Private Stuff ----------------- +*/ +typedef union +{ + quint32 w; + struct + { + quint8 b1; + quint8 b2; + quint8 b3; + quint8 b4; + } ws; +} IndexId; + +bool PacketModel::isIndexContainer(const QModelIndex& index, int level) const +{ + IndexId id; + + id.w = index.internalId(); + if ((id.ws.b1 == level) && (id.ws.b2 == 0xFF)) + return true; + else + return false; +} + +bool PacketModel::isIndexL2Container(const QModelIndex& index) const +{ + return isIndexContainer(index, 2); +} + +bool PacketModel::isIndexSvlanContainer(const QModelIndex& index) const +{ + return isIndexContainer(index, 0x88); +} + +bool PacketModel::isIndexCvlanContainer(const QModelIndex& index) const +{ + return isIndexContainer(index, 0x81); +} + +bool PacketModel::isIndexL3Container(const QModelIndex& index) const +{ + return isIndexContainer(index, 3); +} + +bool PacketModel::isIndexL4Container(const QModelIndex& index) const +{ + return isIndexContainer(index, 4); +} + +bool PacketModel::isIndexField(const QModelIndex& index, int level) const +{ + IndexId id; + + id.w = index.internalId(); + if ((id.ws.b1 == level) && (id.ws.b2 != 0xFF) && (id.ws.b3 == 0xFF)) + return true; + else + return false; +} + +bool PacketModel::isIndexL2Field(const QModelIndex& index) const +{ + return isIndexField(index, 2); +} + +bool PacketModel::isIndexL3Field(const QModelIndex& index) const +{ + return isIndexField(index, 3); +} + +bool PacketModel::isIndexL4Field(const QModelIndex& index) const +{ + return isIndexField(index, 4); +} + +bool PacketModel::isIndexIpField(const QModelIndex& index) const +{ + IndexId id; + + id.w = index.internalId(); + if ((id.ws.b1 == 3) && (id.ws.b2 == 1) && (id.ws.b3 == 0xFF)) + return true; + else + return false; +} + +bool PacketModel::isIndexArpField(const QModelIndex& index) const +{ + IndexId id; + + id.w = index.internalId(); + if ((id.ws.b1 == 3) && (id.ws.b2 == 2) && (id.ws.b3 == 0xFF)) + return true; + else + return false; +} + +bool PacketModel::isIndexL4ProtoField(const QModelIndex& index, int proto) const +{ + IndexId id; + + id.w = index.internalId(); + if ((id.ws.b1 == 4) && (id.ws.b2 == proto) && (id.ws.b3 == 0xFF)) + return true; + else + return false; +} + +bool PacketModel::isIndexTcpField(const QModelIndex& index) const +{ + return isIndexL4ProtoField(index, IP_PROTO_TCP); +} + +bool PacketModel::isIndexUdpField(const QModelIndex& index) const +{ + return isIndexL4ProtoField(index, IP_PROTO_UDP); +} + +bool PacketModel::isIndexIcmpField(const QModelIndex& index) const +{ + return isIndexL4ProtoField(index, IP_PROTO_ICMP); +} + +bool PacketModel::isIndexIgmpField(const QModelIndex& index) const +{ + return isIndexL4ProtoField(index, IP_PROTO_IGMP); +} diff --git a/client/packetmodel.h b/client/packetmodel.h new file mode 100644 index 0000000..1ecd0d2 --- /dev/null +++ b/client/packetmodel.h @@ -0,0 +1,52 @@ +#ifndef _PACKET_MODEL_H +#define _PACKET_MODEL_H + +#include +#include "stream.h" + +class PacketModel: public QAbstractItemModel +{ + +public: + PacketModel(Stream *pStream, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; + QModelIndex parent(const QModelIndex &index) const; + +private: + Stream *mpStream; + typedef union _IndexId + { + quint32 w; + struct + { + quint8 b1; // 1st Level + quint8 b2; // 2nd Level + quint8 b3; // 3rd Level + quint8 b4; // Reserved + } ws; + } IndexId; + + bool PacketModel::isIndexContainer(const QModelIndex& index, int level) const; + bool PacketModel::isIndexL2Container(const QModelIndex& index) const; + bool PacketModel::isIndexSvlanContainer(const QModelIndex& index) const; + bool PacketModel::isIndexCvlanContainer(const QModelIndex& index) const; + bool PacketModel::isIndexL3Container(const QModelIndex& index) const; + bool PacketModel::isIndexL4Container(const QModelIndex& index) const; + bool PacketModel::isIndexField(const QModelIndex& index, int level) const; + bool PacketModel::isIndexL2Field(const QModelIndex& index) const; + bool PacketModel::isIndexL3Field(const QModelIndex& index) const; + bool PacketModel::isIndexL4Field(const QModelIndex& index) const; + bool PacketModel::isIndexIpField(const QModelIndex& index) const; + bool PacketModel::isIndexArpField(const QModelIndex& index) const; + bool PacketModel::isIndexL4ProtoField(const QModelIndex& index, int proto) const; + bool PacketModel::isIndexTcpField(const QModelIndex& index) const; + bool PacketModel::isIndexUdpField(const QModelIndex& index) const; + bool PacketModel::isIndexIcmpField(const QModelIndex& index) const; + bool PacketModel::isIndexIgmpField(const QModelIndex& index) const; +}; +#endif + diff --git a/client/port.cpp b/client/port.cpp index 755e52e..f7122d3 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -18,7 +18,9 @@ void Port::insertDummyStreams() { mStreams.append(*(new Stream)); mStreams[0].setName(QString("%1:%2:0").arg(portGroupId()).arg(id())); +#if 1 mStreams.append(*(new Stream)); mStreams[1].setName(QString("%1:%2:1").arg(portGroupId()).arg(id())); +#endif } diff --git a/client/portgroup.cpp b/client/portgroup.cpp index b7f8eb3..e8a7dfe 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -100,9 +100,9 @@ void PortGroup::ProcessCapabilityInfo(const char *msg, qint32 size) goto _next; } - p = new Port(NTOHL(cap->port), mPortGroupId); - p->setName(cap->name); - p->setDescription(cap->desc); + p = new Port(NTOHL(cap->portId), mPortGroupId); + p->setName(cap->portName); + p->setDescription(cap->portDesc); p->insertDummyStreams(); // FIXME: only for testing qDebug("before port append\n"); mPorts.append(*p); @@ -137,7 +137,7 @@ void PortGroup::when_connected() pkt.ver = 1; pkt.resv1 = 0; pkt.resv2 = 0; - pkt.msgType = HTONS(e_MT_CapabilityReq); + pkt.msgType = HTONS(e_MT_GetCapability); pkt.msgLen = HTONS(8); mpSocket->write((char*) &pkt, sizeof(pkt)); diff --git a/client/portstatsfilter.ui b/client/portstatsfilter.ui index 3dae66d..8220436 100644 --- a/client/portstatsfilter.ui +++ b/client/portstatsfilter.ui @@ -1,6 +1,6 @@ - Dialog - + PortStatsFilterDialog + 0 @@ -16,7 +16,11 @@ - + + + QAbstractItemView::ExtendedSelection + + @@ -34,14 +38,14 @@ - + > - + < @@ -63,7 +67,11 @@ - + + + QAbstractItemView::ExtendedSelection + + @@ -80,10 +88,10 @@ - lvAllPorts - tbFilterIn - tbFilterOut - lvFilteredPorts + lvUnselected + tbSelectIn + tbSelectOut + lvSelected buttonBox @@ -91,7 +99,7 @@ buttonBox accepted() - Dialog + PortStatsFilterDialog accept() @@ -107,7 +115,7 @@ buttonBox rejected() - Dialog + PortStatsFilterDialog reject() diff --git a/client/portstatsfilterdialog.cpp b/client/portstatsfilterdialog.cpp index 8845dd2..af95303 100644 --- a/client/portstatsfilterdialog.cpp +++ b/client/portstatsfilterdialog.cpp @@ -1,9 +1,84 @@ #include "portstatsfilterdialog.h" -PortStatsFilterDialog::PortStatsFilterDialog(AbstractItemModel *allPortsModel, - QWidget *parent) +PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent) { setupUi(this); - lvAllPorts->setModel(allPortsModel); + // TODO(MED): Use ExtendedSelection and use "selected" instead of + // "current" for selecting in/out + // TODO(MED): Ensure items are READ-ONLY not editable + // TODO(MED): Enable "double-click" on items + lvUnselected->setSelectionMode(QAbstractItemView::SingleSelection); + lvSelected->setSelectionMode(QAbstractItemView::SingleSelection); + + mUnselected.setSortRole(PositionRole); + + lvUnselected->setModel(&mUnselected); + lvSelected->setModel(&mSelected); } + +QList PortStatsFilterDialog::getItemList(bool* ok, + QAbstractItemModel *model, Qt::Orientation orientation, + QList initial) +{ + QList ret; + + uint count = (orientation == Qt::Vertical) ? + model->rowCount() : model->columnCount(); + + *ok = false; + + mUnselected.clear(); + mSelected.clear(); + + for (uint i = 0; i < count; i++) + { + QStandardItem *item; + + item = new QStandardItem(model->headerData(i, orientation).toString()); + item->setData(i, PositionRole); + + if (initial.contains(i)) + mSelected.appendRow(item); + else + mUnselected.appendRow(item); + } + + // No need to sort right now 'coz we have inserted items in order + + if (exec() == QDialog::Accepted) + { + uint count = mSelected.rowCount(); + for (uint i = 0; i < count; i++) + { + QModelIndex index = mSelected.index(i, 0, QModelIndex()); + QStandardItem *item = mSelected.itemFromIndex(index); + ret.append(item->data(PositionRole).toInt()); + } + *ok = true; + } + + return ret; +} + +void PortStatsFilterDialog::on_tbSelectIn_clicked() +{ + QStandardItem *item; + + item = mUnselected.takeItem(lvUnselected->currentIndex().row()); + if (mUnselected.removeRow(lvUnselected->currentIndex().row())) + mSelected.appendRow(item); +} + +void PortStatsFilterDialog::on_tbSelectOut_clicked() +{ + QStandardItem *item; + + item = mSelected.takeItem(lvSelected->currentIndex().row()); + if (mSelected.removeRow(lvSelected->currentIndex().row())) + { + mUnselected.appendRow(item); + mUnselected.sort(0); + } +} + diff --git a/client/portstatsfilterdialog.h b/client/portstatsfilterdialog.h index c180f34..e845e0d 100644 --- a/client/portstatsfilterdialog.h +++ b/client/portstatsfilterdialog.h @@ -3,7 +3,8 @@ #include #include -#include "ui_portstatsfilterdialog.h" +#include +#include "ui_portstatsfilter.h" #include "portgrouplist.h" class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog @@ -11,8 +12,21 @@ class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog Q_OBJECT public: - PortStatsFilterDialog(AbstractItemModel *allPortsModel, - QWidget *parent = 0); + PortStatsFilterDialog(QWidget *parent = 0); + QList getItemList(bool* ok, QAbstractItemModel *model, + Qt::Orientation orientation = Qt::Vertical, + QList initial = QList()); + +private: + enum ItemRole { + PositionRole = Qt::UserRole + 1 + }; + QStandardItemModel mUnselected; + QStandardItemModel mSelected; + +private slots: + void on_tbSelectIn_clicked(); + void on_tbSelectOut_clicked(); }; #endif diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index 594209e..1339ebb 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -1,15 +1,37 @@ + #include "portstatswindow.h" #include "portstatsmodel.h" +#include "portstatsfilterdialog.h" + +#include "QHeaderView" //PortStatsWindow::PortStatsWindow(QWidget *parent) : QDialog (parent) PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent) { setupUi(this); - tvPortStats->setModel(pgl->getPortStatsModel()); - + model = pgl->getPortStatsModel(); + tvPortStats->setModel(model); + tvPortStats->horizontalHeader()->setMovable(true); } PortStatsWindow::~PortStatsWindow() { } + +void PortStatsWindow::on_tbFilter_clicked() +{ + bool ok; + QList currentColumns, newColumns; + PortStatsFilterDialog dialog; + + for(int i = 0; i < model->columnCount(); i++) + if (!tvPortStats->isColumnHidden(i)) + currentColumns.append(i); + + newColumns = dialog.getItemList(&ok, model, Qt::Horizontal, currentColumns); + + if(ok) + for(int i = 0; i < model->columnCount(); i++) + tvPortStats->setColumnHidden(i, !newColumns.contains(i)); +} diff --git a/client/portstatswindow.h b/client/portstatswindow.h index 2cec09a..e5a1a97 100644 --- a/client/portstatswindow.h +++ b/client/portstatswindow.h @@ -15,6 +15,9 @@ public: ~PortStatsWindow(); private: QAbstractItemModel *model; + +private slots: + void on_tbFilter_clicked(); }; #endif diff --git a/client/portstatswindow.ui b/client/portstatswindow.ui index f3dff15..4396ff6 100644 --- a/client/portstatswindow.ui +++ b/client/portstatswindow.ui @@ -1,133 +1,192 @@ - - PortStatsWindow - - - - 0 - 0 - 502 - 415 - - - - Form - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - Start Transmit - - - Stop Transmit - - - Start Transmit - - - :/icons/control_play.png - - - - - - - Stop Transmit - - - Stop Transmit - - - Stop Trasmit - - - :/icons/control_stop.png - - - - - - - Clear - - - - - - - Clear All - - - - - - - Start Capture - - - :/icons/sound_none.png - - - - - - - Stop Capture - - - :/icons/sound_mute.png - - - - - - - View Capture - - - :/icons/magnifier.png - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - + + PortStatsWindow + + + + 0 + 0 + 502 + 415 + + + + Form + + + + + + Clear All + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Clear All + + + Starts transmit on selected port(s) + + + Start Transmit + + + :/icons/control_play.png + + + + + + + Clear All + + + Stops transmit on selected port(s) + + + Stop Trasmit + + + :/icons/control_stop.png + + + + + + + Clear All + + + Clears statistics of the selected port(s) + + + Clear + + + + + + + Clear All + + + Clears statistics of all ports + + + Clear All + + + + + + + Clear All + + + Captures packets on the selected port(s) + + + Start Capture + + + :/icons/sound_none.png + + + + + + + Clear All + + + End capture on selecteed port(s) + + + Stop Capture + + + :/icons/sound_mute.png + + + + + + + Clear All + + + View captured packets on selected port(s) + + + View Capture + + + :/icons/magnifier.png + + + + + + + Clear All + + + Qt::Vertical + + + + + + + Clear All + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Clear All + + + Select which ports to view + + + Filter + + + :/icons/portstats_filter.png + + + + + + + + + + Clear All + + + + + + + + + + diff --git a/client/stream.h b/client/stream.h index c1f9d5f..4469065 100644 --- a/client/stream.h +++ b/client/stream.h @@ -6,11 +6,13 @@ class StreamConfigDialog; class StreamModel; +class PacketModel; class Stream { friend class StreamConfigDialog; friend class StreamModel; + friend class PacketModel; enum FrameType { e_ft_none, @@ -114,6 +116,13 @@ class Stream { #define VM_SVLAN_TAGGED 0x0100 #define VM_SVLAN_TPID_OVERRIDE 0x0200 +#define VM_SINGLE_TAGGED(mask) \ + ((mask & VM_CVLAN_TAGGED ) | (mask & VM_SVLAN_TAGGED)) +#define VM_DOUBLE_TAGGED(mask) \ + (mask & (VM_CVLAN_TAGGED | VM_SVLAN_TAGGED)) + + + quint16 ctpid; quint16 cvlanPrio : 3; quint16 cvlanCfi : 1; diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index f29592f..f51c49e 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -2,6 +2,9 @@ #include "streamconfigdialog.h" #include "stream.h" +// TODO(LOW): Remove +#include "modeltest.h" + StreamConfigDialog::StreamConfigDialog(QList *streamList, uint streamIndex, QWidget *parent) : QDialog (parent) { @@ -13,6 +16,12 @@ StreamConfigDialog::StreamConfigDialog(QList *streamList, mCurrentStreamIndex = streamIndex; LoadCurrentStream(); + mpPacketModel = new PacketModel(&((*mpStreamList)[mCurrentStreamIndex]), + this); + tvPacketTree->setModel(mpPacketModel); + mpPacketModelTester = new ModelTest(mpPacketModel); + tvPacketTree->header()->hide(); + qDebug("stream %p %d/%d loaded", mpStreamList, mCurrentStreamIndex, mpStreamList->size()); @@ -66,6 +75,8 @@ void StreamConfigDialog::setupUiExtra() StreamConfigDialog::~StreamConfigDialog() { + delete mpPacketModelTester; + delete mpPacketModel; } void StreamConfigDialog::on_cmbDstMacMode_currentIndexChanged(QString mode) diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 95e7380..6ccf074 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -3,7 +3,9 @@ #include #include "ui_streamconfigdialog.h" -#include +#include "stream.h" +#include "packetmodel.h" +#include "modeltest.h" #define MAX_MAC_ITER_COUNT 256 #define MIN_PKT_LEN 64 @@ -26,6 +28,8 @@ public: private: QList *mpStreamList; uint mCurrentStreamIndex; + PacketModel *mpPacketModel; + ModelTest *mpPacketModelTester; void setupUiExtra(); void LoadCurrentStream(); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 85f29e3..7e7efe1 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -33,9 +33,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 0 + 2 - + Packet Config @@ -2023,66 +2023,18 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff Packet View - + Qt::Vertical - - - true - - - - New Column - - - - - Ethernet - - - - DstMac: 00:00:00:00:00:00 - - - - - SrcMac: 00:00:00:00:00:00 - - - - - EtherType: IP (0800) - - - - - - IP - - - - Version: 4 - - - - - Header Length: 20 - - - - - - - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;">0004 00 00 00 00 00 00</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> + + + QAbstractItemView::SelectItems + @@ -2145,6 +2097,12 @@ p, li { white-space: pre-wrap; } QLineEdit
hexlineedit.h
+ + DumpView + QWidget +
dumpview.h
+ 1 +
twTopLevel @@ -2347,12 +2305,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 79 - 247 + 101 + 276 - 99 - 247 + 101 + 276
@@ -2363,12 +2321,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 79 - 247 + 101 + 276 - 99 - 247 + 101 + 276
@@ -2443,12 +2401,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 79 - 247 + 101 + 276 - 99 - 247 + 101 + 276 @@ -2459,44 +2417,44 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 79 - 247 + 101 + 276 + + + 101 + 276 + + + + + rbFtNone + toggled(bool) + lblDsap + setHidden(bool) + + + 57 + 218 + + + 58 + 218 + + + + + rbFtNone + toggled(bool) + leDsap + setHidden(bool) + + + 57 + 218 99 - 247 - - - - - rbFtNone - toggled(bool) - lblDsap - setHidden(bool) - - - 43 - 186 - - - 137 - 185 - - - - - rbFtNone - toggled(bool) - leDsap - setHidden(bool) - - - 43 - 186 - - - 178 - 185 + 218 @@ -2507,12 +2465,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 186 + 57 + 218 - 137 - 211 + 58 + 218 @@ -2523,12 +2481,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 186 + 57 + 218 - 178 - 211 + 99 + 218 @@ -2539,8 +2497,8 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 186 + 57 + 218 137 @@ -2555,12 +2513,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 186 + 57 + 218 - 178 - 237 + 99 + 218 @@ -2571,12 +2529,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 186 + 57 + 218 - 137 - 263 + 58 + 218 @@ -2587,12 +2545,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 186 + 57 + 218 - 178 - 263 + 99 + 218 @@ -2603,12 +2561,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 186 + 57 + 218 - 137 - 289 + 58 + 218 @@ -2619,12 +2577,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 186 + 57 + 218 - 178 - 289 + 99 + 218 @@ -2635,12 +2593,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 211 + 57 + 218 - 137 - 185 + 58 + 218 @@ -2651,12 +2609,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 211 + 57 + 218 - 178 - 185 + 99 + 218 @@ -2667,12 +2625,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 211 + 57 + 218 - 137 - 211 + 58 + 218 @@ -2683,12 +2641,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 211 + 57 + 218 - 178 - 211 + 99 + 218 @@ -2699,8 +2657,8 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 137 @@ -2715,12 +2673,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 178 - 237 + 99 + 218 @@ -2731,8 +2689,8 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 211 + 57 + 218 137 @@ -2747,12 +2705,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 211 + 57 + 218 - 178 - 237 + 99 + 218 @@ -2763,12 +2721,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 211 + 57 + 218 - 137 - 263 + 58 + 218 @@ -2779,12 +2737,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 211 + 57 + 218 - 178 - 263 + 99 + 218 @@ -2795,12 +2753,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 137 - 185 + 58 + 218 @@ -2811,12 +2769,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 178 - 185 + 99 + 218 @@ -2827,12 +2785,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 137 - 211 + 58 + 218 @@ -2843,12 +2801,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 178 - 211 + 99 + 218 @@ -2859,8 +2817,8 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 137 @@ -2875,12 +2833,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 178 - 237 + 99 + 218 @@ -2891,12 +2849,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 137 - 263 + 58 + 218 @@ -2907,12 +2865,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 178 - 263 + 99 + 218 @@ -2923,12 +2881,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 137 - 289 + 58 + 218 @@ -2939,12 +2897,12 @@ p, li { white-space: pre-wrap; } setHidden(bool) - 43 - 236 + 57 + 218 - 178 - 289 + 99 + 218 @@ -2987,12 +2945,12 @@ p, li { white-space: pre-wrap; } setDisabled(bool) - 43 - 286 + 57 + 218 - 178 - 185 + 99 + 218 @@ -3003,12 +2961,12 @@ p, li { white-space: pre-wrap; } setDisabled(bool) - 43 - 286 + 57 + 218 - 178 - 211 + 99 + 218 @@ -3019,12 +2977,12 @@ p, li { white-space: pre-wrap; } setDisabled(bool) - 43 - 286 + 57 + 218 - 178 - 237 + 99 + 218 @@ -3035,12 +2993,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 355 - 196 + 570 + 218 - 300 - 291 + 570 + 302 @@ -3051,12 +3009,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 355 - 196 + 570 + 218 - 372 - 291 + 570 + 302 @@ -3067,12 +3025,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 355 - 196 + 570 + 218 - 443 - 291 + 570 + 302 @@ -3083,12 +3041,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 355 - 196 + 570 + 218 - 372 - 267 + 570 + 302 @@ -3099,12 +3057,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 355 - 196 + 570 + 218 - 443 - 267 + 570 + 302 @@ -3115,12 +3073,12 @@ p, li { white-space: pre-wrap; } click() - 300 - 196 + 570 + 218 - 300 - 267 + 570 + 302 @@ -3131,12 +3089,12 @@ p, li { white-space: pre-wrap; } click() - 407 - 196 + 570 + 218 - 300 - 267 + 570 + 302 @@ -3147,12 +3105,12 @@ p, li { white-space: pre-wrap; } click() - 457 - 196 + 570 + 218 - 300 - 267 + 570 + 302 @@ -3163,12 +3121,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 334 - 147 + 224 + 207 - 411 - 177 + 224 + 209 @@ -3179,12 +3137,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 38 - 73 + 125 + 207 - 180 - 284 + 191 + 236 @@ -3195,12 +3153,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 46 - 98 + 125 + 207 - 162 - 313 + 173 + 236 @@ -3211,12 +3169,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 73 - 108 + 125 + 207 - 225 - 184 + 224 + 216 diff --git a/common/protocol.h b/common/protocol.h index f7c61dc..01f35f6 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -31,23 +31,139 @@ typedef struct { } tCommHdr; typedef enum { - e_MT_CapabilityReq=1, - e_MT_CapabilityInfo + e_MT_GetCapability=1, // C-->S + e_MT_CapabilityInfo, // C<--S + + e_MT_ChangePortConfig, // C-->S + e_MT_GetPortConfig, // C-->S + e_MT_PortInfo, // C<--S + + e_MT_StartTx, // C-->S + e_MT_StopTx, // C-->S + e_MT_StartCapture, // C-->S + e_MT_StopCapture, // C-->S + e_MT_GetCaptureBuffer, // C-->S + e_MT_CaptureBufferInfo, // C-->S + + e_MT_GetStats, // C-->S + e_MT_StatsInfo, // C<--S + e_MT_ClearStats, // C-->S + } eMsgType; typedef enum { - e_TT_PortCapability + e_TT_PortCapability=0x0000, + + e_TT_StreamOper = 0x0100, + e_TT_StreamName, + e_TT_StreamStatus, + e_TT_StreamFrameLength, + e_TT_StreamDataPattern, + e_TT_StreamHeaderData, } eTlvType; typedef struct { UINT16 tlvType; UINT16 tlvLen; - UINT32 port; - UINT32 speed; +} tTlv; + +typedef struct { + UINT16 tlvType; + UINT16 tlvLen; + UINT32 portId; + UINT32 portSpeed; #define TLV_MAX_PORT_NAME 64 #define TLV_MAX_PORT_DESC 64 - char name[TLV_MAX_PORT_NAME]; - char desc[TLV_MAX_PORT_DESC]; + char portName[TLV_MAX_PORT_NAME]; + char portDesc[TLV_MAX_PORT_DESC]; } tTlvPortCapability; +typedef struct { + UINT16 tlvType; + UINT16 tlvLen; + UINT32 portId; + UINT32 streamId; +} tTlvStream; + +typedef struct { + UINT16 tlvType; + UINT16 tlvLen; + UINT32 portId; + UINT32 streamId; + UINT16 rsvd; + UINT16 streamOper; +#define TLV_STREAM_OPER_INSERT_HEAD 0x0001 +#define TLV_STREAM_OPER_INSERT_TAIL 0x0002 +#define TLV_STREAM_OPER_INSERT_BEFORE 0x0003 +#define TLV_STREAM_OPER_DELETE 0x0010 + UINT32 StreamId; +} tTlvStreamOper; + +typedef struct { + UINT16 tlvType; + UINT16 tlvLen; + UINT32 portId; + UINT32 streamId; + char streamName[0]; +} tTlvStreamName; + +typedef struct { + UINT16 tlvType; + UINT16 tlvLen; + UINT32 portId; + UINT32 streamId; + UINT32 streamStatus; +#define TLV_STREAM_STATUS_DISABLED 0 +#define TLV_STREAM_STATUS_ENABLED 1 +} tTlvStreamStatus; + +typedef struct { + UINT16 tlvType; + UINT16 tlvLen; + UINT32 portId; + UINT32 streamId; + UINT16 frameLenMode; +#define TLV_STREAM_FRAME_LEN_MODE_FIXED 0x0000 +#define TLV_STREAM_FRAME_LEN_MODE_RANDOM 0x0001 +#define TLV_STREAM_FRAME_LEN_MODE_INCREMENT 0x0002 +#define TLV_STREAM_FRAME_LEN_MODE_DECREMENT 0x0003 + UINT16 frameLen; + UINT16 frameLenMin; + UINT16 frameLenMax; +} tTlvStreamFrameLength; + +typedef struct { + UINT16 tlvType; + UINT16 tlvLen; + UINT32 portId; + UINT32 streamId; + UINT16 dataPatternMode; +#define TLV_STREAM_DATA_PATTERN_MODE_FIXED 0x0000 +#define TLV_STREAM_DATA_PATTERN_MODE_RANDOM 0x0001 +#define TLV_STREAM_DATA_PATTERN_MODE_INCREMENT 0x0002 +#define TLV_STREAM_DATA_PATTERN_MODE_DECREMENT 0x0003 + UINT16 rsvd; + UINT32 dataPattern; +} tTlvStreamDataPattern; + +typedef struct { + UINT16 tlvType; + UINT16 tlvLen; + UINT32 portId; + UINT32 streamId; + UINT16 rsvd; + UINT16 headerLen; + UINT8 header[0]; +} tTlvStreamHeaderData; + +typedef union { + tTlvStream tlv; + tTlvStreamOper oper; + tTlvStreamName name; + tTlvStreamStatus status; + tTlvStreamFrameLength frameLen; + tTlvStreamDataPattern dataPattern; + tTlvStreamHeaderData headerData; +} uTlvStream; + #endif diff --git a/server/rxtx.cpp b/server/rxtx.cpp index 7c0be69..0a1bcdf 100644 --- a/server/rxtx.cpp +++ b/server/rxtx.cpp @@ -1,6 +1,8 @@ +#include "qtglobal" // FIXME: needed only for qdebug #include "rxtx.h" #include "../common/protocol.h" -#include "qtglobal" // FIXME: needed only for qdebug + + //#define LOG(...) drone->ui.teLOG->append(QString().sprintf( __VA_ARGS__)) //#define LOG(...) drone->LOG(QString().sprintf( __VA_ARGS__)) @@ -36,6 +38,8 @@ RxTx::RxTx(AbstractHost *host) { portInfo[i].portId = i; portInfo[i].dev = d; + portInfo[i].streamHead = NULL; + portInfo[i].streamTail = NULL; #if 1 LOG("%d. %s", i, d->name); if (d->description) @@ -67,13 +71,17 @@ RxTx::LOG(char* fmt, ...) RxTx::~RxTx() { + unsigned int i; + + for (i = 0; i < numPorts; i++) + DeleteAllStreams(i); pcap_freealldevs(alldevs); } void RxTx::ProcessMsg(const char* msg, int len) { tCommHdr *hdr; - // TODO: For now, assuming we'll get a complete msg + // TODO: For now assuming we'll get a complete msg // but need to fix this as this is a TCP stream hdr = (tCommHdr*) msg; @@ -87,9 +95,15 @@ void RxTx::ProcessMsg(const char* msg, int len) qDebug("msgType - %x: %x\n", hdr->msgType, NTOHS(hdr->msgType)); switch (NTOHS(hdr->msgType)) { - case e_MT_CapabilityReq: + case e_MT_GetCapability: SendCapabilityInfo(); break; + case e_MT_ChangePortConfig: + ProcessPortConfig(msg+sizeof(tCommHdr), len - sizeof(tCommHdr)); + break; + case e_MT_GetPortConfig: + SendPortInfo(); + break; default: LOG("Rcvd msg with unrecognized msgType %d\n", NTOHS(hdr->msgType)); @@ -114,20 +128,20 @@ void RxTx::SendCapabilityInfo(void) // TLV: Port Capability ((tTlvPortCapability*)(p))->tlvType = HTONS(e_TT_PortCapability); ((tTlvPortCapability*)(p))->tlvLen = HTONS(sizeof(tTlvPortCapability)); - ((tTlvPortCapability*)(p))->port = HTONL(portInfo[i].portId); - ((tTlvPortCapability*)(p))->speed = 0; // TODO + ((tTlvPortCapability*)(p))->portId = HTONL(portInfo[i].portId); + ((tTlvPortCapability*)(p))->portSpeed = 0; // TODO #if 0 strncpy(((tTlvPortCapability*)(p))->name, portInfo[i].dev->name, TLV_MAX_PORT_NAME); ((tTlvPortCapability*)(p))->name[TLV_MAX_PORT_NAME-1] = 0; #else - strcpy(((tTlvPortCapability*)(p))->name, "eth"); + strcpy(((tTlvPortCapability*)(p))->portName, "eth"); //strcat(((tTlvPortCapability*)(p))->name, itoa(portInfo[i].portId, NULL, 10)); - itoa(portInfo[i].portId, &(((tTlvPortCapability*)(p))->name[3]), 10); + itoa(portInfo[i].portId, &(((tTlvPortCapability*)(p))->portName[3]), 10); #endif - strncpy(((tTlvPortCapability*)(p))->desc, + strncpy(((tTlvPortCapability*)(p))->portDesc, portInfo[i].dev->description, TLV_MAX_PORT_DESC); - ((tTlvPortCapability*)(p))->desc[TLV_MAX_PORT_DESC -1] = 0; + ((tTlvPortCapability*)(p))->portDesc[TLV_MAX_PORT_DESC -1] = 0; p += sizeof(tTlvPortCapability); } msgLen = (p - msg); @@ -145,3 +159,350 @@ void RxTx::SendCapabilityInfo(void) host->Log(logStr); host->SendMsg(pktBuff, msgLen); } + +void RxTx::ProcessPortConfig(const char* msg, int len) +{ + // ASSUMPTION: msg points to start of first TLV + UINT8 *p = (UINT8*) msg; + uTlvStream u; + Stream *s; + + // Extract and process each TLV + while (len) + { + if (len < 12) + { + LOG("Length (%d) Error - not enough to fit a TLV", len); + goto _exit; + } + + u.tlv.tlvType = NTOHS(GET16(p)); + u.tlv.tlvLen = NTOHS(GET16(p+2)); + u.tlv.portId = NTOHL(GET32(p+4)); + u.tlv.streamId = NTOHL(GET32(p+8)); + + p += 12; + len -= 12; + + // Locate the correct node for processing + if (u.tlv.portId >= numPorts) + goto _next_tlv; + + s = GetStream(u.tlv.portId, u.tlv.streamId); + if ((s == NULL) && (u.tlv.tlvType!= e_TT_StreamOper)) + { + LOG("Unrecognized stream Id %d\n", u.tlv.streamId); + goto _next_tlv; + } + + switch(u.tlv.tlvType) + { + case e_TT_StreamOper: + u.oper.streamOper = NTOHS(GET16(p+2)); + switch (u.oper.streamOper) + { + case TLV_STREAM_OPER_DELETE: + if (!DeleteStream(u.tlv.portId, u.tlv.streamId)) + { + LOG("No Stream with id %d currently in list\n", + u.tlv.streamId); + goto _next_tlv; + } + break; + case TLV_STREAM_OPER_INSERT_HEAD: + s = new Stream; + s->id = u.tlv.streamId; + + InsertStreamAtHead(u.tlv.portId, s); + break; + case TLV_STREAM_OPER_INSERT_TAIL: + s = new Stream; + s->id = u.tlv.streamId; + + InsertStreamAtTail(u.tlv.portId, s); + break; + case TLV_STREAM_OPER_INSERT_BEFORE: + { + UINT32 nextStreamId; + + s = new Stream; + s->id = u.tlv.streamId; + + nextStreamId = NTOHS(GET32(p+4)); + + if (!InsertStreamBefore(u.tlv.portId, s, nextStreamId)) + { + LOG("List Empty or No stream with id %d " + "currently in list\n", nextStreamId); + goto _next_tlv; + } + break; + } + default: + LOG("Unrecognized Stream Oper %d\n", + u.oper.streamOper); + goto _next_tlv; + } + break; + case e_TT_StreamName: + strncpy(s->name, (char*) p, MAX_STREAM_NAME_SIZE); + break; + + case e_TT_StreamStatus: + u.status.streamStatus = NTOHL(GET32(p)); + if (u.status.streamStatus == TLV_STREAM_STATUS_DISABLED) + s->flags |= STREAM_FLAG_VALUE_STATUS_DISABLED; // FIXME + else if (u.status.streamStatus == TLV_STREAM_STATUS_ENABLED) + s->flags |= STREAM_FLAG_VALUE_STATUS_ENABLED; // FIXME + else + goto _next_tlv; + break; + + case e_TT_StreamFrameLength: + u.frameLen.frameLenMode = NTOHS(GET16(p)); + u.frameLen.frameLen = NTOHS(GET16(p+2)); + u.frameLen.frameLenMin = NTOHS(GET16(p+4)); + u.frameLen.frameLenMax = NTOHS(GET16(p+6)); + + s->pktLen = u.frameLen.frameLen; + + // FIXME: other frameLen params + break; + + case e_TT_StreamDataPattern: + u.dataPattern.dataPatternMode = NTOHS(GET16(p)); + u.dataPattern.dataPattern = NTOHS(GET32(p+4)); + + s->dataPattern = u.dataPattern.dataPattern; + + // FIXME: other dataPattern params + break; + + case e_TT_StreamHeaderData: + u.headerData.headerLen = NTOHS(GET16(p+2)); + + s->hdrLen = u.headerData.headerLen; + memcpy(s->pktHdr, p+4, u.headerData.headerLen); + break; + + default: + LOG("Unrecognizeed/Unexpected TLV %d\n", u.tlv.tlvType); + } + +_next_tlv: + p += u.tlv.tlvLen; + len -= u.tlv.tlvLen; + } + +_exit: + return; +} + +void RxTx::SendPortInfo(unsigned int port) +{ + // Assumption: port is valid + assert(port < numPorts); + +} + +/* +** --------------------- STREAM LIST OPERATIONS ------------------------- +*/ + +void RxTx::InsertStreamAtHead(unsigned int port, Stream *s) +{ + if (portInfo[port].streamHead == NULL) + { + // list empty - first entry being added + s->next = NULL; + portInfo[port].streamHead = portInfo[port].streamTail = s; + } + else + { + // at least one entry in list, so tail does not change + s->next = portInfo[port].streamHead; + portInfo[port].streamHead = s; + } +} + +void RxTx::InsertStreamAtTail(unsigned int port, Stream *s) +{ + s->next = NULL; + if (portInfo[port].streamHead == NULL) + { + // list empty - first entry being added + portInfo[port].streamHead = portInfo[port].streamTail = s; + } + else + { + // at least one entry in list, so head does not change + portInfo[port].streamTail->next = s; + portInfo[port].streamTail = s; + } +} + +bool RxTx::InsertStreamBefore(unsigned int port, Stream *s, + unsigned int nextStreamId) +{ + Stream *q, *r; + + // For an "Insert Before", list cannot be empty + if (portInfo[port].streamHead == NULL) + { + LOG("Cannot 'insert before' in an empty list"); + return false; + } + + // Traverse with 'r' and keep track of previous with 'q' + q = NULL; + r = portInfo[port].streamHead; + while (r != NULL) + { + if (r->id == nextStreamId) + { + if (r == portInfo[port].streamHead) + { + // Insert at Head + s->next = portInfo[port].streamHead; + portInfo[port].streamHead = s; + } + else if (r == portInfo[port].streamTail) + { + // Insert one before Tail + s->next = portInfo[port].streamTail; + q->next = s; + } + else + { + s->next = r; + q->next = s; + } + + break; + } + q = r; + r = r->next; + } + + if (r == NULL) + return false; + else + return true; +} + +bool RxTx::DeleteStream(unsigned int port, Stream *s) +{ + Stream *q, *r; + + // Traverse with 'r' and keep track of prev with 'q' + q = NULL; + r = portInfo[port].streamHead; + while (r != NULL) + { + if (r == s) + { + if (r == portInfo[port].streamHead) + { + if (portInfo[port].streamHead == portInfo[port].streamTail) + { + portInfo[port].streamHead = NULL; + portInfo[port].streamTail = NULL; + } + else + portInfo[port].streamHead = portInfo[port].streamHead->next; + } + else if (r == portInfo[port].streamTail) + { + q->next = NULL; + portInfo[port].streamTail = q; + } + else + { + q->next = r->next; + } + + delete r; + break; + } + q = r; + r = r->next; + } + + if (r == NULL) + return false; + else + return true; +} + +bool RxTx::DeleteStream(unsigned int port, unsigned int streamId) +{ + Stream *q, *r; + + // Traverse with 'r' and keep track of prev with 'q' + q = NULL; + r = portInfo[port].streamHead; + while (r != NULL) + { + if (r->id == streamId) + { + if (r == portInfo[port].streamHead) + { + if (portInfo[port].streamHead == portInfo[port].streamTail) + { + portInfo[port].streamHead = NULL; + portInfo[port].streamTail = NULL; + } + else + portInfo[port].streamHead = portInfo[port].streamHead->next; + } + else if (r == portInfo[port].streamTail) + { + q->next = NULL; + portInfo[port].streamTail = q; + } + else + { + q->next = r->next; + } + + delete r; + break; + } + q = r; + r = r->next; + } + + if (r == NULL) + return false; + else + return true; +} + +void RxTx::DeleteAllStreams(unsigned int port) +{ + Stream *r, *q; + + r = portInfo[port].streamHead; + while (r != NULL) + { + q = r; + r = r->next; + delete q; + } +} + +Stream* RxTx::GetStream(unsigned int port, unsigned int streamId) +{ + Stream *r; + + r = portInfo[port].streamHead; + while (r != NULL) + { + if (r->id == streamId) + return r; + r = r->next; + } + + return NULL; +} + diff --git a/server/rxtx.h b/server/rxtx.h index 97eb2c3..986b978 100644 --- a/server/rxtx.h +++ b/server/rxtx.h @@ -4,11 +4,41 @@ #include "pcap.h" #include "abstracthost.h" +#define GET16(x) (UINT16)( \ + (*((UINT8*)x+0) << 16 ) \ + | (*((UINT8*)x+1))) + +#define GET32(x) (UINT32)( \ + (*((UINT8*)x+0) << 24) \ + | (*((UINT8*)x+1) << 16) \ + | (*((UINT8*)x+2) << 8 ) \ + | (*((UINT8*)x+3))) + +#define MAX_PKT_HDR_SIZE 1536 +#define MAX_STREAM_NAME_SIZE 64 + +typedef struct _Stream +{ + unsigned int id; + char name[MAX_STREAM_NAME_SIZE]; + unsigned char pktHdr[MAX_PKT_HDR_SIZE]; + unsigned short hdrLen; + unsigned short pktLen; + unsigned int dataPattern; + unsigned int flags; +#define STREAM_FLAG_MASK_STATUS 0x00000001 +#define STREAM_FLAG_VALUE_STATUS_DISABLED 0x00000000 +#define STREAM_FLAG_VALUE_STATUS_ENABLED 0x00000001 + + struct _Stream *next; +} Stream; typedef struct { unsigned int portId; pcap_if_t *dev; + Stream *streamHead; + Stream *streamTail; } PortInfo; class RxTx @@ -28,8 +58,19 @@ class RxTx PortInfo *portInfo; pcap_if_t *alldevs; + void InsertStreamAtHead(unsigned int port, Stream *s); + void InsertStreamAtTail(unsigned int port, Stream *s); + bool InsertStreamBefore(unsigned int port, Stream *s, + unsigned int nextStreamId); + bool DeleteStream(unsigned int port, Stream *s); + bool DeleteStream(unsigned int port, unsigned int streamId); + void DeleteAllStreams(unsigned int port); + Stream* GetStream(unsigned int port, unsigned int streamId); + //void Log(char *fmt, ...); void SendCapabilityInfo(void); + void SendPortInfo(unsigned int port); + void ProcessPortConfig(const char* msg, int len); }; #endif From 03ab9c4349651d251942c49ad718129cab190fc8 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 25 May 2008 11:53:49 +0000 Subject: [PATCH 03/98] - Fixed some trivial compilation problems with Drone - Putting in the new PacketTreeView code (still not complete) --- client/packetmodel.cpp | 652 ++++++++++++++++++++--------------------- client/packetmodel.h | 88 ++++-- server/rxtx.cpp | 6 +- 3 files changed, 392 insertions(+), 354 deletions(-) diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 4cbc92c..fd720dc 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -1,158 +1,45 @@ #include "packetmodel.h" - PacketModel::PacketModel(Stream *pStream, QObject *parent) { mpStream = pStream; + populatePacketProtocols(); + registerFrameTypeProto(); + registerVlanProto(); + registerIpProto(); + registerArpProto(); + registerTcpProto(); + registerUdpProto(); + registerIcmpProto(); + registerIgmpProto(); + registerData(); + registerInvalidProto(); } int PacketModel::rowCount(const QModelIndex &parent) const { - // Parent - Invisible Root. - // Children - Top Level Items + IndexId parentId; + + // Parent - Invalid i.e. Invisible Root. + // Children - Protocol (Top Level) Items if (!parent.isValid()) + return mPacketProtocols.count(); + + // Parent - Valid Item + parentId.w = parent.internalId(); + switch(parentId.ws.type) { - int v = 0; - - if (mpStream->l2.eth.vlanMask & VM_SVLAN_TAGGED) - v++; - if (mpStream->l2.eth.vlanMask & VM_CVLAN_TAGGED) - v++; - - if (mpStream->proto.protoMask & PM_L3_PROTO_NONE) - return v+2; // L2, Data - if (mpStream->proto.protoMask & PM_L4_PROTO_NONE) - return v+3; // L2, L3, Data - else - return v+4; // L2, L3, L4, Data + case ITYP_PROTOCOL: + return fieldCount(parentId.ws.protocol); + case ITYP_FIELD: + return subfieldCount(parentId.ws.protocol, parentId.ws.field); + case ITYP_SUBFIELD: + return 0; + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); } - // Parent - Top Level Item (L2) - // Children(count) - Second Level Items (L2 fields) - if (isIndexL2Container(parent)) - { - switch(mpStream->proto.ft) - { - case Stream::e_ft_none: - return 2; // DstMac, SrcMac - break; - - case Stream::e_ft_eth_2: - case Stream::e_ft_802_3_raw: - return 3; // DstMac, SrcMac, Type/Len - break; - - case Stream::e_ft_802_3_llc: - case Stream::e_ft_snap: - return 5; // DstMac, SrcMac, Type, DSAP, SSAP, CTL, OUI, Type - break; - - default: - qDebug("%s: Unsupported frametype", __FUNCTION__); - return -1; - } - } - - // Parent - Top Level Item (SVLAN) - // Children(count) - Second Level Items (SVLAN fields) - if (isIndexSvlanContainer(parent)) - { - return 4; // TPID, PCP, DE, VlanId - } - - // Parent - Top Level Item (CVLAN) - // Children(count) - Second Level Items (CVLAN fields) - if (isIndexCvlanContainer(parent)) - { - return 4; // TPID, Prio, CFI, VlanId - } - - // Parent - Top Level Item (L3) - // Children(count) - Second Level Items (L3 fields) - if (isIndexL3Container(parent)) - { - // L3 cannot be "None" - Q_ASSERT(mpStream->proto.protoMask & PM_L3_PROTO_NONE); - - switch(mpStream->proto.etherType) - { - case ETH_TYP_IP: - return 12; // Ver, HdrLen, TOS, TotLen, Id, Flags, - // FragOfs, TTL, Proto, Cksum, SrcIp, DstIp - break; - case ETH_TYP_ARP: - return 0; // TODO(LOW) - break; - default: - qDebug("%s: Unsupported ethtype", __FUNCTION__); - return -1; - } - } - - // Parent - Top Level Item (L4) - // Children(count) - Second Level Items (L4 fields) - if (isIndexL4Container(parent)) - { - // L4 cannot be "None" - Q_ASSERT(mpStream->proto.protoMask & PM_L4_PROTO_NONE); - - switch(mpStream->proto.ipProto) - { - case IP_PROTO_TCP: - return 10; // SrcPort, DstPort, SeqNum, AckNum, HdrLen, - // Rsvd, Flags, Window, Cksum, UrgPtr, - break; - case IP_PROTO_UDP: - return 4; // SrcPort, DstPort, TotLen, Cksum - break; - case IP_PROTO_ICMP: - case IP_PROTO_IGMP: - return 0; // TODO(LOW) - break; - default: - qDebug("%s: Unsupported ethtype", __FUNCTION__); - return -1; - } - } - - // Parent - Second Level Item (L2 field) - // Children(count) - Third Level Items (L2 subfield) - if (isIndexL2Field(parent)) - { - return 0; // No subfields for any L2 field - } - - // Parent - Second Level Item (L3 field) - // Children(count) - Third Level Items (L3 subfield) - if (isIndexL3Field(parent)) - { - if (isIndexIpField(parent)) - return 0; // TODO (MED) - if (isIndexArpField(parent)) - return 0; // TODO (LOW) - - qDebug("%s: Unknown L3 Field", __FUNCTION__); - return 0; // catch all - } - - // Parent - Second Level Item (L4 field) - // Children(count) - Third Level Items (L4 subfield) - if (isIndexL4Field(parent)) - { - if (isIndexTcpField(parent)) - return 0; // TODO (MED) - if (isIndexUdpField(parent)) - return 0; // No subfields for any UDP fields - if (isIndexIcmpField(parent)) - return 0; // TODO (LOW) - if (isIndexIgmpField(parent)) - return 0; // TODO (LOW) - - qDebug("%s: Unknown L4 Field", __FUNCTION__); - return 0; // catch all - } - - //qDebug("%s: Catch all - need to investigate", __FUNCTION__); + qWarning("%s: Catch all - need to investigate", __FUNCTION__); return 0; // catch all } @@ -165,68 +52,42 @@ QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) cons { QModelIndex index; IndexId id, parentId; - uint vlanMask = mpStream->l2.eth.vlanMask; if (!hasIndex(row, col, parent)) goto _exit; + // Parent is Invisible Root + // Request for a Protocol Item + if (!parent.isValid()) + { + id.w = 0; + id.ws.type = ITYP_PROTOCOL; + id.ws.protocol = mPacketProtocols.at(row); + index = createIndex(row, col, id.w); + goto _exit; + } + + // Parent is a Valid Item parentId.w = parent.internalId(); - - // Parent - Invisible Root - // Requested child - First/Top Level Item - if (parentId.ws.b2 == 0xFF) + id.w = parentId.w; + switch(parentId.ws.type) { - Q_ASSERT(!parent.isValid()); - - if (mpStream->l2.eth.vlanMask & VM_UNTAGGED) - id.ws.b1 = row+2; // Only L2, L3, L4 - else if (VM_SINGLE_TAGGED(vlanMask)) - { - switch (row) - { - case 0: id.ws.b1 = 2; break; // L2 - case 1: id.ws.b1 = (vlanMask & VM_SVLAN_TAGGED)?0x88:0x81; break; - case 2: id.ws.b1 = 3; break; // L3 - case 3: id.ws.b1 = 4; break; // L4 - case 4: id.ws.b1 = 0; break; // Data - default: qWarning("%s: Unexpected row (%d)", __FUNCTION__, row); - } - } - else if (VM_DOUBLE_TAGGED(vlanMask)) - { - switch (row) - { - case 0: id.ws.b1 = 2; break; // L2 - case 1: id.ws.b1 = 0x88; break; // SVLAN - case 2: id.ws.b1 = 0x81; break; // CVLAN - case 3: id.ws.b1 = 3; break; // L3 - case 4: id.ws.b1 = 4; break; // L4 - case 5: id.ws.b1 = 0; break; // Data - default: qWarning("%s: Unexpected row (%d)", __FUNCTION__, row); - } - } - id.ws.b2 = 0xFF; + case ITYP_PROTOCOL: + id.ws.type = ITYP_FIELD; + id.ws.field = row; index = createIndex(row, col, id.w); goto _exit; - } - // Parent - First Level Item - // Requested child - Second Level Item - if (parentId.ws.b3 == 0xFF) - { - Q_ASSERT(parentId.ws.b1 != 0xFF); - Q_ASSERT(parentId.ws.b2 != 0xFF); - - id.ws.b1 = parentId.ws.b1; - id.ws.b2 = 0; // TODO(MED): Set Field Id for subfields - index = createIndex(row, col, id.w); + case ITYP_FIELD: + // TODO(MED): Nothing till subfield support is added goto _exit; - } - // Parent - Second Level Item (Field) - // Requested child - Third Level Item (Subfield) - // TODO(MED): Support subfields - // Till then we return an invalid index + case ITYP_SUBFIELD: + goto _exit; + + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } _exit: return index; @@ -234,207 +95,342 @@ _exit: QModelIndex PacketModel::parent(const QModelIndex &index) const { + QModelIndex parentIndex; IndexId id, parentId; + if (!index.isValid()) + return QModelIndex(); + id.w = index.internalId(); - parentId = id; - - // 1st/Top Level Item - Protocol - // Requested Parent => Invisible Root - if (id.ws.b2 == 0xFF) - return QModelIndex(); - - // Second Level Item - Field - // Requested Parent => 1st Level Item (Protocol) - if (id.ws.b3 == 0xFF) + parentId.w = id.w; + switch(id.ws.type) { - uint vlanMask = mpStream->l2.eth.vlanMask; - int row = -1; + case ITYP_PROTOCOL: + // return invalid index for invisible root + goto _exit; - parentId.ws.b2 = 0xFF; + case ITYP_FIELD: + parentId.ws.type = ITYP_PROTOCOL; + parentId.ws.field = 0; + parentIndex = createIndex(mPacketProtocols.indexOf(parentId.ws.protocol), 0, + parentId.w); + goto _exit; - if (vlanMask & VM_UNTAGGED) - { - row = parentId.ws.b1 - 2; - } - else if (VM_SINGLE_TAGGED(vlanMask)) - { - switch (parentId.ws.b1) - { - case 2: row = 0; break; // L2 - case 0x88: - case 0x81: row = 1; break; // SVlan/CVlan - case 3: row = 2; break; // L3 - case 4: row = 3; break; // L4 - case 0: row = 4; break; // Data - default: qWarning("%s: Unexpected b1 (%d)", __FUNCTION__, parentId.ws.b1); - } - } - else if (VM_DOUBLE_TAGGED(vlanMask)) - { - switch (parentId.ws.b1) - { - case 2: row = 0; break; // L2 - case 0x88: row = 1; break; // Svlan - case 0x81: row = 2; break; // CVlan - case 3: row = 3; break; // L3 - case 4: row = 4; break; // L4 - case 0: row = 5; break; // Data - default: qWarning("%s: Unexpected b1 (%d)", __FUNCTION__, parentId.ws.b1); - } - } - else - qWarning("%s: Unhandled leg", __FUNCTION__); + case ITYP_SUBFIELD: + // TODO(MED): invalid index till subfield support is added + goto _exit; - return createIndex(row, 0, parentId.w); + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); } - // Third Level Item - Subfield - // Requested Parent => 2nd Level Item (Field) - // TODO(Med) - qWarning("%s: Unexpected leg", __FUNCTION__); - return QModelIndex(); +_exit: + return parentIndex; } QVariant PacketModel::data(const QModelIndex &index, int role) const { - IndexId id; + IndexId id; + ProtocolInfo proto; + + if (!index.isValid()) + return QVariant(); + + if (role != Qt::DisplayRole) + return QVariant(); id.w = index.internalId(); + foreach(proto, mProtocols) + { + if (proto.handle == id.ws.protocol) + goto _found; + } + return QVariant(); - if (id.ws.b2 == 0xFF) - return QString("Protocol Header"); - else - return QString("Field: Value"); +_found: + switch(id.ws.type) + { + case ITYP_PROTOCOL: + return proto.name; + + case ITYP_FIELD: + return proto.fieldList.at(id.ws.field).name; + + case ITYP_SUBFIELD: + return QVariant(); // TODO(MED): Till subfield support is added + + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + + return QVariant(); } /* ** --------------- Private Stuff ----------------- */ -typedef union +void PacketModel::populatePacketProtocols() { - quint32 w; - struct + int proto; + + // Clear the protocols list + mPacketProtocols.clear(); + + // Check and populate L2 Protocol + switch(mpStream->proto.ft) { - quint8 b1; - quint8 b2; - quint8 b3; - quint8 b4; - } ws; -} IndexId; + case Stream::e_ft_none: + proto = PTYP_L2_NONE; + break; -bool PacketModel::isIndexContainer(const QModelIndex& index, int level) const -{ - IndexId id; - - id.w = index.internalId(); - if ((id.ws.b1 == level) && (id.ws.b2 == 0xFF)) - return true; - else - return false; + case Stream::e_ft_eth_2: + proto = PTYP_L2_ETH_2; + break; + + case Stream::e_ft_802_3_raw: + proto = PTYP_L2_802_3_RAW; + break; + + case Stream::e_ft_802_3_llc: + proto = PTYP_L2_802_3_LLC; + break; + + case Stream::e_ft_snap: + proto = PTYP_L2_SNAP; + break; + + default: + qDebug("%s: Unsupported frametype", __FUNCTION__); + proto = PTYP_INVALID; + } + mPacketProtocols.append(proto); + + // Check and populate VLANs, if present + if (mpStream->l2.eth.vlanMask & VM_SVLAN_TAGGED) + mPacketProtocols.append(PTYP_SVLAN); + + if (mpStream->l2.eth.vlanMask & VM_CVLAN_TAGGED) + mPacketProtocols.append(PTYP_CVLAN); + + // Check and populate L3 protocols + if (mpStream->proto.protoMask & PM_L3_PROTO_NONE) + goto _data; + + switch(mpStream->proto.etherType) + { + case ETH_TYP_IP: + proto = PTYP_L3_IP; + break; + + case ETH_TYP_ARP: + proto = PTYP_L3_ARP; + break; + + default: + qDebug("%s: Unsupported ethtype", __FUNCTION__); + proto = PTYP_INVALID; + } + mPacketProtocols.append(proto); + + if (mpStream->proto.protoMask & PM_L4_PROTO_NONE) + goto _data; + + switch(mpStream->proto.ipProto) + { + case IP_PROTO_TCP: + proto = PTYP_L4_TCP; + break; + case IP_PROTO_UDP: + proto = PTYP_L4_UDP; + break; + case IP_PROTO_ICMP: + proto = PTYP_L4_ICMP; + break; + case IP_PROTO_IGMP: + proto = PTYP_L4_IGMP; + break; + default: + qDebug("%s: Unsupported ipProto", __FUNCTION__); + proto = PTYP_INVALID; + }; + mPacketProtocols.append(proto); + +_data: + mPacketProtocols.append(PTYP_DATA); } -bool PacketModel::isIndexL2Container(const QModelIndex& index) const +int PacketModel::fieldCount(uint protocol) const { - return isIndexContainer(index, 2); + ProtocolInfo proto; + + foreach(proto, mProtocols) + { + if (proto.handle == protocol) + { + qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data()); + qDebug("fieldcount = %d", proto.fieldList.size()); + return proto.fieldList.size(); + } + } + + return 0; } -bool PacketModel::isIndexSvlanContainer(const QModelIndex& index) const +int PacketModel::subfieldCount(uint protocol, int field) const { - return isIndexContainer(index, 0x88); + // TODO(MED): Till subfield support is added + return 0; } -bool PacketModel::isIndexCvlanContainer(const QModelIndex& index) const +/* +** ------------- Registration Functions --------------- +*/ + +void PacketModel::registerProto(uint handle, char *name, char *abbr) { - return isIndexContainer(index, 0x81); + ProtocolInfo proto; + + proto.handle = handle; + proto.name = QString(name); + proto.abbr = QString(abbr); + mProtocols.append(proto); } -bool PacketModel::isIndexL3Container(const QModelIndex& index) const +void PacketModel::registerField(uint protoHandle, char *name, char *abbr) { - return isIndexContainer(index, 3); + for (int i = 0; i < mProtocols.size(); i++) + { + if (mProtocols.at(i).handle == protoHandle) + { + FieldInfo field; + + field.name = QString(name); + field.abbr = QString(abbr); + mProtocols[i].fieldList.append(field); + qDebug("proto = %d, name = %s", protoHandle, name); + break; + } + } } -bool PacketModel::isIndexL4Container(const QModelIndex& index) const +void PacketModel::registerFrameTypeProto() { - return isIndexContainer(index, 4); + registerProto(PTYP_L2_NONE, "None", ""); + registerField(PTYP_L2_NONE, "Destination Mac", "dstMac"); + registerField(PTYP_L2_NONE, "Source Mac", "srcMac"); + + registerProto(PTYP_L2_ETH_2, "Ethernet II", "eth"); + registerField(PTYP_L2_ETH_2, "Destination Mac", "dstMac"); + registerField(PTYP_L2_ETH_2, "Source Mac", "srcMac"); + registerField(PTYP_L2_ETH_2, "Ethernet Type", "type"); + + registerProto(PTYP_L2_802_3_RAW, "IEEE 802.3 Raw", "dot3raw"); + registerField(PTYP_L2_802_3_RAW, "Destination Mac", "dstMac"); + registerField(PTYP_L2_802_3_RAW, "Source Mac", "srcMac"); + registerField(PTYP_L2_802_3_RAW, "Length", "len"); + + registerProto(PTYP_L2_802_3_LLC, "802.3 LLC", "dot3llc"); + registerField(PTYP_L2_802_3_LLC, "Destination Mac", "dstMac"); + registerField(PTYP_L2_802_3_LLC, "Source Mac", "srcMac"); + registerField(PTYP_L2_802_3_LLC, "Destination Service Acces Point", "dsap"); + registerField(PTYP_L2_802_3_LLC, "Source Service Acces Point", "ssap"); + registerField(PTYP_L2_802_3_LLC, "Control", "ctl"); + + registerProto(PTYP_L2_SNAP, "802.3 LLC SNAP", "dot3snap"); + registerField(PTYP_L2_SNAP, "Destination Mac", "dstMac"); + registerField(PTYP_L2_SNAP, "Source Mac", "srcMac"); + registerField(PTYP_L2_SNAP, "Destination Service Acces Point", "dsap"); + registerField(PTYP_L2_SNAP, "Source Service Access Point", "ssap"); + registerField(PTYP_L2_SNAP, "Control", "ctl"); + registerField(PTYP_L2_SNAP, "Organisationally Unique Identifier", "oui"); + registerField(PTYP_L2_SNAP, "Type", "type"); + } -bool PacketModel::isIndexField(const QModelIndex& index, int level) const +void PacketModel::registerVlanProto() { - IndexId id; - - id.w = index.internalId(); - if ((id.ws.b1 == level) && (id.ws.b2 != 0xFF) && (id.ws.b3 == 0xFF)) - return true; - else - return false; + registerProto(PTYP_SVLAN, "IEEE 802.1ad Service VLAN", "SVLAN"); + + registerField(PTYP_SVLAN, "Tag Protocol Identifier", "tpid"); + registerField(PTYP_SVLAN, "Priority Code Point", "pcp"); + registerField(PTYP_SVLAN, "Drop Eligible", "de"); + registerField(PTYP_SVLAN, "VLAN Identifier", "vlan"); + + registerProto(PTYP_CVLAN, "IEEE 802.1Q VLAN/CVLAN", "VLAN"); + + registerField(PTYP_CVLAN, "Tag Protocol Identifier", "tpid"); + registerField(PTYP_CVLAN, "Priority", "prio"); + registerField(PTYP_CVLAN, "Canonical Format Indicator", "cfi"); + registerField(PTYP_CVLAN, "VLAN Identifier", "vlan"); } -bool PacketModel::isIndexL2Field(const QModelIndex& index) const +void PacketModel::registerIpProto() { - return isIndexField(index, 2); + registerProto(PTYP_L3_IP, "Internet Protocol version 4", "IPv4"); + + registerField(PTYP_L3_IP, "Version", "ver"); + registerField(PTYP_L3_IP, "Header Length", "hdrlen"); + registerField(PTYP_L3_IP, "Type of Service/DiffServ Code Point", "tos"); + registerField(PTYP_L3_IP, "Total Length", "len"); + registerField(PTYP_L3_IP, "Identification", "id"); + registerField(PTYP_L3_IP, "Flags", "flags"); + registerField(PTYP_L3_IP, "Fragment Offset", "fragofs"); + registerField(PTYP_L3_IP, "Time to Live", "ttl"); + registerField(PTYP_L3_IP, "Protocol Id", "proto"); + registerField(PTYP_L3_IP, "Checksum", "cksum"); + registerField(PTYP_L3_IP, "Source IP", "srcip"); + registerField(PTYP_L3_IP, "Destination IP", "dstip"); } -bool PacketModel::isIndexL3Field(const QModelIndex& index) const +void PacketModel::registerArpProto() { - return isIndexField(index, 3); + // TODO (LOW) } -bool PacketModel::isIndexL4Field(const QModelIndex& index) const +void PacketModel::registerTcpProto() { - return isIndexField(index, 4); + registerProto(PTYP_L4_TCP, "Transmission Control Protocol", "TCP"); + + registerField(PTYP_L4_TCP, "Source Port", "srcport"); + registerField(PTYP_L4_TCP, "Destination Port", "dstport"); + registerField(PTYP_L4_TCP, "Sequence Number", "seqnum"); + registerField(PTYP_L4_TCP, "Acknowledgement Number", "acknum"); + registerField(PTYP_L4_TCP, "Header Length", "hdrlen"); + registerField(PTYP_L4_TCP, "Reserved", "rsvd"); + registerField(PTYP_L4_TCP, "Flags", "flags"); + registerField(PTYP_L4_TCP, "Window", "win"); + registerField(PTYP_L4_TCP, "Checksum", "cksum"); + registerField(PTYP_L4_TCP, "Urgent Pointer", "urgptr"); } -bool PacketModel::isIndexIpField(const QModelIndex& index) const +void PacketModel::registerUdpProto() { - IndexId id; - - id.w = index.internalId(); - if ((id.ws.b1 == 3) && (id.ws.b2 == 1) && (id.ws.b3 == 0xFF)) - return true; - else - return false; + registerProto(PTYP_L4_UDP, "User Datagram Protocol", "UDP"); + + registerField(PTYP_L4_UDP, "Source Port", "srcport"); + registerField(PTYP_L4_UDP, "Destination Port", "dstport"); + registerField(PTYP_L4_UDP, "Length", "len"); + registerField(PTYP_L4_UDP, "Checksum", "cksum"); } -bool PacketModel::isIndexArpField(const QModelIndex& index) const +void PacketModel::registerIcmpProto() { - IndexId id; - - id.w = index.internalId(); - if ((id.ws.b1 == 3) && (id.ws.b2 == 2) && (id.ws.b3 == 0xFF)) - return true; - else - return false; + // TODO (LOW) } -bool PacketModel::isIndexL4ProtoField(const QModelIndex& index, int proto) const +void PacketModel::registerIgmpProto() { - IndexId id; - - id.w = index.internalId(); - if ((id.ws.b1 == 4) && (id.ws.b2 == proto) && (id.ws.b3 == 0xFF)) - return true; - else - return false; + // TODO (LOW) } -bool PacketModel::isIndexTcpField(const QModelIndex& index) const +void PacketModel::registerInvalidProto() { - return isIndexL4ProtoField(index, IP_PROTO_TCP); + registerProto(PTYP_INVALID, "Invalid Protocol (bug in code)", "invalid"); } -bool PacketModel::isIndexUdpField(const QModelIndex& index) const +void PacketModel::registerData() { - return isIndexL4ProtoField(index, IP_PROTO_UDP); + registerProto(PTYP_DATA, "Data", "data"); } -bool PacketModel::isIndexIcmpField(const QModelIndex& index) const -{ - return isIndexL4ProtoField(index, IP_PROTO_ICMP); -} - -bool PacketModel::isIndexIgmpField(const QModelIndex& index) const -{ - return isIndexL4ProtoField(index, IP_PROTO_IGMP); -} diff --git a/client/packetmodel.h b/client/packetmodel.h index 1ecd0d2..6b2e82f 100644 --- a/client/packetmodel.h +++ b/client/packetmodel.h @@ -13,40 +13,84 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const { return QVariant(); } ; QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; QModelIndex parent(const QModelIndex &index) const; private: - Stream *mpStream; typedef union _IndexId { quint32 w; struct { - quint8 b1; // 1st Level - quint8 b2; // 2nd Level - quint8 b3; // 3rd Level - quint8 b4; // Reserved + quint8 type; +#define ITYP_PROTOCOL 1 +#define ITYP_FIELD 2 +#define ITYP_SUBFIELD 3 + quint8 protocol; + quint8 field; + quint8 subfield; } ws; } IndexId; - bool PacketModel::isIndexContainer(const QModelIndex& index, int level) const; - bool PacketModel::isIndexL2Container(const QModelIndex& index) const; - bool PacketModel::isIndexSvlanContainer(const QModelIndex& index) const; - bool PacketModel::isIndexCvlanContainer(const QModelIndex& index) const; - bool PacketModel::isIndexL3Container(const QModelIndex& index) const; - bool PacketModel::isIndexL4Container(const QModelIndex& index) const; - bool PacketModel::isIndexField(const QModelIndex& index, int level) const; - bool PacketModel::isIndexL2Field(const QModelIndex& index) const; - bool PacketModel::isIndexL3Field(const QModelIndex& index) const; - bool PacketModel::isIndexL4Field(const QModelIndex& index) const; - bool PacketModel::isIndexIpField(const QModelIndex& index) const; - bool PacketModel::isIndexArpField(const QModelIndex& index) const; - bool PacketModel::isIndexL4ProtoField(const QModelIndex& index, int proto) const; - bool PacketModel::isIndexTcpField(const QModelIndex& index) const; - bool PacketModel::isIndexUdpField(const QModelIndex& index) const; - bool PacketModel::isIndexIcmpField(const QModelIndex& index) const; - bool PacketModel::isIndexIgmpField(const QModelIndex& index) const; + typedef struct + { + QString name; + QString abbr; + } FieldInfo; + + typedef struct + { + uint handle; + QString name; + QString abbr; + QList fieldList; + } ProtocolInfo; + + Stream *mpStream; + QList mPacketProtocols; + QList mProtocols; + + void registerProto(uint handle, char *name, char *abbr); + void registerField(uint protoHandle, char *name, char *abbr); + + void registerFrameTypeProto(); + void registerVlanProto(); + void registerIpProto(); + void registerArpProto(); + void registerTcpProto(); + void registerUdpProto(); + void registerIcmpProto(); + void registerIgmpProto(); + void registerData(); + void registerInvalidProto(); + + void populatePacketProtocols(); + int fieldCount(uint protocol) const; + int subfieldCount(uint protocol, int field) const; + +// FIXME(HIGH): Is this how I want this? +#define PTYP_L2_NONE 1 +#define PTYP_L2_ETH_2 2 +#define PTYP_L2_802_3_RAW 3 +#define PTYP_L2_802_3_LLC 4 +#define PTYP_L2_SNAP 5 + +#define PTYP_SVLAN 10 +#define PTYP_CVLAN 11 + +#define PTYP_L3_IP 30 +#define PTYP_L3_ARP 31 + +#define PTYP_L4_TCP 40 +#define PTYP_L4_UDP 41 +#define PTYP_L4_ICMP 42 +#define PTYP_L4_IGMP 43 + +#define PTYP_INVALID 0 +#define PTYP_DATA 0xFF + }; #endif diff --git a/server/rxtx.cpp b/server/rxtx.cpp index 0a1bcdf..2eab59b 100644 --- a/server/rxtx.cpp +++ b/server/rxtx.cpp @@ -102,7 +102,7 @@ void RxTx::ProcessMsg(const char* msg, int len) ProcessPortConfig(msg+sizeof(tCommHdr), len - sizeof(tCommHdr)); break; case e_MT_GetPortConfig: - SendPortInfo(); + SendPortInfo(0); // FIXME break; default: @@ -300,9 +300,7 @@ _exit: void RxTx::SendPortInfo(unsigned int port) { - // Assumption: port is valid - assert(port < numPorts); - + // FIXME } /* From a480be5a230756210a1cabb4a4e89840995ab4b7 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 14 Jun 2008 06:35:17 +0000 Subject: [PATCH 04/98] Finished basic PacketModel to feed actual data into PacketView TODO: PacketModel to feed data into DumpView --- client/packetmodel.cpp | 537 +++++++++++++++++++++++++++++++++++++---- client/packetmodel.h | 35 ++- 2 files changed, 519 insertions(+), 53 deletions(-) diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index fd720dc..9064b1d 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -1,9 +1,11 @@ +#include #include "packetmodel.h" PacketModel::PacketModel(Stream *pStream, QObject *parent) { mpStream = pStream; populatePacketProtocols(); +#if 1 registerFrameTypeProto(); registerVlanProto(); registerIpProto(); @@ -14,6 +16,7 @@ PacketModel::PacketModel(Stream *pStream, QObject *parent) registerIgmpProto(); registerData(); registerInvalidProto(); +#endif } int PacketModel::rowCount(const QModelIndex &parent) const @@ -23,7 +26,7 @@ int PacketModel::rowCount(const QModelIndex &parent) const // Parent - Invalid i.e. Invisible Root. // Children - Protocol (Top Level) Items if (!parent.isValid()) - return mPacketProtocols.count(); + return protoCount(); // Parent - Valid Item parentId.w = parent.internalId(); @@ -32,13 +35,12 @@ int PacketModel::rowCount(const QModelIndex &parent) const case ITYP_PROTOCOL: return fieldCount(parentId.ws.protocol); case ITYP_FIELD: - return subfieldCount(parentId.ws.protocol, parentId.ws.field); - case ITYP_SUBFIELD: return 0; default: qWarning("%s: Unhandled ItemType", __FUNCTION__); } + Q_ASSERT(1 == 1); // Unreachable code qWarning("%s: Catch all - need to investigate", __FUNCTION__); return 0; // catch all } @@ -62,7 +64,7 @@ QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) cons { id.w = 0; id.ws.type = ITYP_PROTOCOL; - id.ws.protocol = mPacketProtocols.at(row); + id.ws.protocol = row; index = createIndex(row, col, id.w); goto _exit; } @@ -74,21 +76,18 @@ QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) cons { case ITYP_PROTOCOL: id.ws.type = ITYP_FIELD; - id.ws.field = row; index = createIndex(row, col, id.w); goto _exit; case ITYP_FIELD: - // TODO(MED): Nothing till subfield support is added - goto _exit; - - case ITYP_SUBFIELD: goto _exit; default: qWarning("%s: Unhandled ItemType", __FUNCTION__); } + Q_ASSERT(1 == 1); // Unreachable code + _exit: return index; } @@ -111,19 +110,15 @@ QModelIndex PacketModel::parent(const QModelIndex &index) const case ITYP_FIELD: parentId.ws.type = ITYP_PROTOCOL; - parentId.ws.field = 0; - parentIndex = createIndex(mPacketProtocols.indexOf(parentId.ws.protocol), 0, - parentId.w); - goto _exit; - - case ITYP_SUBFIELD: - // TODO(MED): invalid index till subfield support is added + parentIndex = createIndex(id.ws.protocol, 0, parentId.w); goto _exit; default: qWarning("%s: Unhandled ItemType", __FUNCTION__); } + Q_ASSERT(1 == 1); // Unreachable code + _exit: return parentIndex; } @@ -140,35 +135,30 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const return QVariant(); id.w = index.internalId(); - foreach(proto, mProtocols) - { - if (proto.handle == id.ws.protocol) - goto _found; - } - return QVariant(); - -_found: switch(id.ws.type) { case ITYP_PROTOCOL: - return proto.name; + return protoName(id.ws.protocol); case ITYP_FIELD: - return proto.fieldList.at(id.ws.field).name; - - case ITYP_SUBFIELD: - return QVariant(); // TODO(MED): Till subfield support is added + return fieldName(id.ws.protocol, index.row()) + + QString(" : ") + + fieldTextValue(id.ws.protocol, index.row()).toString(); default: qWarning("%s: Unhandled ItemType", __FUNCTION__); } + Q_ASSERT(1 == 1); // Unreachable code + return QVariant(); } /* ** --------------- Private Stuff ----------------- +** FIXME(MED): Move these to the Stream Class +** */ void PacketModel::populatePacketProtocols() { @@ -193,10 +183,13 @@ void PacketModel::populatePacketProtocols() break; case Stream::e_ft_802_3_llc: + mPacketProtocols.append(PTYP_L2_NONE); proto = PTYP_L2_802_3_LLC; break; case Stream::e_ft_snap: + mPacketProtocols.append(PTYP_L2_NONE); + mPacketProtocols.append(PTYP_L2_802_3_LLC); proto = PTYP_L2_SNAP; break; @@ -260,29 +253,494 @@ _data: mPacketProtocols.append(PTYP_DATA); } -int PacketModel::fieldCount(uint protocol) const +int PacketModel::protoCount() const +{ + return mPacketProtocols.count(); +} + +int PacketModel::fieldCount(int protocol) const { ProtocolInfo proto; + if (protocol >= mPacketProtocols.count()) + return 0; + foreach(proto, mProtocols) { - if (proto.handle == protocol) + if (proto.handle == mPacketProtocols.at(protocol)) { qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data()); qDebug("fieldcount = %d", proto.fieldList.size()); - return proto.fieldList.size(); + return proto.fieldList.count(); } } return 0; } -int PacketModel::subfieldCount(uint protocol, int field) const +QString PacketModel::protoName(int protocol) const { - // TODO(MED): Till subfield support is added - return 0; + ProtocolInfo proto; + + if (protocol >= mPacketProtocols.count()) + return 0; + + foreach(proto, mProtocols) + { + if (proto.handle == mPacketProtocols.at(protocol)) + { + qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data()); + qDebug("fieldcount = %d", proto.fieldList.size()); + return proto.name; + } + } + + return QString(); } +QString PacketModel::fieldName(int protocol, int field) const +{ + ProtocolInfo proto; + + if (protocol >= mPacketProtocols.count()) + return 0; + + foreach(proto, mProtocols) + { + if (proto.handle == mPacketProtocols.at(protocol)) + { + qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data()); + qDebug("fieldcount = %d", proto.fieldList.size()); + if (field >= proto.fieldList.count()) + return QString(); + + return proto.fieldList.at(field).name; + } + } + + return QString(); +} + +QVariant PacketModel::fieldTextValue(int protocol, int field) const +{ + if (protocol >= mPacketProtocols.count()) + return QVariant(); + + switch(mPacketProtocols.at(protocol)) + { + case PTYP_L2_NONE: + case PTYP_L2_ETH_2: + return ethField(field, FROL_TEXT_VALUE); + case PTYP_L2_802_3_RAW: + //return dot3Field(field, FROL_TEXT_VALUE); // FIXME(HIGH) + return ethField(field, FROL_TEXT_VALUE); + case PTYP_L2_802_3_LLC: + return llcField(field, FROL_TEXT_VALUE); + case PTYP_L2_SNAP: + return snapField(field, FROL_TEXT_VALUE); + + case PTYP_SVLAN: + return svlanField(field, FROL_TEXT_VALUE); + case PTYP_CVLAN: + // return cvlanField(field, FROL_TEXT_VALUE); // FIXME(HIGH) + return svlanField(field, FROL_TEXT_VALUE); + + case PTYP_L3_IP: + return ipField(field, FROL_TEXT_VALUE); + case PTYP_L3_ARP: + return QString(); // FIXME(HIGH) + + case PTYP_L4_TCP: + return tcpField(field, FROL_TEXT_VALUE); + case PTYP_L4_UDP: + return udpField(field, FROL_TEXT_VALUE); + case PTYP_L4_ICMP: + return QString(); // FIXME(HIGH) + case PTYP_L4_IGMP: + return QString(); // FIXME(HIGH) + + case PTYP_INVALID: + return QString(); // FIXME(HIGH) + case PTYP_DATA: + return QString(); // FIXME(HIGH) + } + + return QString(); +} + +QVariant PacketModel::ethField(int field, int role) const +{ + FieldInfo info; + + // FIXME(MED): Mac Addr formatting + + switch(field) + { + case 0: + info.name = QString("Destination Mac Address"); + info.textValue = QString("%1%2"). + arg(mpStream->l2.eth.dstMacMshw, 4, BASE_HEX, QChar('0')). + arg(mpStream->l2.eth.dstMacLsw, 8, BASE_HEX, QChar('0')); + break; + case 1: + info.name = QString("Source Mac Address"); + info.textValue = QString("%1%2"). + arg(mpStream->l2.eth.srcMacMshw, 4, BASE_HEX, QChar('0')). + arg(mpStream->l2.eth.srcMacLsw, 8, BASE_HEX, QChar('0')); + break; + case 2: + info.name = QString("Type"); + info.textValue = QString("0x%1"). + arg(mpStream->proto.etherType, 4, BASE_HEX, QChar('0')); + break; + default: + info.name = QString(); + info.textValue = QString(); + } + + switch(role) + { + case FROL_NAME: + return info.name; + case FROL_TEXT_VALUE: + return info.textValue; + default: + ; + } + + Q_ASSERT(1 == 1); // Unreachable code + return QVariant(); +} + +QVariant PacketModel::llcField(int field, int role) const +{ + FieldInfo info; + + switch(field) + { + case 0: + info.name = QString("DSAP"); + info.textValue = QString("0x%1"). + arg(mpStream->proto.dsap, 2, BASE_HEX, QChar('0')); + break; + case 1: + info.name = QString("SSAP"); + info.textValue = QString("0x%1"). + arg(mpStream->proto.ssap, 2, BASE_HEX, QChar('0')); + break; + case 2: + info.name = QString("Control"); + info.textValue = QString("0x%1"). + arg(mpStream->proto.ctl, 2, BASE_HEX, QChar('0')); + break; + default: + info.name = QString(); + info.textValue = QString(); + } + + switch(role) + { + case FROL_NAME: + return info.name; + case FROL_TEXT_VALUE: + return info.textValue; + default: + ; + } + + Q_ASSERT(1 == 1); // Unreachable code + return QVariant(); +} + +QVariant PacketModel::snapField(int field, int role) const +{ + FieldInfo info; + + switch(field) + { + case 0: + info.name = QString("OUI"); + info.textValue = QString("0x%1%2"). + arg(mpStream->proto.ouiMsb, 2, BASE_HEX, QChar('0')). + arg(mpStream->proto.ouiLshw, 4, BASE_HEX, QChar('0')); + break; + case 1: + info.name = QString("Type"); + info.textValue = QString("0x%1"). + arg(mpStream->proto.etherType, 4, BASE_HEX, QChar('0')); + break; + default: + info.name = QString(); + info.textValue = QString(); + } + + switch(role) + { + case FROL_NAME: + return info.name; + case FROL_TEXT_VALUE: + return info.textValue; + default: + ; + } + + Q_ASSERT(1 == 1); // Unreachable code + return QVariant(); +} + +QVariant PacketModel::svlanField(int field, int role) const +{ + FieldInfo info; + + switch(field) + { + case 0: + info.name = QString("TPID"); + info.textValue = QString("0x%1"). + arg(mpStream->l2.eth.stpid, 4, BASE_HEX, QChar('0')); + break; + case 1: + info.name = QString("PCP"); + info.textValue = QString("%1"). + arg(mpStream->l2.eth.svlanPrio); + break; + case 2: + info.name = QString("DE"); + info.textValue = QString("%1"). + arg(mpStream->l2.eth.svlanCfi); + break; + case 3: + info.name = QString("VlanId"); + info.textValue = QString("%1"). + arg(mpStream->l2.eth.svlanId); + break; + default: + info.name = QString(); + info.textValue = QString(); + } + + switch(role) + { + case FROL_NAME: + return info.name; + case FROL_TEXT_VALUE: + return info.textValue; + default: + ; + } + + Q_ASSERT(1 == 1); // Unreachable code + return QVariant(); +} + + +QVariant PacketModel::ipField(int field, int role) const +{ + FieldInfo info; + + switch(field) + { + case 0: + info.name = QString("Version"); + info.textValue = QString("%1"). + arg(mpStream->l3.ip.ver); + break; + case 1: + info.name = QString("Header Length"); + info.textValue = QString("%1"). + arg(mpStream->l3.ip.hdrLen); + break; + case 2: + info.name = QString("TOS/DSCP"); + info.textValue = QString("0x%1"). + arg(mpStream->l3.ip.tos, 2, BASE_HEX, QChar('0')); + break; + case 3: + info.name = QString("Total Length"); + info.textValue = QString("%1"). + arg(mpStream->l3.ip.totLen); + break; + case 4: + info.name = QString("ID"); + info.textValue = QString("0x%1"). + arg(mpStream->l3.ip.id, 2, BASE_HEX, QChar('0')); + break; + case 5: + info.name = QString("Flags"); + info.textValue = QString("0x%1"). + arg(mpStream->l3.ip.flags, 2, BASE_HEX, QChar('0')); // FIXME(HIGH) + break; + case 6: + info.name = QString("Fragment Offset"); + info.textValue = QString("%1"). + arg(mpStream->l3.ip.fragOfs); + break; + case 7: + info.name = QString("TTL"); + info.textValue = QString("%1"). + arg(mpStream->l3.ip.ttl); + break; + case 8: + info.name = QString("Protocol Type"); + info.textValue = QString("0x%1"). + arg(mpStream->l3.ip.proto, 2, BASE_HEX, QChar('0')); + break; + case 9: + info.name = QString("Checksum"); + info.textValue = QString("0x%1"). + arg(mpStream->l3.ip.cksum, 4, BASE_HEX, QChar('0')); + break; + case 10: + info.name = QString("Source IP"); + info.textValue = QHostAddress(mpStream->l3.ip.srcIp).toString(); + break; + case 11: + info.name = QString("Destination IP"); + info.textValue = QHostAddress(mpStream->l3.ip.dstIp).toString(); + break; + default: + info.name = QString(); + info.textValue = QString(); + } + + switch(role) + { + case FROL_NAME: + return info.name; + case FROL_TEXT_VALUE: + return info.textValue; + default: + ; + } + + Q_ASSERT(1 == 1); // Unreachable code + return QVariant(); +} + + +QVariant PacketModel::tcpField(int field, int role) const +{ + FieldInfo info; + + switch(field) + { + case 0: + info.name = QString("Source Port"); + info.textValue = QString("%1"). + arg(mpStream->l4.tcp.srcPort); + break; + case 1: + info.name = QString("Destination Port"); + info.textValue = QString("%1"). + arg(mpStream->l4.tcp.dstPort); + break; + case 2: + info.name = QString("Seq Number"); + info.textValue = QString("%1"). + arg(mpStream->l4.tcp.seqNum); + break; + case 3: + info.name = QString("Ack Number"); + info.textValue = QString("%1"). + arg(mpStream->l4.tcp.ackNum); + break; + case 4: + info.name = QString("Header Length"); + info.textValue = QString("%1"). + arg(mpStream->l4.tcp.hdrLen); + break; + case 5: + info.name = QString("Reserved"); + info.textValue = QString("%1"). + arg(mpStream->l4.tcp.rsvd); + break; + case 6: + info.name = QString("Flags"); + info.textValue = QString("0x%1"). + arg(mpStream->l4.tcp.flags, 2, BASE_HEX, QChar('0')); + break; + case 7: + info.name = QString("Window"); + info.textValue = QString("%1"). + arg(mpStream->l4.tcp.flags); + break; + case 8: + info.name = QString("Checksum"); + info.textValue = QString("0x%1"). + arg(mpStream->l4.tcp.cksum, 4, BASE_HEX, QChar('0')); + break; + case 9: + info.name = QString("Urgent Pointer"); + info.textValue = QString("%1"). + arg(mpStream->l4.tcp.urgPtr); + break; + default: + info.name = QString(); + info.textValue = QString(); + } + + switch(role) + { + case FROL_NAME: + return info.name; + case FROL_TEXT_VALUE: + return info.textValue; + default: + ; + } + + Q_ASSERT(1 == 1); // Unreachable code + return QVariant(); +} + + +QVariant PacketModel::udpField(int field, int role) const +{ + FieldInfo info; + + switch(field) + { + case 0: + info.name = QString("Source Port"); + info.textValue = QString("%1"). + arg(mpStream->l4.udp.srcPort); + break; + case 1: + info.name = QString("Destination Port"); + info.textValue = QString("%1"). + arg(mpStream->l4.udp.dstPort); + break; + case 2: + info.name = QString("Total Length"); + info.textValue = QString("%1"). + arg(mpStream->l4.udp.totLen); + break; + case 3: + info.name = QString("Checksum"); + info.textValue = QString("0x%1"). + arg(mpStream->l4.udp.cksum, 4, BASE_HEX, QChar('0')); + break; + default: + info.name = QString(); + info.textValue = QString(); + } + + switch(role) + { + case FROL_NAME: + return info.name; + case FROL_TEXT_VALUE: + return info.textValue; + default: + ; + } + + Q_ASSERT(1 == 1); // Unreachable code + return QVariant(); +} + + + /* ** ------------- Registration Functions --------------- */ @@ -331,18 +789,11 @@ void PacketModel::registerFrameTypeProto() registerField(PTYP_L2_802_3_RAW, "Length", "len"); registerProto(PTYP_L2_802_3_LLC, "802.3 LLC", "dot3llc"); - registerField(PTYP_L2_802_3_LLC, "Destination Mac", "dstMac"); - registerField(PTYP_L2_802_3_LLC, "Source Mac", "srcMac"); registerField(PTYP_L2_802_3_LLC, "Destination Service Acces Point", "dsap"); registerField(PTYP_L2_802_3_LLC, "Source Service Acces Point", "ssap"); registerField(PTYP_L2_802_3_LLC, "Control", "ctl"); - registerProto(PTYP_L2_SNAP, "802.3 LLC SNAP", "dot3snap"); - registerField(PTYP_L2_SNAP, "Destination Mac", "dstMac"); - registerField(PTYP_L2_SNAP, "Source Mac", "srcMac"); - registerField(PTYP_L2_SNAP, "Destination Service Acces Point", "dsap"); - registerField(PTYP_L2_SNAP, "Source Service Access Point", "ssap"); - registerField(PTYP_L2_SNAP, "Control", "ctl"); + registerProto(PTYP_L2_SNAP, "SNAP", "dot3snap"); registerField(PTYP_L2_SNAP, "Organisationally Unique Identifier", "oui"); registerField(PTYP_L2_SNAP, "Type", "type"); diff --git a/client/packetmodel.h b/client/packetmodel.h index 6b2e82f..4f79155 100644 --- a/client/packetmodel.h +++ b/client/packetmodel.h @@ -24,20 +24,21 @@ private: quint32 w; struct { - quint8 type; + quint16 type; #define ITYP_PROTOCOL 1 #define ITYP_FIELD 2 -#define ITYP_SUBFIELD 3 - quint8 protocol; - quint8 field; - quint8 subfield; + quint16 protocol; } ws; } IndexId; + Stream *mpStream; + QList mPacketProtocols; + typedef struct { QString name; QString abbr; + QString textValue; } FieldInfo; typedef struct @@ -48,10 +49,7 @@ private: QList fieldList; } ProtocolInfo; - Stream *mpStream; - QList mPacketProtocols; QList mProtocols; - void registerProto(uint handle, char *name, char *abbr); void registerField(uint protoHandle, char *name, char *abbr); @@ -67,13 +65,26 @@ private: void registerInvalidProto(); void populatePacketProtocols(); - int fieldCount(uint protocol) const; - int subfieldCount(uint protocol, int field) const; + + int protoCount() const; + int fieldCount(int protocol) const; + QString protoName(int protocol) const; + QString fieldName(int protocol, int field) const; + QVariant fieldTextValue(int protocol, int field) const; + + QVariant ethField(int field, int role) const; + QVariant llcField(int field, int role) const; + QVariant snapField(int field, int role) const; + QVariant svlanField(int field, int role) const; + QVariant ipField(int field, int role) const; + QVariant tcpField(int field, int role) const; + QVariant udpField(int field, int role) const; // FIXME(HIGH): Is this how I want this? #define PTYP_L2_NONE 1 #define PTYP_L2_ETH_2 2 #define PTYP_L2_802_3_RAW 3 + #define PTYP_L2_802_3_LLC 4 #define PTYP_L2_SNAP 5 @@ -91,6 +102,10 @@ private: #define PTYP_INVALID 0 #define PTYP_DATA 0xFF +#define FROL_NAME 1 +#define FROL_TEXT_VALUE 2 + +#define BASE_HEX 16 }; #endif From a009fcffdff8538c3adccff8457d687533587f1f Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 14 Jun 2008 07:40:41 +0000 Subject: [PATCH 05/98] Deleted unused files --- client/mythread.cpp | 24 ----- client/mythread.h | 23 ----- client/ostinato.pro | 1 - client/portgrouplistmodel.h | 55 ----------- client/portlistmodel.cpp | 191 ------------------------------------ client/portlistmodel.h | 37 ------- client/streamlistmodel.cpp | 119 ---------------------- client/streamlistmodel.h | 46 --------- 8 files changed, 496 deletions(-) delete mode 100644 client/mythread.cpp delete mode 100644 client/mythread.h delete mode 100644 client/portgrouplistmodel.h delete mode 100644 client/portlistmodel.cpp delete mode 100644 client/portlistmodel.h delete mode 100644 client/streamlistmodel.cpp delete mode 100644 client/streamlistmodel.h diff --git a/client/mythread.cpp b/client/mythread.cpp deleted file mode 100644 index 69fe660..0000000 --- a/client/mythread.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "mythread.h" - - void MyThread::run() - { - int i, j; - - for (i=0; i - -#define NumPorts 2 -#define NumStats 8 - - class MyThread : public QThread - { - Q_OBJECT - - public: - void run(); - - signals: - void portStatsUpdate(int port, void *stats); - - private: - int stats[2][8]; - }; - -#endif diff --git a/client/ostinato.pro b/client/ostinato.pro index aceb998..07dcdc0 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -6,7 +6,6 @@ HEADERS += \ dumpview.h \ hexlineedit.h \ mainwindow.h \ - mythread.h \ packetmodel.h \ port.h \ portgroup.h \ diff --git a/client/portgrouplistmodel.h b/client/portgrouplistmodel.h deleted file mode 100644 index 4242539..0000000 --- a/client/portgrouplistmodel.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _PORT_GROUP_LIST_H -#define _PORT_GROUP_LIST_H - -#include "portgroup.h" -#include - -/* ----------------------------------------------------------- -** NOTE: FILE NOT USED 'COZ MOC DOESN'T SUPPORT NESTED CLASSES -*-------------------------------------------------------------*/ - - -class PortGroupList; - -class PortGroupList : public QObject { - - Q_OBJECT - - class PortListModel : public QAbstractItemModel - { - // This is currently a read only model - Q_OBJECT - - PortGroupList *pgl; // FIXME(HIGH): rename member - - public: - PortListModel(PortGroupList *p, QObject *parent = 0); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; - QModelIndex parent(const QModelIndex &index) const; - - friend class PortGroupList; // FIXME(MED): Review need for friend - }; - - friend class PortListModel; - - QList mPortGroups; - PortListModel mPortGroupListModel; - -// Methods -public: - PortGroupList::PortGroupList(); - QAbstractItemModel* getModel(); - int addPortGroup(PortGroup &portGroup); - int removePortGroup(PortGroup &portGroup); - -private slots: - void when_portlist_dataChanged(); -}; - -#endif diff --git a/client/portlistmodel.cpp b/client/portlistmodel.cpp deleted file mode 100644 index df53fb9..0000000 --- a/client/portlistmodel.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "portlistmodel.h" - ------------------------ -This file is not used ------------------------ - -PortListModel::PortListModel(QObject *parent) - : QAbstractItemModel(parent) -{ - portList = new QList; - -#if 0 // FIXME: Dummy data only for testing; to be removed - PortGroup pg; - - pg.name = "A"; - pg.isLocal = TRUE; - pg.numPorts = 3; - pg.port = new Port[pg.numPorts]; - pg.port[0].portId = 0; - pg.port[0].name = "A0"; - pg.port[0].desc = "a0a0a0a0a0a0"; - pg.port[1].portId = 1; - pg.port[1].name = "A1"; - pg.port[1].desc = "a1a1a1a1a1a1"; - pg.port[2].portId = 2; - pg.port[2].name = "A2"; - pg.port[2].desc = "a2a2a2a2a2a2"; - - portList->append(pg); - - pg.name = "B"; - pg.isLocal = FALSE; - pg.numPorts = 2; - pg.port = new Port[pg.numPorts]; - pg.port[0].portId = 0; - pg.port[0].name = "B0"; - pg.port[0].desc = "b0b0b0b0b0b0"; - pg.port[1].portId = 1; - pg.port[1].name = "B1"; - pg.port[1].desc = "b1b1b1b1b1b1"; - - portList->append(pg); -#endif - // Do I need to do anything here? -} - -int PortListModel::rowCount(const QModelIndex &parent) const -{ - // qDebug("RowCount Enter\n"); - if (!parent.isValid()) - { - // Top Level Item - // qDebug("RowCount top\n"); - // qDebug("RowCount Exit: %d\n", portList->size()); - return portList->size(); - } - // qDebug("RowCount non top %d, %d, %llx\n", - // parent.row(), parent.column(), parent.internalId()); - - quint16 p = parent.internalId() & 0xFFFF; - if (p == 0xFFFF) - { - // qDebug("RowCount Exit: %d\n", portList->at(parent.row()).numPorts); - return portList->at(parent.row()).numPorts; - } - else - { - // Leaf Item - return 0; - } -} - -int PortListModel::columnCount(const QModelIndex &parent ) const -{ - return 1; // FIXME: hardcoding -} - -Qt::ItemFlags PortListModel::flags(const QModelIndex &index) const -{ - return QAbstractItemModel::flags(index); // FIXME: no need for this func -} -QVariant PortListModel::data(const QModelIndex &index, int role) const -{ - //qDebug("Enter PortListModel data\n"); - // Check for a valid index - if (!index.isValid()) - return QVariant(); - - - // Check role - if ((role == Qt::DisplayRole)) - { -#if 0 // Only for debug - qDebug("Exit PortListModel data\n"); - return "Testing"; // FIXME: for dbg only -#endif - - QModelIndex parent = index.parent(); - - if (!parent.isValid()) - { - // Top Level Item - return QString("%1 (%2) [%3]"). - arg(portList->at(index.row()).name). - arg(portList->at(index.row()).isLocal == TRUE? "LOCAL" : "REMOTE"). - arg(portList->at(index.row()).numPorts); - } - return QString("%1: %2 (%3)"). - arg(portList->at(parent.row()).port[index.row()].portId). - arg(portList->at(parent.row()).port[index.row()].name). - arg(portList->at(parent.row()).port[index.row()].desc); - } - else - return QVariant(); -} - -QVariant PortListModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role != Qt::DisplayRole) - return QVariant(); - - if (orientation == Qt::Horizontal) - return QVariant(); - else - return QString("%1").arg(section+1); -} - -QModelIndex PortListModel::index (int row, int col, - const QModelIndex & parent) const -{ -#if 0 - if (!hasIndex(row, col, parent)) - return QModelIndex(); -#endif - - //qDebug("index: R=%d, C=%d, PR=%d, PC=%d, PID=%llx\n", - // row, col, parent.row(), parent.column(), parent.internalId()); - - if (!parent.isValid()) - { - // Top Level Item - quint16 pg = row, p = 0xFFFF; - quint32 id = (pg << 16) | p; - //qDebug("index (top) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); - - return createIndex(row, col, id); - } - else - { - quint16 pg = parent.row(), p = row; - quint32 id = (pg << 16) | p; - //qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); - - return createIndex(row, col, id); - } -} - -QModelIndex PortListModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - //qDebug("parent: R=%d, C=%d ID=%llx\n", - // index.row(), index.column(), index.internalId()); - - quint16 pg = index.internalId() >> 16; - quint16 p = index.internalId() & 0x0000FFFF; - - //qDebug("parent dbg: PG=%d, P=%d\n", pg, p); - - if (p == 0xFFFF) - { - //qDebug("parent ret: NULL\n"); - // Top Level Item - PG - return QModelIndex(); - } - - quint32 id = (pg << 16) | 0xFFFF; - //qDebug("parent ret: R=%d, C=%d, ID=%x\n", - // pg, 0, id); - - return createIndex(pg, 0, id); - -} - -void PortListModel::doRefresh() -{ - emit layoutChanged(); -} - - diff --git a/client/portlistmodel.h b/client/portlistmodel.h deleted file mode 100644 index 45a07bc..0000000 --- a/client/portlistmodel.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _PORT_LIST_MODEL_H -#define _PORT_LIST_MODEL_H - - - ----------------- - This file is not used - ------------------ - -#include -#include -#include "portgroup.h" - -static QStringList PortListCols = (QStringList() - << "Name" -); - -class PortListModel : public QAbstractItemModel -{ - Q_OBJECT - - public: - //PortListModel(QObject *parent = 0) : QAbstractItemModel(parent) {} - PortListModel(QObject *parent = 0); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; - QModelIndex parent(const QModelIndex &index) const; - - void doRefresh(); // FIXME: temp till model exports functions to insert rows - QList *portList; // FIXME: this shd be private -}; - -#endif diff --git a/client/streamlistmodel.cpp b/client/streamlistmodel.cpp deleted file mode 100644 index 9812720..0000000 --- a/client/streamlistmodel.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "streamlistmodel.h" - -StreamListModel::StreamListModel(QObject *parent) - : QAbstractTableModel(parent) -{ - uint i; - - // Enable all streams by default - for (i=0; i= MAX_ROWS) - return QVariant(); - - if (index.column() >= MAX_COLS) - return QVariant(); - - // Check role - if (index.column() == 0) // Icon - { - if ((role == Qt::DisplayRole)) - return QString("EDIT"); - else - return QVariant(); - } - else if (index.column() == 1) // Name - { - if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) - return streamList[index.row()].streamName; - else - return QVariant(); - } - else if (index.column() == 2) // Enabled? - { - //if ((role == Qt::CheckStateRole) || (role == Qt::EditRole)) - // return streamList[index.row()].isEnabled ? Qt::Checked : Qt::Unchecked; - if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) - return streamList[index.row()].isEnabled; - else - return QVariant(); - } -} - -bool StreamListModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (index.isValid() && role == Qt::EditRole) - { - if (index.column() == 1) // Name - streamList[index.row()].streamName = value.toString(); - else if (index.column() == 2) // Enabled? - streamList[index.row()].isEnabled = value.toBool(); - else - return false; - - return true; - } - return false; -} - -QVariant StreamListModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role != Qt::DisplayRole) - return QVariant(); - - if (orientation == Qt::Horizontal) - return StreamListCols.at(section); - else - return QString("%1").arg(section+1); -} - -#if 0 -// QModelIndex StreamListModel::index (int portNum, PortStat stat, const QModelIndex & parent = QModelIndex() ) const - -void StreamListModel::on_portStatsUpdate(int port, void*stats) -{ - int i; - QModelIndex topLeft = index(port, 0, QModelIndex()); - QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex()); - - for (i = 0; i < e_STAT_MAX; i++) - dummyStats[port][i] = ((int *)stats)[i]; - - emit dataChanged(topLeft, bottomRight); -} - -#endif diff --git a/client/streamlistmodel.h b/client/streamlistmodel.h deleted file mode 100644 index 54c222b..0000000 --- a/client/streamlistmodel.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _STREAM_LIST_MODEL_H -#define _STREAM_LIST_MODEL_H - -#include -#include - -static QStringList StreamListCols = (QStringList() - << "Icon" - << "Name" - << "Enable" -); - -#define MAX_ROWS 5 -#define MAX_COLS 3 - -class StreamListModel : public QAbstractTableModel -{ - Q_OBJECT - - public: - //StreamListModel(QObject *parent = 0) : QAbstractTableModel(parent) {} - StreamListModel(QObject *parent = 0); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - // QModelIndex index (int portNum, PortStat stat, const QModelIndex & parent = QModelIndex() ) const; - - public slots: -// void on_portStatsUpdate(int port, void*stats); - - private: - // FIXME: temp -//#define NUM_PORTS 2 -// int dummyStats[NUM_PORTS][e_STAT_MAX]; - struct { - QString streamName; - bool isEnabled; - } streamList[MAX_ROWS]; - -}; - -#endif From f220482876104bed3c948886a16e9742b64106c0 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 9 Aug 2008 03:22:13 +0000 Subject: [PATCH 06/98] Added Google Protocol Buffers as the serialization format between client and server. Initial Checkin. PB related code not yet complete --- Makefile | 5 + client/hexlineedit.cpp | 3 +- client/ostinato.pro | 8 +- client/packetmodel.cpp | 17 +- client/port.cpp | 74 ++- client/port.h | 71 ++- client/portgroup.cpp | 143 +++++- client/portgroup.h | 45 +- client/portstatsmodel.cpp | 4 + client/portswindow.cpp | 1 - client/stream.cpp | 11 + client/stream.h | 862 +++++++++++++++++++++++----------- client/streamconfigdialog.cpp | 233 +++++---- client/streamconfigdialog.h | 3 +- client/streamconfigdialog.ui | 148 +++--- client/streammodel.cpp | 2 +- common/Makefile | 14 + common/protocol.proto | 302 ++++++++++++ rpc/pbhelper.h | 66 +++ rpc/pbrpc.pro | 13 + rpc/pbrpcchannel.cpp | 189 ++++++++ rpc/pbrpcchannel.h | 74 +++ rpc/pbrpccommon.h | 52 ++ rpc/pbrpccontroller.h | 27 ++ rpc/rpcserver.cpp | 180 +++++++ rpc/rpcserver.h | 44 ++ server/abstracthost.h | 2 + server/drone.cpp | 17 +- server/drone.h | 19 +- server/drone.pro | 10 +- server/myservice.cpp | 290 ++++++++++++ server/myservice.h | 146 ++++++ server/rxtx.cpp | 10 +- server/rxtx.h | 8 + 34 files changed, 2598 insertions(+), 495 deletions(-) create mode 100644 Makefile create mode 100644 common/Makefile create mode 100644 common/protocol.proto create mode 100644 rpc/pbhelper.h create mode 100644 rpc/pbrpc.pro create mode 100644 rpc/pbrpcchannel.cpp create mode 100644 rpc/pbrpcchannel.h create mode 100644 rpc/pbrpccommon.h create mode 100644 rpc/pbrpccontroller.h create mode 100644 rpc/rpcserver.cpp create mode 100644 rpc/rpcserver.h create mode 100644 server/myservice.cpp create mode 100644 server/myservice.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c24ac11 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +all: + $(MAKE) -C rpc install + $(MAKE) -C common + $(MAKE) -C server + $(MAKE) -C client diff --git a/client/hexlineedit.cpp b/client/hexlineedit.cpp index a983bfd..85d5ccf 100644 --- a/client/hexlineedit.cpp +++ b/client/hexlineedit.cpp @@ -1,7 +1,8 @@ #include "hexlineedit.h" #include "qdebug.h" -QString & uintToHexStr(quint32 num, QString &hexStr, quint8 octets); +QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets); + HexLineEdit::HexLineEdit( QWidget * parent) : QLineEdit(parent) { diff --git a/client/ostinato.pro b/client/ostinato.pro index 07dcdc0..4b1cb69 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -1,6 +1,8 @@ TEMPLATE = app CONFIG += qt debug QT += network +INCLUDEPATH += "c:\msys\1.0\local\include" "..\rpc\" +LIBS += -L"c:\msys\1.0\local\lib" -lprotobuf -L"..\rpc\debug" -lpbrpc RESOURCES += ostinato.qrc HEADERS += \ dumpview.h \ @@ -31,7 +33,6 @@ SOURCES += \ hexlineedit.cpp \ main.cpp \ mainwindow.cpp \ - mythread.cpp \ packetmodel.cpp \ port.cpp \ portgroup.cpp \ @@ -44,5 +45,10 @@ SOURCES += \ streamconfigdialog.cpp \ streammodel.cpp +# Protocol Buffer Sources + +SOURCES += \ + ..\common\protocol.pb.cc + # TODO(LOW): Test only include(modeltest.pri) diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 9064b1d..8711b53 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -167,6 +167,7 @@ void PacketModel::populatePacketProtocols() // Clear the protocols list mPacketProtocols.clear(); +#if 0 // FIXME: protobuf // Check and populate L2 Protocol switch(mpStream->proto.ft) { @@ -251,6 +252,7 @@ void PacketModel::populatePacketProtocols() _data: mPacketProtocols.append(PTYP_DATA); +#endif } int PacketModel::protoCount() const @@ -373,7 +375,7 @@ QVariant PacketModel::ethField(int field, int role) const FieldInfo info; // FIXME(MED): Mac Addr formatting - +#if 0 // FIXME protobuf switch(field) { case 0: @@ -409,6 +411,7 @@ QVariant PacketModel::ethField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -416,6 +419,7 @@ QVariant PacketModel::llcField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -449,6 +453,7 @@ QVariant PacketModel::llcField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -456,6 +461,7 @@ QVariant PacketModel::snapField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -485,6 +491,7 @@ QVariant PacketModel::snapField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -492,6 +499,7 @@ QVariant PacketModel::svlanField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -530,6 +538,7 @@ QVariant PacketModel::svlanField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -538,6 +547,7 @@ QVariant PacketModel::ipField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -614,6 +624,7 @@ QVariant PacketModel::ipField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -622,6 +633,7 @@ QVariant PacketModel::tcpField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -690,6 +702,7 @@ QVariant PacketModel::tcpField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -698,6 +711,7 @@ QVariant PacketModel::udpField(int field, int role) const { FieldInfo info; +#if 0 // FIXME:protobuf switch(field) { case 0: @@ -736,6 +750,7 @@ QVariant PacketModel::udpField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } diff --git a/client/port.cpp b/client/port.cpp index f7122d3..2196e7d 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -1,17 +1,82 @@ +#include + +#include + #include "port.h" +#include "pbhelper.h" + Port::Port(quint32 id, quint32 portGroupId) { - mPortId = id; + d.set_port_id(id); mPortGroupId = portGroupId; - mAdminStatus = AdminDisable; - mOperStatus = OperDown; - mControlMode = ControlShared; +#if 0 // PB // FIXME(HI): TEST only for(int i = 0; i < 10; i++) mPortStats[i] = mPortGroupId*10000+mPortId*100+i; +#endif +} + +void Port::updatePortConfig(OstProto::PortConfig *portConfig) +{ + + PbHelper pbh; + + pbh.update(&d, portConfig); +#if 0 + const ::google::protobuf::Message::Reflection *ref1; + ::google::protobuf::Message::Reflection *ref2; + std::vector list; + + qDebug("In %s", __FUNCTION__); + + ref1 = portConfig.GetReflection(); + ref1->ListFields(&list); + + ref2 = d.GetReflection(); + + for (uint i=0; i < list.size(); i++) + { + const ::google::protobuf::FieldDescriptor *f1, *f2; + + f1 = list[i]; + f2 = d.GetDescriptor()->FindFieldByName(f1->name()); + switch(f2->type()) + { + case ::google::protobuf::FieldDescriptor::TYPE_UINT32: + ref2->SetUInt32(f2, ref1->GetUInt32(f1)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_BOOL: + ref2->SetBool(f2, ref1->GetBool(f1)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_STRING: + ref2->SetString(f2, ref1->GetString(f1)); + break; + default: + qDebug("unhandled Field Type"); + break; + } + } + + if (msg->GetDescriptor() != OstProto::PortConfig::descriptor()) + { + qDebug("%s: invalid Message Descriptor (%s)", __FUNCTION__, + msg->GetDescriptor()->name()); + goto _error_exit; + } + + portConfig = msg; + + // check for "required" param + if (!portConfig.has_port_id()) + { + qDebug("%s: invalid Message Descriptor (%s)", __FUNCTION__, + msg->GetDescriptor()->name()); + goto _error_exit; + } +#endif } void Port::insertDummyStreams() @@ -24,3 +89,4 @@ void Port::insertDummyStreams() #endif } + diff --git a/client/port.h b/client/port.h index 13795ff..f308b3b 100644 --- a/client/port.h +++ b/client/port.h @@ -6,48 +6,77 @@ #include #include "stream.h" +class StreamModel; + class Port { - - friend class StreamModel; + +#if 0 // PB friend class PortStatsModel; +#endif + friend class StreamModel; + + //friend class PbHelper; + + // FIXME: non-friend mechanism + //friend QList* StreamModel::currentPortStreamList(void); + +private: + OstProto::PortConfig d; + + quint32 mPortId; + quint32 mPortGroupId; + QString mUserAlias; // user defined + + QList mStreams; + +#if 0 // PB + quint32 mPortId; + QString mName; + QString mDescription; + AdminStatus mAdminStatus; + OperStatus mOperStatus; + ControlMode mControlMode; + + quint32 mPortStats[10]; // FIXME(HI):Hardcoding +#endif public: enum AdminStatus { AdminDisable, AdminEnable }; enum OperStatus { OperDown, OperUp }; enum ControlMode { ControlShared, ControlExclusive }; -private: - quint32 mPortId; - quint32 mPortGroupId; - QList mStreams; - QString mName; - QString mDescription; - QString mUserAlias; // user defined - AdminStatus mAdminStatus; - OperStatus mOperStatus; - ControlMode mControlMode; - - quint32 mPortStats[10]; // FIXME(HI):Hardcoding - -public: // FIXME(HIGH): default args is a hack for QList operations on Port Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF); - quint32 id() const { return mPortId; } quint32 portGroupId() const { return mPortGroupId; } - const QString& name() const { return mName; } - const QString& description() const { return mDescription; } const QString& userAlias() const { return mUserAlias; } - void setName(QString &name) { mName = name; } + quint32 id() const + { return d.port_id(); } + const QString name() const + { return QString().fromStdString(d.name()); } + const QString description() const + { return QString().fromStdString(d.description()); } + AdminStatus adminStatus() + { return (d.is_enabled()?AdminEnable:AdminDisable); } + OperStatus operStatus() + { return (d.is_oper_up()?OperUp:OperDown); } + ControlMode controlMode() + { return (d.is_exclusive_control()?ControlExclusive:ControlShared); } + +#if 0 + void setName(QString &name) { d.name; } void setName(const char* name) { mName = QString(name); } void setDescription(QString &description) { mDescription = description; } void setDescription(const char *description) { mDescription = QString(description); } - +#endif //void setAdminEnable(AdminStatus status) { mAdminStatus = status; } void setAlias(QString &alias) { mUserAlias = alias; } //void setExclusive(bool flag); + + void updatePortConfig(OstProto::PortConfig *portConfig); + // FIXME(HIGH): Only for testing void insertDummyStreams(); }; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index e8a7dfe..fa5fa0e 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -1,6 +1,8 @@ #include "portgroup.h" #include "../common/protocol.h" +#include + quint32 PortGroup::mPortGroupAllocId = 0; PortGroup::PortGroup(QHostAddress ip, quint16 port) @@ -8,48 +10,67 @@ PortGroup::PortGroup(QHostAddress ip, quint16 port) // Allocate an id for self mPortGroupId = PortGroup::mPortGroupAllocId++; +#if 0 // PB // Init attributes for which we values were passed to us mServerAddress = ip; mServerPort = port; // Init remaining attributes with defaults mpSocket = new QTcpSocket(this); +#endif + rpcChannel = new PbRpcChannel(ip, port); + rpcController = new PbRpcController(); + serviceStub = new OstProto::OstService::Stub(rpcChannel, + OstProto::OstService::STUB_OWNS_CHANNEL); + +#if 0 // PB // TODO: consider using QT's signal-slot autoconnect connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(on_mpSocket_stateChanged())); connect(mpSocket, SIGNAL(connected()), this, SLOT(when_connected())); connect(mpSocket, SIGNAL(disconnected()), this, SLOT(when_disconnected())); connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(when_error(QAbstractSocket::SocketError))); connect(mpSocket, SIGNAL(readyRead()), this, SLOT(when_dataAvail())); +#endif + // FIXME:Can't for my life figure out why this ain't working! + //QMetaObject::connectSlotsByName(this); + connect(rpcChannel, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(on_rpcChannel_stateChanged())); + connect(rpcChannel, SIGNAL(connected()), + this, SLOT(on_rpcChannel_connected())); + connect(rpcChannel, SIGNAL(disconnected()), + this, SLOT(on_rpcChannel_disconnected())); + connect(rpcChannel, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_rpcChannel_error(QAbstractSocket::SocketError))); } PortGroup::~PortGroup() { qDebug("PortGroup Destructor"); - // Disconnect and free TCP mpSocketet etc. + // Disconnect and free rpc channel etc. PortGroup::disconnectFromHost(); - delete mpSocket; + delete serviceStub; } +#if 0 // PB void PortGroup::connectToHost(QHostAddress ip, quint16 port) { - mServerAddress = ip; - mServerPort = port; - - PortGroup::connectToHost(); + rpcChannel->establish(ip, port) } void PortGroup::connectToHost() { qDebug("PortGroup::connectToHost()"); - mpSocket->connectToHost(mServerAddress, mServerPort); + rpcChannel->establish() } void PortGroup::disconnectFromHost() { mpSocket->disconnectFromHost(); } +#endif +#if 0 // PB // -------------------------------------------- // Private Methods // -------------------------------------------- @@ -116,22 +137,32 @@ _next: return; } +#endif // ------------------------------------------------ // Slots // ------------------------------------------------ -void PortGroup::on_mpSocket_stateChanged() +void PortGroup::on_rpcChannel_stateChanged() { qDebug("state changed"); emit portGroupDataChanged(this); } -void PortGroup::when_connected() +void PortGroup::on_rpcChannel_connected() { - qDebug("connected\n"); + OstProto::Void void_; + OstProto::PortIdList *portIdList; + qDebug("connected\n"); emit portGroupDataChanged(this); + qDebug("requesting portlist ..."); + portIdList = new OstProto::PortIdList(); + rpcController->Reset(); + serviceStub->getPortIdList(rpcController, &void_, portIdList, + NewCallback(this, &PortGroup::processPortIdList, portIdList)); + +#if 0 // PB // Ask for Port Capability tCommHdr pkt; pkt.ver = 1; @@ -141,9 +172,10 @@ void PortGroup::when_connected() pkt.msgLen = HTONS(8); mpSocket->write((char*) &pkt, sizeof(pkt)); +#endif } -void PortGroup::when_disconnected() +void PortGroup::on_rpcChannel_disconnected() { qDebug("disconnected\n"); emit portListAboutToBeChanged(mPortGroupId); @@ -152,12 +184,13 @@ void PortGroup::when_disconnected() emit portGroupDataChanged(this); } -void PortGroup::when_error(QAbstractSocket::SocketError socketError) +void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) { qDebug("error\n"); emit portGroupDataChanged(this); } +#if 0 // PB void PortGroup::when_dataAvail() { qDebug("dataAvail\n"); @@ -165,5 +198,91 @@ void PortGroup::when_dataAvail() QByteArray msg = mpSocket->read(1024); // FIXME: hardcoding ProcessMsg(msg.constData(), msg.size()); } +#endif +void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) +{ + int count; + qDebug("got a portlist ..."); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } + + count = portIdList->port_id_size(); + qDebug("%s: portid count = %d", __FUNCTION__, count); + qDebug("%s: %s", __FUNCTION__, portIdList->DebugString().c_str()); + + emit portListAboutToBeChanged(mPortGroupId); + + for(int i = 0; i < count; i++) + { + Port *p; + + p = new Port(portIdList->port_id(i), mPortGroupId); + //p->setName("name"); + //p->setDescription("Desc"); + p->insertDummyStreams(); // FIXME: only for testing + qDebug("before port append\n"); + mPorts.append(*p); + } + + emit portListChanged(mPortGroupId); + + // Request PortConfigList + { + OstProto::PortConfigList *portConfigList; + + qDebug("requesting port config list ..."); + portConfigList = new OstProto::PortConfigList(); + rpcController->Reset(); + serviceStub->getPortConfig(rpcController, + portIdList, portConfigList, NewCallback(this, + &PortGroup::processPortConfigList, portConfigList)); + } + + goto _exit; + +_error_exit: +_exit: + delete portIdList; +} + +void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) +{ + int count; + + qDebug("In %s", __FUNCTION__); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } + + count = portConfigList->list_size(); + qDebug("%s: count = %d", __FUNCTION__, count); + qDebug("%s: <%s>", __FUNCTION__, portConfigList->DebugString().c_str()); + + emit portListAboutToBeChanged(mPortGroupId); + + for(int i = 0; i < count; i++) + { + uint id; + + id = portConfigList->list(i).port_id(); + // FIXME: don't mix port id & index into mPorts[] + mPorts[id].updatePortConfig(portConfigList->mutable_list(i)); + } + + emit portListChanged(mPortGroupId); + + // FIXME: check if we need new signals since we are not changing the + // number of ports, just the port data + +_error_exit: + delete portConfigList; +} diff --git a/client/portgroup.h b/client/portgroup.h index 8f5c1e3..528f48b 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -5,6 +5,9 @@ #include #include +#include "../common/protocol.pb.h" +#include "pbrpcchannel.h" + /* TODO HIGH MED @@ -21,10 +24,14 @@ private: quint32 mPortGroupId; static quint32 mPortGroupAllocId; QString mUserAlias; // user defined - +#if 0 // PB QTcpSocket *mpSocket; QHostAddress mServerAddress; quint16 mServerPort; +#endif + PbRpcChannel *rpcChannel; + ::google::protobuf::RpcController *rpcController; + OstProto::OstService::Stub *serviceStub; public: // FIXME(HIGH): member access QList mPorts; @@ -33,34 +40,46 @@ public: quint16 port = DEFAULT_SERVER_PORT); ~PortGroup(); - void connectToHost(); - void connectToHost(QHostAddress ip, quint16 port); - void disconnectFromHost(); + void connectToHost() { rpcChannel->establish(); } + void connectToHost(QHostAddress ip, quint16 port) + { rpcChannel->establish(ip, port); } + void disconnectFromHost() { rpcChannel->tearDown(); } int numPorts() const { return mPorts.size(); } quint32 id() const { return mPortGroupId; } - const QHostAddress& serverAddress() const { return mServerAddress; } - quint16 serverPort() const { return mServerPort; } - const QString& userAlias() const { return mUserAlias; } - QAbstractSocket::SocketState state() const { return mpSocket->state(); } + const QString& userAlias() const { return mUserAlias; } void setUserAlias(QString alias) { mUserAlias = alias; }; + const QHostAddress& serverAddress() const + { return rpcChannel->serverAddress(); } + quint16 serverPort() const + { return rpcChannel->serverPort(); } + QAbstractSocket::SocketState state() const + { return rpcChannel->state(); } + + void processPortIdList(OstProto::PortIdList *portIdList); + void processPortConfigList(OstProto::PortConfigList *portConfigList); + signals: void portGroupDataChanged(PortGroup* portGroup); void portListAboutToBeChanged(quint32 portGroupId); void portListChanged(quint32 portGroupId); private slots: - void on_mpSocket_stateChanged(); - void when_connected(); - void when_disconnected(); - void when_error(QAbstractSocket::SocketError socketError); - void when_dataAvail(); + void on_rpcChannel_stateChanged(); + void on_rpcChannel_connected(); + void on_rpcChannel_disconnected(); + void on_rpcChannel_error(QAbstractSocket::SocketError socketError); +#if 0 // PB + void on_rpcChannel_when_dataAvail(); +#endif private: +#if 0 // PB void ProcessCapabilityInfo(const char *msg, qint32 size); void ProcessMsg(const char *msg, quint32 size); +#endif }; #endif diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index c67c7e4..435344c 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -70,7 +70,11 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const // Check role if (role == Qt::DisplayRole) + { +#if 0 // PB return pgl->mPortGroups.at(pgidx)->mPorts.at(pidx).mPortStats[index.row()]; +#endif return 0; //FIXME: Get actual port stats + } else return QVariant(); diff --git a/client/portswindow.cpp b/client/portswindow.cpp index c316b0d..2e6df17 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -1,5 +1,4 @@ #include "portswindow.h" -#include "streamlistmodel.h" #include "streamconfigdialog.h" #include #include diff --git a/client/stream.cpp b/client/stream.cpp index 980d26c..e153b8e 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -1,15 +1,25 @@ #include +quint32 Stream::mAllocId = 0; + Stream::Stream() { + mId = mAllocId++; + + mCore = new OstProto::StreamCore; + mMac = new MacProtocol; + mIp = new IpProtocol; +#if 0 // Default constructor InitDefaultMeta(); InitDefaultProto(); InitDefaultL2(); InitDefaultL3(); InitDefaultL4(); +#endif } +#if 0 void Stream::InitDefaultMeta() { // TODO(LOW): Use #defines @@ -121,3 +131,4 @@ void Stream::InitDefaultL4Udp() l4.udp.totLen = STREAM_DEF_L4_UDP_TOT_LEN; l4.udp.cksum = STREAM_DEF_L4_UDP_CKSUM; } +#endif diff --git a/client/stream.h b/client/stream.h index 4469065..4b134cb 100644 --- a/client/stream.h +++ b/client/stream.h @@ -3,17 +3,547 @@ #include #include +#include "../common/protocol.pb.h" class StreamConfigDialog; class StreamModel; class PacketModel; +// Convenience Defines FIXME +#define IP_PROTO_ICMP 0x01 +#define IP_PROTO_IGMP 0x02 +#define IP_PROTO_TCP 0x06 +#define IP_PROTO_UDP 0x11 + +#if 0 + // Protocols + struct { + FrameType ft; + + + + quint16 protoMask; +#define PM_L3_PROTO_NONE 0x0001 +#define PM_L3_PROTO_OTHER 0x0002 +#define PM_L4_PROTO_NONE 0x0004 +#define PM_L4_PROTO_OTHER 0x0008 + + quint16 etherType; +#define ETH_TYP_IP 0x0800 +#define ETH_TYP_ARP 0x0806 + + quint16 ipProto; +#define IP_PROTO_ICMP 0x01 +#define IP_PROTO_IGMP 0x02 +#define IP_PROTO_TCP 0x06 +#define IP_PROTO_UDP 0x11 + } proto; + + // L2 + struct { + // Ethernet + + + + + } eth; + } l2; +#endif + +class AbstractProtocol +{ + // TODO +}; + +class MacProtocol : public AbstractProtocol +{ +private: + OstProto::Mac d; + +public: + enum MacAddrMode { + MacAddrFixed, + MacAddrInc, + MacAddrDec + }; + + // Dst Mac + quint64 dstMac() + { return d.dst_mac(); } + + bool setDstMac(quint64 dstMac) + { d.set_dst_mac(dstMac); return true; } + + MacAddrMode dstMacMode() + { return (MacAddrMode) d.dst_mac_mode(); } + bool setDstMacMode(MacAddrMode dstMacMode) + { d.set_dst_mac_mode((OstProto::Mac::MacAddrMode)dstMacMode); return true; } + + quint16 dstMacCount() + { return d.dst_mac_count(); } + bool setDstMacCount(quint16 dstMacCount) + { d.set_dst_mac_count(dstMacCount); return true; } + + quint16 dstMacStep() + { return d.dst_mac_step(); } + bool setDstMacStep(quint16 dstMacStep) + { d.set_dst_mac_step(dstMacStep); return true; } + + // Src Mac + quint64 srcMac() + { return d.src_mac(); } + + bool setSrcMac(quint64 srcMac) + { d.set_src_mac(srcMac); return true; } + + MacAddrMode srcMacMode() + { return (MacAddrMode) d.src_mac_mode(); } + bool setSrcMacMode(MacAddrMode srcMacMode) + { d.set_src_mac_mode((OstProto::Mac::MacAddrMode)srcMacMode); return true; } + + quint16 srcMacCount() + { return d.src_mac_count(); } + bool setSrcMacCount(quint16 srcMacCount) + { d.set_src_mac_count(srcMacCount); return true; } + + quint16 srcMacStep() + { return d.src_mac_step(); } + bool setSrcMacStep(quint16 srcMacStep) + { d.set_src_mac_step(srcMacStep); return true; } +}; + +class LlcProtocol : public AbstractProtocol +{ +private: + OstProto::Llc d; + +public: + quint8 dsap() + { return d.dsap(); } + bool setDsap(quint8 dsap) + { d.set_dsap(dsap); return true; } + + quint8 ssap() + { return d.ssap(); } + bool setSsap(quint8 ssap) + { d.set_ssap(ssap); return true; } + + quint8 ctl() + { return d.ctl(); } + bool setCtl(quint8 ctl) + { d.set_ctl(ctl); return true; } + +}; + +class SnapProtocol : public AbstractProtocol +{ +private: + OstProto::Snap d; + +public: + quint32 oui() + { return d.oui(); } + bool setOui(quint32 oui) + { d.set_oui(oui); return true; } + + quint16 type() + { return d.type(); } + bool setType(quint16 type) + { d.set_type(type); return true; } +}; + +class Eth2Protocol : public AbstractProtocol +{ +private: + OstProto::Eth2 d; + +public: + quint16 type() + { return d.type(); } + bool setType(quint16 type) + { d.set_type(type); return true; } +}; + +class VlanProtocol : public AbstractProtocol +{ +// TODO +#if 0 + quint16 vlanMask; +#define VM_UNTAGGED 0x0000 +#define VM_CVLAN_TAGGED 0x0001 +#define VM_CVLAN_TPID_OVERRIDE 0x0002 +#define VM_SVLAN_TAGGED 0x0100 +#define VM_SVLAN_TPID_OVERRIDE 0x0200 + +#define VM_SINGLE_TAGGED(mask) \ +((mask & VM_CVLAN_TAGGED ) | (mask & VM_SVLAN_TAGGED)) +#define VM_DOUBLE_TAGGED(mask) \ +(mask & (VM_CVLAN_TAGGED | VM_SVLAN_TAGGED)) + + quint16 ctpid; + quint16 cvlanPrio : 3; + quint16 cvlanCfi : 1; + quint16 cvlanId : 13; + quint16 stpid; + quint16 svlanPrio : 3; + quint16 svlanCfi : 1; + quint16 svlanId : 13; +#endif +}; + +// IP +class IpProtocol : public AbstractProtocol +{ +private: + OstProto::Ip d; + +public: + + enum IpAddrMode { + IpAddrFixed, + IpAddrIncHost, + IpAddrDecHost, + IpAddrRandomHost + }; + + enum IpFlag { + IpOverrideVersion = 0x01, + IpOverrideHdrLen = 0x02, + IpOverrideTotLen = 0x03, + IpOverrideCksum = 0x04 + }; + Q_DECLARE_FLAGS(IpFlags, IpFlag); + + IpFlags ipFlags() + { + IpFlags f; + + if (d.is_override_ver()) f|= IpOverrideVersion; + if (d.is_override_hdrlen()) f|= IpOverrideHdrLen; + if (d.is_override_totlen()) f|= IpOverrideTotLen; + if (d.is_override_cksum()) f|= IpOverrideCksum; + + return f; + } + + bool setIpFlags(IpFlags ipFlags) + { + if (ipFlags.testFlag(IpOverrideVersion)) + d.set_is_override_ver(true); + else + d.set_is_override_ver(false); + + if (ipFlags.testFlag(IpOverrideHdrLen)) + d.set_is_override_hdrlen(true); + else + d.set_is_override_hdrlen(false); + + if (ipFlags.testFlag(IpOverrideTotLen)) + d.set_is_override_totlen(true); + else + d.set_is_override_totlen(false); + + if (ipFlags.testFlag(IpOverrideCksum)) + d.set_is_override_cksum(true); + else + d.set_is_override_cksum(false); + + return true; + } + + quint8 ver() + { return (d.ver_hdrlen() >> 4); } + bool setVer(quint8 ver) + { d.set_ver_hdrlen((d.ver_hdrlen() & 0x0F) | (ver << 4)); return true; } + + quint8 hdrLen() + { return (d.ver_hdrlen() & 0xF); } + bool setHdrLen(quint8 hdrLen) + { d.set_ver_hdrlen((d.ver_hdrlen() & 0xF0) | hdrLen); return true; } + + quint8 tos() + { return d.tos(); } + bool setTos(quint8 tos) + { d.set_tos(tos); return true; } + + quint16 totLen() + { return d.tot_len(); } + bool setTotLen(quint16 totLen) + { d.set_tot_len(totLen); return true; } + + quint16 id() + { return d.id(); } + bool setId(quint16 id) + { d.set_id(id); return true; } + + quint16 flags() + { return d.flags(); } + bool setFlags(quint16 flags) + { d.set_flags(flags); return true; } +#define IP_FLAG_UNUSED 0x1 +#define IP_FLAG_DF 0x2 +#define IP_FLAG_MF 0x4 + + quint16 fragOfs() + { return d.frag_ofs(); } + bool setFragOfs(quint16 fragOfs) + { d.set_frag_ofs(fragOfs); return true; } + + quint8 ttl() + { return d.ttl(); } + bool setTtl(quint8 ttl) + { d.set_ttl(ttl); return true; } + + quint8 proto() + { return d.proto(); } + bool setProto(quint8 proto) + { d.set_proto(proto); return true; } + + quint16 cksum() + { return d.cksum(); } + bool setCksum(quint16 cksum) + { d.set_cksum(cksum); return true; } + + // Source IP + quint32 srcIp() + { return d.src_ip(); } + bool setSrcIp(quint32 srcIp) + { d.set_src_ip(srcIp); return true; } + + IpAddrMode srcIpMode() + { return (IpAddrMode) d.src_ip_mode(); } + bool setSrcIpMode(IpAddrMode srcIpMode) + { d.set_src_ip_mode((OstProto::Ip::IpAddrMode)srcIpMode); return true; } + + quint16 srcIpCount() + { return d.src_ip_count(); } + bool setSrcIpCount(quint16 srcIpCount) + { d.set_src_ip_count(srcIpCount); return true; } + + quint32 srcIpMask() + { return d.src_ip_mask(); } + bool setSrcIpMask(quint32 srcIpMask) + { d.set_src_ip_mask(srcIpMask); return true; } + + // Destination IP + quint32 dstIp() + { return d.dst_ip(); } + bool setDstIp(quint32 dstIp) + { d.set_dst_ip(dstIp); return true; } + + IpAddrMode dstIpMode() + { return (IpAddrMode) d.dst_ip_mode(); } + bool setDstIpMode(IpAddrMode dstIpMode) + { d.set_dst_ip_mode((OstProto::Ip::IpAddrMode)dstIpMode); return true; } + + quint16 dstIpCount() + { return d.dst_ip_count(); } + bool setDstIpCount(quint16 dstIpCount) + { d.set_dst_ip_count(dstIpCount); return true; } + + quint32 dstIpMask() + { return d.dst_ip_mask(); } + bool setDstIpMask(quint32 dstIpMask) + { d.set_dst_ip_mask(dstIpMask); return true; } + + // TODO: Options +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(IpProtocol::IpFlags) + +class ArpProtocol: public AbstractProtocol +{ + // TODO: ARP +}; + +// TCP +class TcpProtocol : public AbstractProtocol +{ +private: + OstProto::Tcp d; + +public: + enum TcpFlag + { + TcpOverrideHdrLen = 0x01, + TcpOverrideCksum = 0x02 + }; + Q_DECLARE_FLAGS(TcpFlags, TcpFlag); + + TcpFlags tcpFlags() + { + TcpFlags f; + + if (d.is_override_hdrlen()) f|= TcpOverrideHdrLen; + if (d.is_override_cksum()) f|= TcpOverrideCksum; + + return f; + } + + bool setTcpFlags(TcpFlags tcpFlags) + { + if (tcpFlags.testFlag(TcpOverrideHdrLen)) + d.set_is_override_hdrlen(true); + else + d.set_is_override_hdrlen(false); + + if (tcpFlags.testFlag(TcpOverrideCksum)) + d.set_is_override_cksum(true); + else + d.set_is_override_cksum(false); + + return true; + } + + quint16 srcPort() + { return d.src_port(); } + bool setSrcPort(quint16 srcPort) + { d.set_src_port(srcPort); return true; } + + quint16 dstPort() + { return d.dst_port(); } + bool setdstPort(quint16 dstPort) + { d.set_dst_port(dstPort); return true; } + + quint32 seqNum() + { return d.seq_num(); } + bool setSeqNum(quint32 seqNum) + { d.set_seq_num(seqNum); return true;} + + quint32 ackNum() + { return d.ack_num(); } + bool setAckNum(quint32 ackNum) + { d.set_ack_num(ackNum); return true;} + + quint8 hdrLen() + { return (d.hdrlen_rsvd() >> 4); } + bool setHdrLen(quint8 hdrLen) + { d.set_hdrlen_rsvd((d.hdrlen_rsvd() & 0x0F) | (hdrLen << 4)); return true; } + + quint8 rsvd() + { return (d.hdrlen_rsvd() & 0xF); } + bool setRsvd(quint8 rsvd) + { d.set_hdrlen_rsvd((d.hdrlen_rsvd() & 0xF0) | rsvd); return true; } + + + // TODO: convert to enum maybe? + quint8 flags() + { return d.flags(); } + bool setFlags(quint8 flags) + { d.set_flags(flags); return true; } +#define TCP_FLAG_URG 0x01 +#define TCP_FLAG_ACK 0x02 +#define TCP_FLAG_PSH 0x04 +#define TCP_FLAG_RST 0x08 +#define TCP_FLAG_SYN 0x10 +#define TCP_FLAG_FIN 0x20 + + quint16 window() + { return d.window(); } + bool setWindow(quint16 window) + { d.set_window(window); return true; } + + quint16 cksum() + { return d.cksum(); } + bool setCksum(quint16 cksum) + { d.set_cksum(cksum); return true; } + + quint16 urg_ptr() + { return d.urg_ptr(); } + bool seturg_ptr(quint16 urg_ptr) + { d.set_urg_ptr(urg_ptr); return true; } + +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(TcpProtocol::TcpFlags) + + +// UDP +class UdpProtocol : public AbstractProtocol +{ +private: + OstProto::Udp d; + +public: + enum UdpFlag + { + UdpOverrideTotLen = 0x01, + UdpOverrideCksum = 0x02 + }; + Q_DECLARE_FLAGS(UdpFlags, UdpFlag); + + UdpFlags udpFlags() + { + UdpFlags f; + + if (d.is_override_totlen()) f|= UdpOverrideTotLen; + if (d.is_override_cksum()) f|= UdpOverrideCksum; + + return f; + } + + bool setUdpFlags(UdpFlags udpFlags) + { + if (udpFlags.testFlag(UdpOverrideTotLen)) + d.set_is_override_totlen(true); + else + d.set_is_override_totlen(false); + + if (udpFlags.testFlag(UdpOverrideCksum)) + d.set_is_override_cksum(true); + else + d.set_is_override_cksum(false); + + return true; + } + + quint16 srcPort() + { return d.src_port(); } + bool setSrcPort(quint16 srcPort) + { d.set_src_port(srcPort); return true; } + + quint16 dstPort() + { return d.dst_port(); } + bool setdstPort(quint16 dstPort) + { d.set_dst_port(dstPort); return true; } + + quint16 totLen() + { return d.totlen(); } + bool setTotLen(quint16 totLen) + { d.set_totlen(totLen); return true; } + + quint16 cksum() + { return d.cksum(); } + bool setCksum(quint16 cksum) + { d.set_cksum(cksum); return true; } + +}; + +class IcmpProtocol { +// TODO: ICMP +}; + +class IgmpProtocol { +// TODO: IGMP +}; + + class Stream { + static quint32 mAllocId; + + quint32 mId; + OstProto::StreamCore *mCore; + + MacProtocol *mMac; + IpProtocol *mIp; + +#if 0 friend class StreamConfigDialog; friend class StreamModel; friend class PacketModel; +#endif +public: enum FrameType { e_ft_none, e_ft_eth_2, @@ -36,273 +566,78 @@ class Stream { e_fl_random }; - enum MacAddrMode { - e_mm_fixed, - e_mm_inc, - e_mm_dec, - }; - - enum IpAddrMode { - e_im_fixed, - e_im_inc_host, - e_im_dec_host, - e_im_random_host - }; - - // Meta Data - struct { - // Data Pattern - DataPatternMode patternMode; - quint32 pattern; - quint16 dataStartOfs; - - // Frame Length (includes CRC) - FrameLengthMode lenMode; - quint16 frameLen; - quint16 frameLenMin; - quint16 frameLenMax; - } meta; - - // Protocols - struct { - FrameType ft; - - quint8 dsap; - quint8 ssap; - quint8 ctl; - quint8 ouiMsb; - quint16 ouiLshw; - - quint16 protoMask; -#define PM_L3_PROTO_NONE 0x0001 -#define PM_L3_PROTO_OTHER 0x0002 -#define PM_L4_PROTO_NONE 0x0004 -#define PM_L4_PROTO_OTHER 0x0008 - - quint16 etherType; -#define ETH_TYP_IP 0x0800 -#define ETH_TYP_ARP 0x0806 - - quint16 ipProto; -#define IP_PROTO_ICMP 0x01 -#define IP_PROTO_IGMP 0x02 -#define IP_PROTO_TCP 0x06 -#define IP_PROTO_UDP 0x11 - } proto; - - // L2 - struct { - // Ethernet - struct { - // Dst Mac - quint16 dstMacMshw; - quint32 dstMacLsw; - MacAddrMode dstMacMode; - quint16 dstMacCount; - quint16 dstMacStep; - - // srcMac - quint16 srcMacMshw; - quint32 srcMacLsw; - MacAddrMode srcMacMode; - quint16 srcMacCount; - quint16 srcMacStep; - - - quint16 vlanMask; -#define VM_UNTAGGED 0x0000 -#define VM_CVLAN_TAGGED 0x0001 -#define VM_CVLAN_TPID_OVERRIDE 0x0002 -#define VM_SVLAN_TAGGED 0x0100 -#define VM_SVLAN_TPID_OVERRIDE 0x0200 - -#define VM_SINGLE_TAGGED(mask) \ - ((mask & VM_CVLAN_TAGGED ) | (mask & VM_SVLAN_TAGGED)) -#define VM_DOUBLE_TAGGED(mask) \ - (mask & (VM_CVLAN_TAGGED | VM_SVLAN_TAGGED)) - - - - quint16 ctpid; - quint16 cvlanPrio : 3; - quint16 cvlanCfi : 1; - quint16 cvlanId : 13; - quint16 stpid; - quint16 svlanPrio : 3; - quint16 svlanCfi : 1; - quint16 svlanId : 13; - } eth; - } l2; - - struct { - // IP - struct { - quint8 ipMask; -#define IM_OVERRIDE_VERSION 0x01 -#define IM_OVERRIDE_HDRLEN 0x02 -#define IM_OVERRIDE_TOTLEN 0x04 -#define IM_OVERRIDE_CKSUM 0x08 -#define STREAM_DEF_IP_MASK 0x00 - - quint8 ver : 4; -#define STREAM_DEF_L3_IP_VER 0x4 - - quint8 hdrLen : 4; -#define STREAM_DEF_L3_IP_HDR_LEN 0x5 - - quint8 tos; -#define STREAM_DEF_L3_IP_TOS 0x00 - - quint16 totLen; -#define STREAM_DEF_L3_IP_TOT_LEN 0x00 - - quint16 id; -#define STREAM_DEF_L3_IP_ID 0x1234 - - quint16 flags : 3; -#define IP_FLAG_UNUSED 0x1 -#define IP_FLAG_DF 0x2 -#define IP_FLAG_MF 0x4 -#define STREAM_DEF_L3_IP_FLAGS 0x00 - - quint16 fragOfs : 13; -#define STREAM_DEF_L3_IP_FRAG_OFS 0x0000 - - quint8 ttl; -#define STREAM_DEF_L3_IP_TTL 0x7F - - quint8 proto; -#define STREAM_DEF_L3_IP_PROTO 0x00 - - quint16 cksum; -#define STREAM_DEF_L3_IP_CKSUM 0x0000 - - // Source IP - quint32 srcIp; -#define STREAM_DEF_L3_IP_SRC_IP 0x02020202 - - IpAddrMode srcIpMode; -#define STREAM_DEF_L3_IP_SRC_IP_MODE e_im_fixed - - quint16 srcIpCount; -#define STREAM_DEF_L3_IP_SRC_IP_COUNT 16 - - quint32 srcIpMask; -#define STREAM_DEF_L3_IP_SRC_IP_MASK 0xFFFFFFFF - - // Destination IP - quint32 dstIp; -#define STREAM_DEF_L3_IP_DST_IP 0x01010101 - - IpAddrMode dstIpMode; -#define STREAM_DEF_L3_IP_DST_IP_MODE e_im_fixed - - quint16 dstIpCount; -#define STREAM_DEF_L3_IP_DST_IP_COUNT 16 - - quint32 dstIpMask; -#define STREAM_DEF_L3_IP_DST_IP_MASK 0xFFFFFFFF - - // TODO: Options - } ip; - - // TODO: ARP - struct { - } arp; - } l3; - - // L4 - struct { - // TCP - struct { - quint32 tcpMask; -#define TM_OVERRIDE_HDRLEN 0x1 -#define TM_OVERRIDE_CKSUM 0x2 -#define STREAM_DEF_L4_TCP_TCP_MASK 0x00; - - quint16 srcPort; -#define STREAM_DEF_L4_TCP_SRC_PORT 8902; - - quint16 dstPort; -#define STREAM_DEF_L4_TCP_DST_PORT 80 - - quint32 seqNum; -#define STREAM_DEF_L4_TCP_SEQ_NUM 129018 - - quint32 ackNum; -#define STREAM_DEF_L4_TCP_ACK_NUM 98223 - - quint8 hdrLen : 4; -#define STREAM_DEF_L4_TCP_HDR_LEN 0x5 - - quint8 rsvd : 4; -#define STREAM_DEF_L4_TCP_RSVD 0x0 - - quint8 flags; -#define TCP_FLAG_URG 0x01 -#define TCP_FLAG_ACK 0x02 -#define TCP_FLAG_PSH 0x04 -#define TCP_FLAG_RST 0x08 -#define TCP_FLAG_SYN 0x10 -#define TCP_FLAG_FIN 0x20 -#define STREAM_DEF_L4_TCP_FLAGS 0x00 - - - quint16 window; -#define STREAM_DEF_L4_TCP_WINDOW 1024 - - quint16 cksum; -#define STREAM_DEF_L4_TCP_CKSUM 0x0000 - - quint16 urgPtr; -#define STREAM_DEF_L4_TCP_URG_PTR 0x0000 - } tcp; - - // UDP - struct { - quint32 udpMask; -#define UM_OVERRIDE_TOTLEN 0x01 -#define UM_OVERRIDE_CKSUM 0x02 -#define STREAM_DEF_L4_UDP_UDP_MASK 0x00 - - quint16 srcPort; -#define STREAM_DEF_L4_UDP_SRC_PORT 8902 - - quint16 dstPort; -#define STREAM_DEF_L4_UDP_DST_PORT 80 - - quint16 totLen; -#define STREAM_DEF_L4_UDP_TOT_LEN 0x0000 - - quint16 cksum; -#define STREAM_DEF_L4_UDP_CKSUM 0x0000 - } udp; - - // TODO: ICMP - struct { - } icmp; - - // TODO: IGMP - struct { - } igmp; - } l4; - - QString mName; - bool mIsEnabled; - -// ------------------------------------------------------- -// Methods -// ------------------------------------------------------- -public: + // ------------------------------------------------------- + // Methods + // ------------------------------------------------------- Stream(); - int enable(bool flag); - const QString& name() const { return mName; } - bool isEnabled() const { return mIsEnabled; } - void setName(QString name) { mName = name; } - void setEnabled(bool isEnabled) { mIsEnabled = isEnabled; } + quint32 id() + { return mId;} + + quint32 ordinal() + { return mCore->ordinal();} + bool setOrderdinal(quint32 ordinal) + { mCore->set_ordinal(ordinal); return true; } + + bool isEnabled() const + { return mCore->is_enabled(); } + bool setIsEnabled(bool flag) + { mCore->set_is_enabled(flag); return true; } + + const QString name() const + { return QString().fromStdString(mCore->name()); } + bool setName(QString name) + { mCore->set_name(name.toStdString()); return true; } + + FrameType frameType() + { return (FrameType) mCore->ft(); } + bool setFrameType(FrameType frameType) + { mCore->set_ft((OstProto::StreamCore::FrameType) frameType); return true; } + + // Data Pattern + DataPatternMode patternMode() + { return (DataPatternMode) mCore->pattern_mode(); } + bool setPatternMode(DataPatternMode patternMode) + { mCore->set_pattern_mode( + (OstProto::StreamCore::DataPatternMode) patternMode); return true; } + + quint32 pattern() + { return mCore->pattern(); } + bool setPattern(quint32 pattern) + { mCore->set_pattern(pattern); return true; } + + // Frame Length (includes CRC) + FrameLengthMode lenMode() + { return (FrameLengthMode) mCore->len_mode(); } + bool setLenMode(FrameLengthMode lenMode) + { mCore->set_len_mode( + (OstProto::StreamCore::FrameLengthMode) lenMode); return true; } + + quint16 frameLen() + { return mCore->frame_len(); } + bool setFrameLen(quint16 frameLen) + { mCore->set_frame_len(frameLen); return true; } + + quint16 frameLenMin() + { return mCore->frame_len_min(); } + bool setFrameLenMin(quint16 frameLenMin) + { mCore->set_frame_len_min(frameLenMin); return true; } + + quint16 frameLenMax() + { return mCore->frame_len_max(); } + bool setFrameLenMax(quint16 frameLenMax) + { mCore->set_frame_len_max(frameLenMax); return true; } + +// TODO +#if 0 + quint16 dataStartOfs; +#endif + + MacProtocol* mac() { return mMac; } + IpProtocol* ip() { return mIp; } private: +#if 0 void InitDefaultMeta(); void InitDefaultProto(); void InitDefaultL2(); @@ -311,6 +646,7 @@ private: void InitDefaultL4(); void InitDefaultL4Tcp(); void InitDefaultL4Udp(); +#endif }; #endif diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index f51c49e..8e6a8a6 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -82,9 +82,29 @@ StreamConfigDialog::~StreamConfigDialog() void StreamConfigDialog::on_cmbDstMacMode_currentIndexChanged(QString mode) { if (mode == "Fixed") + { leDstMacCount->setEnabled(FALSE); + leDstMacStep->setEnabled(FALSE); + } else + { leDstMacCount->setEnabled(TRUE); + leDstMacStep->setEnabled(TRUE); + } +} + +void StreamConfigDialog::on_cmbSrcMacMode_currentIndexChanged(QString mode) +{ + if (mode == "Fixed") + { + leSrcMacCount->setEnabled(FALSE); + leSrcMacStep->setEnabled(FALSE); + } + else + { + leSrcMacCount->setEnabled(TRUE); + leSrcMacStep->setEnabled(TRUE); + } } void StreamConfigDialog::on_pbPrev_clicked() @@ -246,7 +266,7 @@ void StreamConfigDialog::update_NumPacketsAndNumBursts() leNumBursts->setEnabled(false); } -QString & uintToHexStr(quint32 num, QString &hexStr, quint8 octets) +QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets) { int i; QChar zero('0'); @@ -291,19 +311,19 @@ void StreamConfigDialog::LoadCurrentStream() // Meta Data { - cmbPatternMode->setCurrentIndex(pStream->meta.patternMode); - lePattern->setText(uintToHexStr(pStream->meta.pattern, str, 4)); + cmbPatternMode->setCurrentIndex(pStream->patternMode()); + lePattern->setText(uintToHexStr(pStream->pattern(), str, 4)); - cmbPktLenMode->setCurrentIndex(pStream->meta.lenMode); - lePktLen->setText(str.setNum(pStream->meta.frameLen)); - lePktLenMin->setText(str.setNum(pStream->meta.frameLenMin)); - lePktLenMax->setText(str.setNum(pStream->meta.frameLenMax)); + cmbPktLenMode->setCurrentIndex(pStream->lenMode()); + lePktLen->setText(str.setNum(pStream->frameLen())); + lePktLenMin->setText(str.setNum(pStream->frameLenMin())); + lePktLenMax->setText(str.setNum(pStream->frameLenMax())); } // Protocols { - qDebug("ft = %d\n", pStream->proto.ft); - switch(pStream->proto.ft) + qDebug("ft = %d\n", pStream->frameType()); + switch(pStream->frameType()) { case Stream::e_ft_none: rbFtNone->setChecked(TRUE); @@ -321,6 +341,9 @@ void StreamConfigDialog::LoadCurrentStream() rbFtLlcSnap->setChecked(TRUE); break; } + +// TODO +#if 0 leDsap->setText(uintToHexStr(pStream->proto.dsap, str, 1)); leSsap->setText(uintToHexStr(pStream->proto.ssap, str, 1)); leControl->setText(uintToHexStr(pStream->proto.ctl, str, 1)); @@ -351,24 +374,23 @@ void StreamConfigDialog::LoadCurrentStream() // ... then for None/Other rbL4None->setChecked((pStream->proto.protoMask & PM_L4_PROTO_NONE) > 0); rbL4Other->setChecked((pStream->proto.protoMask & PM_L4_PROTO_OTHER) > 0); +#endif } // L2 { // L2 | Ethernet { - leDstMac->setText(uintToHexStr(pStream->l2.eth.dstMacMshw, str, 2) + - uintToHexStr(pStream->l2.eth.dstMacLsw, str, 4)); - cmbDstMacMode->setCurrentIndex(pStream->l2.eth.dstMacMode); - leDstMacCount->setText(str.setNum(pStream->l2.eth.dstMacCount)); - leDstMacStep->setText(str.setNum(pStream->l2.eth.dstMacStep)); + leDstMac->setText(uintToHexStr(pStream->mac()->dstMac(), str, 6)); + cmbDstMacMode->setCurrentIndex(pStream->mac()->dstMacMode()); + leDstMacCount->setText(str.setNum(pStream->mac()->dstMacCount())); + leDstMacStep->setText(str.setNum(pStream->mac()->dstMacStep())); - leSrcMac->setText(uintToHexStr(pStream->l2.eth.srcMacMshw, str, 2) + - uintToHexStr(pStream->l2.eth.srcMacLsw, str, 4)); - cmbSrcMacMode->setCurrentIndex(pStream->l2.eth.srcMacMode); - leSrcMacCount->setText(str.setNum(pStream->l2.eth.srcMacCount)); - leSrcMacStep->setText(str.setNum(pStream->l2.eth.srcMacStep)); - + leSrcMac->setText(uintToHexStr(pStream->mac()->srcMac(), str, 6)); + cmbSrcMacMode->setCurrentIndex(pStream->mac()->srcMacMode()); + leSrcMacCount->setText(str.setNum(pStream->mac()->srcMacCount())); + leSrcMacStep->setText(str.setNum(pStream->mac()->srcMacStep())); +#if 0 cmbCvlanPrio->setCurrentIndex(pStream->l2.eth.cvlanPrio); cmbCvlanCfi->setCurrentIndex(pStream->l2.eth.cvlanCfi); leCvlanId->setText(str.setNum(pStream->l2.eth.cvlanId)); @@ -382,43 +404,48 @@ void StreamConfigDialog::LoadCurrentStream() leSvlanTpid->setText(str.setNum(pStream->l2.eth.stpid)); cbSvlanTpidOverride->setChecked((pStream->l2.eth.vlanMask & VM_SVLAN_TPID_OVERRIDE) > 0); gbSvlan->setChecked((pStream->l2.eth.vlanMask & VM_SVLAN_TAGGED) > 0); +#endif } } - + // L3 { // L3 | IP { - leIpVersion->setText(str.setNum(pStream->l3.ip.ver)); - cbIpVersionOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_VERSION) > 0); - leIpHdrLen->setText(str.setNum(pStream->l3.ip.hdrLen)); - cbIpHdrLenOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_HDRLEN) > 0); + leIpVersion->setText(str.setNum(pStream->ip()->ver())); + cbIpVersionOverride->setChecked( + pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideVersion)); + leIpHdrLen->setText(str.setNum(pStream->ip()->hdrLen())); + cbIpHdrLenOverride->setChecked( + pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideHdrLen)); - leIpTos->setText(uintToHexStr(pStream->l3.ip.tos, str, 1)); + leIpTos->setText(uintToHexStr(pStream->ip()->tos(), str, 1)); - leIpLength->setText(str.setNum(pStream->l3.ip.totLen)); - cbIpLengthOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_TOTLEN) > 0); + leIpLength->setText(str.setNum(pStream->ip()->totLen())); + cbIpLengthOverride->setChecked( + pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideTotLen)); - leIpId->setText(uintToHexStr(pStream->l3.ip.id, str, 2)); - leIpFragOfs->setText(str.setNum(pStream->l3.ip.fragOfs)); - cbIpFlagsDf->setChecked((pStream->l3.ip.flags & IP_FLAG_DF) > 0); - cbIpFlagsMf->setChecked((pStream->l3.ip.flags & IP_FLAG_MF) > 0); + leIpId->setText(uintToHexStr(pStream->ip()->id(), str, 2)); + leIpFragOfs->setText(str.setNum(pStream->ip()->fragOfs())); + cbIpFlagsDf->setChecked((pStream->ip()->flags() & IP_FLAG_DF) > 0); + cbIpFlagsMf->setChecked((pStream->ip()->flags() & IP_FLAG_MF) > 0); - leIpTtl->setText(str.setNum(pStream->l3.ip.ttl)); - leIpProto->setText(uintToHexStr(pStream->l3.ip.proto, str, 1)); + leIpTtl->setText(str.setNum(pStream->ip()->ttl())); + leIpProto->setText(uintToHexStr(pStream->ip()->proto(), str, 1)); - leIpCksum->setText(uintToHexStr(pStream->l3.ip.cksum, str, 2)); - cbIpCksumOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_CKSUM) > 0); + leIpCksum->setText(uintToHexStr(pStream->ip()->cksum(), str, 2)); + cbIpCksumOverride->setChecked( + pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideCksum)); - leIpSrcAddr->setText(QHostAddress(pStream->l3.ip.srcIp).toString()); - cmbIpSrcAddrMode->setCurrentIndex(pStream->l3.ip.srcIpMode); - leIpSrcAddrCount->setText(str.setNum(pStream->l3.ip.srcIpCount)); - leIpSrcAddrMask->setText(QHostAddress(pStream->l3.ip.srcIpMask).toString()); + leIpSrcAddr->setText(QHostAddress(pStream->ip()->srcIp()).toString()); + cmbIpSrcAddrMode->setCurrentIndex(pStream->ip()->srcIpMode()); + leIpSrcAddrCount->setText(str.setNum(pStream->ip()->srcIpCount())); + leIpSrcAddrMask->setText(QHostAddress(pStream->ip()->srcIpMask()).toString()); - leIpDstAddr->setText(QHostAddress(pStream->l3.ip.dstIp).toString()); - cmbIpDstAddrMode->setCurrentIndex(pStream->l3.ip.dstIpMode); - leIpDstAddrCount->setText(str.setNum(pStream->l3.ip.dstIpCount)); - leIpDstAddrMask->setText(QHostAddress(pStream->l3.ip.dstIpMask).toString()); + leIpDstAddr->setText(QHostAddress(pStream->ip()->dstIp()).toString()); + cmbIpDstAddrMode->setCurrentIndex(pStream->ip()->dstIpMode()); + leIpDstAddrCount->setText(str.setNum(pStream->ip()->dstIpCount())); + leIpDstAddrMask->setText(QHostAddress(pStream->ip()->dstIpMask()).toString()); } // L3 | ARP @@ -427,6 +454,7 @@ void StreamConfigDialog::LoadCurrentStream() } } +#if 0 // L4 { // L4 | TCP @@ -477,6 +505,7 @@ void StreamConfigDialog::LoadCurrentStream() // TODO } } +#endif } void StreamConfigDialog::StoreCurrentStream() @@ -487,30 +516,31 @@ void StreamConfigDialog::StoreCurrentStream() qDebug("storing pStream %p", pStream); +#if 1 // FIXME: Temp till we use protobuff accessors // Meta Data - pStream->meta.patternMode = (Stream::DataPatternMode) cmbPatternMode->currentIndex(); - pStream->meta.pattern = lePattern->text().remove(QChar(' ')).toULong(&isOk, 16); - - pStream->meta.lenMode = (Stream::FrameLengthMode) cmbPktLenMode->currentIndex(); - pStream->meta.frameLen = lePktLen->text().toULong(&isOk); - pStream->meta.frameLenMin = lePktLenMin->text().toULong(&isOk); - pStream->meta.frameLenMax = lePktLenMax->text().toULong(&isOk); + pStream->setPatternMode((Stream::DataPatternMode) cmbPatternMode->currentIndex()); + pStream->setPattern(lePattern->text().remove(QChar(' ')).toULong(&isOk, 16)); + pStream->setLenMode((Stream::FrameLengthMode) cmbPktLenMode->currentIndex()); + pStream->setFrameLen(lePktLen->text().toULong(&isOk)); + pStream->setFrameLenMin(lePktLenMin->text().toULong(&isOk)); + pStream->setFrameLenMax(lePktLenMax->text().toULong(&isOk)); +#endif // Protocols { if (rbFtNone->isChecked()) - pStream->proto.ft = Stream::e_ft_none; + pStream->setFrameType(Stream::e_ft_none); else if (rbFtEthernet2->isChecked()) - pStream->proto.ft = Stream::e_ft_eth_2; + pStream->setFrameType(Stream::e_ft_eth_2); else if (rbFt802Dot3Raw->isChecked()) - pStream->proto.ft = Stream::e_ft_802_3_raw; + pStream->setFrameType(Stream::e_ft_802_3_raw); else if (rbFt802Dot3Llc->isChecked()) - pStream->proto.ft = Stream::e_ft_802_3_llc; + pStream->setFrameType(Stream::e_ft_802_3_llc); else if (rbFtLlcSnap->isChecked()) - pStream->proto.ft = Stream::e_ft_snap; - - qDebug("store ft = %d\n", pStream->proto.ft); + pStream->setFrameType(Stream::e_ft_snap); + qDebug("store ft(%d)\n", pStream->frameType()); +#if 0 pStream->proto.dsap = leDsap->text().remove(QChar(' ')).toULong(&isOk, 16); pStream->proto.ssap = leSsap->text().remove(QChar(' ')).toULong(&isOk, 16); pStream->proto.ctl = leControl->text().remove(QChar(' ')).toULong(&isOk, 16); @@ -531,24 +561,33 @@ void StreamConfigDialog::StoreCurrentStream() pStream->proto.protoMask |= PM_L4_PROTO_NONE; else if (rbL4Other->isChecked()) pStream->proto.protoMask |= PM_L4_PROTO_OTHER; +#endif } // L2 { // L2 | Ethernet { - pStream->l2.eth.dstMacMshw = leDstMac->text().remove(QChar(' ')).left(4).toULong(&isOk, 16); - pStream->l2.eth.dstMacLsw = leDstMac->text().remove(QChar(' ')).right(8).toULong(&isOk, 16); - pStream->l2.eth.dstMacMode = (Stream::MacAddrMode) cmbDstMacMode->currentIndex(); - pStream->l2.eth.dstMacCount = leDstMacCount->text().toULong(&isOk); - pStream->l2.eth.dstMacStep = leDstMacStep->text().toULong(&isOk); + pStream->mac()->setDstMac( + leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); + pStream->mac()->setDstMacMode( + (MacProtocol::MacAddrMode) cmbDstMacMode->currentIndex()); + pStream->mac()->setDstMacCount( + leDstMacCount->text().toULong(&isOk)); + pStream->mac()->setDstMacStep( + leDstMacStep->text().toULong(&isOk)); - pStream->l2.eth.srcMacMshw = leSrcMac->text().remove(QChar(' ')).left(4).toULong(&isOk, 16); - pStream->l2.eth.srcMacLsw = leSrcMac->text().remove(QChar(' ')).right(8).toULong(&isOk, 16); - pStream->l2.eth.srcMacMode = (Stream::MacAddrMode) cmbSrcMacMode->currentIndex(); - pStream->l2.eth.srcMacCount = leSrcMacCount->text().toULong(&isOk); - pStream->l2.eth.srcMacStep = leSrcMacStep->text().toULong(&isOk); + pStream->mac()->setSrcMac( + leSrcMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); + pStream->mac()->setSrcMacMode( + (MacProtocol::MacAddrMode) cmbSrcMacMode->currentIndex()); + pStream->mac()->setSrcMacCount( + leSrcMacCount->text().toULong(&isOk)); + pStream->mac()->setSrcMacStep( + leSrcMacStep->text().toULong(&isOk)); + +#if 0 pStream->l2.eth.vlanMask = 0; pStream->l2.eth.cvlanPrio = cmbCvlanPrio->currentIndex(); @@ -568,6 +607,7 @@ void StreamConfigDialog::StoreCurrentStream() pStream->l2.eth.vlanMask |= VM_SVLAN_TPID_OVERRIDE; if (gbSvlan->isChecked()) pStream->l2.eth.vlanMask |= VM_SVLAN_TAGGED; +#endif } } @@ -575,42 +615,48 @@ void StreamConfigDialog::StoreCurrentStream() { // L3 | IP { - pStream->l3.ip.ipMask = 0; + IpProtocol *ip = pStream->ip(); + IpProtocol::IpFlags f; - pStream->l3.ip.ver = leIpVersion->text().toULong(&isOk); + ip->setVer(leIpVersion->text().toULong(&isOk)); if (cbIpVersionOverride->isChecked()) - pStream->l3.ip.ipMask |= IM_OVERRIDE_VERSION; - pStream->l3.ip.hdrLen = leIpHdrLen->text().toULong(&isOk); + f |= IpProtocol::IpOverrideVersion; + ip->setHdrLen(leIpHdrLen->text().toULong(&isOk)); if (cbIpHdrLenOverride->isChecked()) - pStream->l3.ip.ipMask |= IM_OVERRIDE_HDRLEN; + f |= IpProtocol::IpOverrideHdrLen; - pStream->l3.ip.tos = leIpTos->text().toULong(&isOk, 16); + ip->setTos(leIpTos->text().toULong(&isOk, 16)); - pStream->l3.ip.totLen = leIpLength->text().toULong(&isOk); + ip->setTotLen(leIpLength->text().toULong(&isOk)); if (cbIpLengthOverride->isChecked()) - pStream->l3.ip.ipMask |= IM_OVERRIDE_TOTLEN; + f |= IpProtocol::IpOverrideHdrLen; - pStream->l3.ip.id = leIpId->text().remove(QChar(' ')).toULong(&isOk, 16); - pStream->l3.ip.fragOfs = leIpFragOfs->text().toULong(&isOk); - if (cbIpFlagsDf->isChecked()) pStream->l3.ip.ipMask |= IP_FLAG_DF; - if (cbIpFlagsMf->isChecked()) pStream->l3.ip.ipMask |= IP_FLAG_MF; + ip->setId(leIpId->text().remove(QChar(' ')).toULong(&isOk, 16)); + ip->setFragOfs(leIpFragOfs->text().toULong(&isOk)); - pStream->l3.ip.ttl = leIpTtl->text().toULong(&isOk); - pStream->l3.ip.proto = leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16); + int ff; + if (cbIpFlagsDf->isChecked()) ff |= IP_FLAG_DF; + if (cbIpFlagsMf->isChecked()) ff |= IP_FLAG_MF; + ip->setFlags(ff); + + ip->setTtl(leIpTtl->text().toULong(&isOk)); + ip->setProto(leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16)); - pStream->l3.ip.cksum = leIpCksum->text().remove(QChar(' ')).toULong(&isOk); + ip->setCksum(leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); if (cbIpCksumOverride->isChecked()) - pStream->l3.ip.ipMask |= IM_OVERRIDE_CKSUM; + f |= IpProtocol::IpOverrideCksum; - pStream->l3.ip.srcIp = QHostAddress(leIpSrcAddr->text()).toIPv4Address(); - pStream->l3.ip.srcIpMode = (Stream::IpAddrMode) cmbIpSrcAddrMode->currentIndex(); - pStream->l3.ip.srcIpCount = leIpSrcAddrCount->text().toULong(&isOk); - pStream->l3.ip.srcIpMask = QHostAddress(leIpSrcAddrMask->text()).toIPv4Address(); + ip->setSrcIp(QHostAddress(leIpSrcAddr->text()).toIPv4Address()); + ip->setSrcIpMode((IpProtocol::IpAddrMode) cmbIpSrcAddrMode->currentIndex()); + ip->setSrcIpCount(leIpSrcAddrCount->text().toULong(&isOk)); + ip->setSrcIpMask(QHostAddress(leIpSrcAddrMask->text()).toIPv4Address()); - pStream->l3.ip.dstIp = QHostAddress(leIpDstAddr->text()).toIPv4Address(); - pStream->l3.ip.dstIpMode = (Stream::IpAddrMode) cmbIpDstAddrMode->currentIndex(); - pStream->l3.ip.dstIpCount = leIpDstAddrCount->text().toULong(&isOk); - pStream->l3.ip.dstIpMask = QHostAddress(leIpDstAddrMask->text()).toIPv4Address(); + ip->setDstIp(QHostAddress(leIpDstAddr->text()).toIPv4Address()); + ip->setDstIpMode((IpProtocol::IpAddrMode) cmbIpDstAddrMode->currentIndex()); + ip->setDstIpCount(leIpDstAddrCount->text().toULong(&isOk)); + ip->setDstIpMask(QHostAddress(leIpDstAddrMask->text()).toIPv4Address()); + + ip->setIpFlags(f); } // L3 | ARP @@ -619,6 +665,8 @@ void StreamConfigDialog::StoreCurrentStream() } } +// TODO +#if 0 // L4 { // L4 | TCP @@ -676,6 +724,7 @@ void StreamConfigDialog::StoreCurrentStream() // TODO } } +#endif } void StreamConfigDialog::on_pbOk_clicked() { diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 6ccf074..1d3c99b 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -37,6 +37,7 @@ private: private slots: void on_cmbDstMacMode_currentIndexChanged(QString mode); + void on_cmbSrcMacMode_currentIndexChanged(QString mode); void on_pbPrev_clicked(); void on_pbNext_clicked(); @@ -56,7 +57,7 @@ private slots: void on_pbOk_clicked(); }; -QString & uintToHexStr(quint32 num, QString &hexStr, quint8 octets); +QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets); #endif diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 7e7efe1..a9c1ba4 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -33,7 +33,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 2 + 0 @@ -191,7 +191,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 2 + 1 @@ -2145,12 +2145,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 147 - 238 + 252 + 288 - 147 - 238 + 252 + 317 @@ -2161,12 +2161,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 147 - 238 + 252 + 388 - 147 - 238 + 252 + 417 @@ -2177,12 +2177,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 259 - 101 - 238 + 41 + 317 @@ -2193,12 +2193,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 259 - 101 - 238 + 81 + 317 @@ -2209,12 +2209,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 259 - 133 - 238 + 120 + 317 @@ -2225,12 +2225,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 259 - 147 - 238 + 252 + 288 @@ -2241,12 +2241,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 359 - 101 - 238 + 41 + 417 @@ -2257,12 +2257,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 359 - 101 - 238 + 120 + 417 @@ -2273,12 +2273,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 359 - 147 - 238 + 252 + 388 @@ -2289,12 +2289,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 359 - 101 - 238 + 81 + 417 @@ -2305,12 +2305,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 276 + 123 + 305 - 101 - 276 + 123 + 305 @@ -2321,12 +2321,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 276 + 123 + 305 - 101 - 276 + 123 + 305 @@ -2401,12 +2401,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 276 + 123 + 305 - 101 - 276 + 123 + 305 @@ -2417,12 +2417,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 276 + 123 + 305 - 101 - 276 + 123 + 305 @@ -3121,12 +3121,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 224 - 207 + 381 + 140 - 224 - 209 + 381 + 174 @@ -3137,12 +3137,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 125 - 207 + 30 + 69 - 191 - 236 + 85 + 285 @@ -3153,12 +3153,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 125 - 207 + 30 + 94 - 173 - 236 + 67 + 331 @@ -3169,12 +3169,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 125 - 207 + 30 + 94 - 224 - 216 + 222 + 189 diff --git a/client/streammodel.cpp b/client/streammodel.cpp index 21588b7..d56f4ee 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -125,7 +125,7 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r return true; break; case StreamStatus: - mCurrentPort->mStreams[index.row()].setEnabled(value.toBool()); + mCurrentPort->mStreams[index.row()].setIsEnabled(value.toBool()); return true; break; diff --git a/common/Makefile b/common/Makefile new file mode 100644 index 0000000..7c95f2b --- /dev/null +++ b/common/Makefile @@ -0,0 +1,14 @@ +RM=del +PROTOC=protoc + +#-#-# + +all: protocol.pb.cc + +protocol.pb.cc: protocol.proto + $(PROTOC) --cpp_out=. $< + +clean: + $(RM) *.pb.h *.pb.cc + +distclean: clean diff --git a/common/protocol.proto b/common/protocol.proto new file mode 100644 index 0000000..4fa777d --- /dev/null +++ b/common/protocol.proto @@ -0,0 +1,302 @@ +// stream.proto + +// FIXME: Re-evaluate Tag Values + +package OstProto; + +// Ethernet +message Mac { + + enum MacAddrMode { + e_mm_fixed = 0; + e_mm_inc = 1; + e_mm_dec = 2; + } + + // Dst Mac + optional uint64 dst_mac = 1; + optional MacAddrMode dst_mac_mode = 2 [default = e_mm_fixed]; + optional uint32 dst_mac_count = 3 [default = 16]; + optional uint32 dst_mac_step = 4 [default = 1]; + + // Src Mac + optional uint32 src_mac = 5; + optional MacAddrMode src_mac_mode = 6 [default = e_mm_fixed]; + optional uint32 src_mac_count = 7 [default = 16]; + optional uint32 src_mac_step = 8 [default = 1]; +} + +message Llc { + optional uint32 dsap = 1; + optional uint32 ssap = 2; + optional uint32 ctl = 3; +} + +message Snap { + optional uint32 oui = 1; + optional uint32 type = 2; +} + +message Eth2 { + optional uint32 type = 1; +} + +message Vlan { + // VLAN presence/absence + optional bool is_cvlan_tagged = 9; + optional bool is_ctpid_override = 10; + optional bool is_svlan_tagged = 11; + optional bool is_stpid_override = 12; + + // VLAN values + optional uint32 ctpid = 13; + optional uint32 cvlan_tag = 14; // includes prio, cfi and cvlanid + optional uint32 stpid = 15; + optional uint32 svlan_tag = 16; // includes pcp, de and svlanid +} + +// IP +message Ip { + + enum IpAddrMode { + e_im_fixed = 0; + e_im_inc_host = 1; + e_im_dec_host = 2; + e_im_random_host = 3; + } + + optional bool is_override_ver = 1; + optional bool is_override_hdrlen = 2; + optional bool is_override_totlen = 3; + optional bool is_override_cksum = 4; + + optional uint32 ver_hdrlen = 5 [default = 0x45]; + optional uint32 tos = 6; + optional uint32 tot_len = 7; + optional uint32 id = 8 [default = 1234]; + // TODO: rename flags to frag_flags + optional uint32 flags = 9; + optional uint32 frag_ofs = 10; + optional uint32 ttl = 11 [default = 127]; + optional uint32 proto = 12; + optional uint32 cksum = 13; + + // Source IP + optional fixed32 src_ip = 14; + optional IpAddrMode src_ip_mode = 15 [default = e_im_fixed]; + optional uint32 src_ip_count = 16 [default = 16]; + optional fixed32 src_ip_mask = 17 [default = 0xFFFFFFFF]; + + // Destination IP + optional fixed32 dst_ip = 18; + optional IpAddrMode dst_ip_mode = 19 [default = e_im_fixed]; + optional uint32 dst_ip_count = 20 [default = 16]; + optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFFFF]; + + // TODO: Options +} + +message Arp { +// TODO: ARP +} + +message Tcp { + + optional bool is_override_hdrlen = 1; + optional bool is_override_cksum = 2; + + optional uint32 src_port = 3 [default = 8902]; + optional uint32 dst_port = 4 [default = 80]; + + optional uint32 seq_num = 5 [default = 129018]; + optional uint32 ack_num = 6 [default = 98223]; + + optional uint32 hdrlen_rsvd = 7 [default = 0x50]; + optional uint32 flags = 8; + + optional uint32 window = 9 [default = 1024]; + optional uint32 cksum = 10; + optional uint32 urg_ptr = 11; +} + +// UDP +message Udp { + optional bool is_override_totlen = 1; + optional bool is_override_cksum = 2; + + optional uint32 src_port = 3 [default = 8902]; + optional uint32 dst_port = 4 [default = 80]; + optional uint32 totLen = 5; + optional uint32 cksum = 6; +} + +// TODO: ICMP +message Icmp { +} + +// TODO: IGMP +message Igmp { +} + + +message StreamCore { + + enum FrameType { + e_ft_none = 0; + e_ft_eth_2 = 1; + e_ft_802_3_raw = 2; + e_ft_802_3_llc = 3; + e_ft_snap = 4; + } + + enum L3Proto { + e_l3_none = 0; + e_l3_other = 1; + e_l3_ip = 2; + e_l3_arp = 3; + } + + enum L4Proto { + e_l4_none = 0; + e_l4_other = 1; + e_l4_tcp = 2; + e_l4_udp = 3; + e_l4_icmp = 4; + e_l4_igmp = 5; + } + + enum DataPatternMode { + e_dp_fixed = 0; + e_dp_inc = 1; + e_dp_dec = 2; + e_dp_random = 3; + } + + enum FrameLengthMode { + e_fl_fixed = 0; + e_fl_inc = 1; + e_fl_dec = 2; + e_fl_random = 3; + } + + // Basics + optional string name = 1; + optional bool is_enabled = 2; + optional uint32 ordinal = 3; + + // Data Pattern + optional DataPatternMode pattern_mode = 11; + optional uint32 pattern = 12; + optional uint32 data_start_ofs = 13; + + // Frame Length (includes CRC) + optional FrameLengthMode len_mode = 14; + optional uint32 frame_len = 15; + optional uint32 frame_len_min = 16; + optional uint32 frame_len_max = 17; + + // Currently Selected Protocols + optional FrameType ft = 21 [default = e_ft_none]; + optional L3Proto l3_proto = 22; + optional L4Proto l4_proto = 23; +} + +message StreamId { + required uint32 port_id = 1; + required uint32 stream_id = 2; +} + +message Stream { + + required StreamId id = 1; + optional StreamCore core = 2; + + // Protocol data - L2 + optional Mac mac = 51; + optional Llc llc = 52; + optional Snap snap = 53; + optional Eth2 eth2 = 54; + + // Protocol data - L3 + optional Ip ip = 61; + optional Arp arp = 62; + + // Protocol data - L4 + optional Tcp tcp = 71; + optional Udp udp = 72; + optional Icmp icmp = 73; + optional Igmp igmp = 74; + +} + +message Void { + // nothing! +} + +message Ack { + // TODO +} + +message PortIdList { + repeated uint32 port_id = 1; +} + +message StreamIdList { + repeated StreamId id = 1; +} + + +message PortConfig { + required uint32 port_id = 1; + optional string name = 2; + optional string description = 3; + optional bool is_enabled = 4; + optional bool is_oper_up = 5; + optional bool is_exclusive_control = 6; +} + +message PortConfigList { + repeated PortConfig list = 1; +} + +message StreamConfigList { + repeated Stream stream = 1; +} + +message CaptureBuffer { + // TODO +} + +message CaptureBufferList { + repeated CaptureBuffer list = 1; +} + +message PortStats { + // TODO +} + +message PortStatsList { + repeated PortStats list = 1; +} + +service OstService { + rpc getPortIdList(Void) returns (PortIdList); + rpc getPortConfig(PortIdList) returns (PortConfigList); + + rpc getStreamIdList(PortIdList) returns (StreamIdList); + rpc getStreamConfig(StreamIdList) returns (StreamConfigList); + rpc addStream(StreamIdList) returns (Ack); + rpc deleteStream(StreamIdList) returns (Ack); + rpc modifyStream(StreamConfigList) returns (Ack); + + rpc startTx(PortIdList) returns (Ack); + rpc stopTx(PortIdList) returns (Ack); + + rpc startCapture(PortIdList) returns (Ack); + rpc stopCapture(PortIdList) returns (Ack); + rpc getCaptureBuffer(PortIdList) returns (CaptureBufferList); + + rpc getStats(PortIdList) returns (PortStatsList); + rpc clearStats(PortIdList) returns (Ack); +} + diff --git a/rpc/pbhelper.h b/rpc/pbhelper.h new file mode 100644 index 0000000..19e3daf --- /dev/null +++ b/rpc/pbhelper.h @@ -0,0 +1,66 @@ +#ifndef _PB_HELPER_H +#define _PB_HELPER_H + +#include +#include + +#include + +class PbHelper +{ +public: + bool update( + ::google::protobuf::Message *target, + ::google::protobuf::Message *source) + { + ::google::protobuf::Message::Reflection *sourceRef; + ::google::protobuf::Message::Reflection *targetRef; + std::vector srcFieldList; + + qDebug("In %s", __FUNCTION__); + + if (source->GetDescriptor()->full_name() != + target->GetDescriptor()->full_name()) + goto _error_exit; + + sourceRef = source->GetReflection(); + targetRef = target->GetReflection(); + + sourceRef->ListFields(&srcFieldList); + for (uint i=0; i < srcFieldList.size(); i++) + { + const ::google::protobuf::FieldDescriptor *srcField, *targetField; + + srcField = srcFieldList[i]; + targetField = target->GetDescriptor()->FindFieldByName( + srcField->name()); + + switch(targetField->type()) + { + case ::google::protobuf::FieldDescriptor::TYPE_UINT32: + targetRef->SetUInt32(targetField, + sourceRef->GetUInt32(srcField)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_BOOL: + targetRef->SetBool(targetField, + sourceRef->GetBool(srcField)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_STRING: + targetRef->SetString(targetField, + sourceRef->GetString(srcField)); + break; + default: + qDebug("unhandled Field Type"); + break; + } + } + + return true; + + _error_exit: + qDebug("%s: error!", __FUNCTION__); + return false; + } + +}; +#endif diff --git a/rpc/pbrpc.pro b/rpc/pbrpc.pro new file mode 100644 index 0000000..79c0e08 --- /dev/null +++ b/rpc/pbrpc.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += qt +QT += network +DEFINES += HAVE_REMOTE +INCLUDEPATH += "c:\msys\1.0\local\include" +LIBS += -L"C:\msys\1.0\local\lib" -lprotobuf +HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h +SOURCES += rpcserver.cpp pbrpcchannel.cpp +client.path = ..\client\debug +client.files = debug\libpbrpc.a debug\pbrpc.dll +server.path = ..\server\debug +server.files = debug\libpbrpc.a debug\pbrpc.dll +INSTALLS += client server diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp new file mode 100644 index 0000000..0d6226b --- /dev/null +++ b/rpc/pbrpcchannel.cpp @@ -0,0 +1,189 @@ +#include "pbrpcchannel.h" + +//#include "../common/protocol.pb.h" + +PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) +{ + isPending = false; + pendingMethodId = -1; // don't care as long as isPending is false + + controller = NULL; + done = NULL; + response = NULL; + + mServerAddress = ip; + mServerPort = port; + mpSocket = new QTcpSocket(this); + + // FIXME: Not quite sure why this ain't working! + // QMetaObject::connectSlotsByName(this); + + connect(mpSocket, SIGNAL(connected()), + this, SLOT(on_mpSocket_connected())); + connect(mpSocket, SIGNAL(disconnected()), + this, SLOT(on_mpSocket_disconnected())); + connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(on_mpSocket_stateChanged(QAbstractSocket::SocketState))); + connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_mpSocket_error(QAbstractSocket::SocketError))); + + connect(mpSocket, SIGNAL(readyRead()), + this, SLOT(on_mpSocket_readyRead())); + +} + +PbRpcChannel::~PbRpcChannel() +{ + delete mpSocket; +} + +void PbRpcChannel::establish() +{ + qDebug("In %s", __FUNCTION__); + + mpSocket->connectToHost(mServerAddress, mServerPort); +} + +void PbRpcChannel::establish(QHostAddress ip, quint16 port) +{ + mServerAddress = ip; + mServerPort = port; + establish(); +} + +void PbRpcChannel::tearDown() +{ + qDebug("In %s", __FUNCTION__); + + mpSocket->disconnectFromHost(); +} + +void PbRpcChannel::CallMethod( + const ::google::protobuf::MethodDescriptor *method, + ::google::protobuf::RpcController *controller, + const ::google::protobuf::Message *req, + ::google::protobuf::Message *response, + ::google::protobuf::Closure* done) +{ + char msg[1024]; // FIXME: hardcoding + char *p = (char *)&msg; + int len; + + qDebug("In %s", __FUNCTION__); + + pendingMethodId = method->index(); + this->controller=controller; + this->done=done; + this->response=response; + isPending = true; + + *((quint16*)(p+0)) = HTONS(PB_MSG_TYPE_REQUEST); // type + qDebug("CLi:GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)), + PB_MSG_TYPE_REQUEST); + *((quint16*)(p+2)) = HTONS(method->index()); // method id + // (p+4) len later after serialization + *((quint16*)(p+6)) = HTONS(0); // rsvd + + // SerialData is at offset 8 + req->SerializeToArray((void*) (p+8), sizeof(msg)); + + len = req->ByteSize(); + *((quint16*)(p+4)) = HTONS(len); // len + + qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, len+8, + req->ShortDebugString().c_str()); + BUFDUMP(msg, len+8); + + mpSocket->write(msg, len + 8); +} + +void PbRpcChannel::on_mpSocket_readyRead() +{ + char msg[1024]; // FIXME: hardcoding; + char *p = (char*)&msg; + int msgLen; + quint16 type, method, len, rsvd; + PbRpcController *controller; + + qDebug("In %s", __FUNCTION__); + + msgLen = mpSocket->read(msg, sizeof(msg)); + + qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); + BUFDUMP(msg, msgLen); + + type = NTOHS(GET16(p+0)); + method = NTOHS(GET16(p+2)); + len = NTOHS(GET16(p+4)); + rsvd = NTOHS(GET16(p+6)); + + if (!isPending) + { + qDebug("not waiting for response"); + + goto _error_exit; + } + + if (type != PB_MSG_TYPE_RESPONSE) + { + qDebug("invalid msgType %d (expected = %d)", type, + PB_MSG_TYPE_RESPONSE); + + goto _error_exit; + } + + if (pendingMethodId != method) + { + qDebug("invalid method id %d (expected = %d)", method, + pendingMethodId); + + goto _error_exit; + } + + + // Serialized data starts from offset 8 + response->ParseFromArray((void*) &msg[8], len); + qDebug("client(%s): Parsed as %s", __FUNCTION__, + response->DebugString().c_str()); + + + pendingMethodId = -1; + controller = NULL; + //done = NULL; + response = NULL; + isPending = false; + + done->Run(); + + return; + +_error_exit: + qDebug("client(%s) discarding received msg", __FUNCTION__); + return; +} + +void PbRpcChannel::on_mpSocket_stateChanged( + QAbstractSocket::SocketState socketState) +{ + qDebug("In %s", __FUNCTION__); + emit stateChanged(socketState); +} + +void PbRpcChannel::on_mpSocket_connected() +{ + qDebug("In %s", __FUNCTION__); + emit connected(); +} + +void PbRpcChannel::on_mpSocket_disconnected() +{ + qDebug("In %s", __FUNCTION__); + emit disconnected(); +} + +void PbRpcChannel::on_mpSocket_error(QAbstractSocket::SocketError socketError) +{ + qDebug("In %s", __FUNCTION__); + emit error(socketError); +} + diff --git a/rpc/pbrpcchannel.h b/rpc/pbrpcchannel.h new file mode 100644 index 0000000..657b095 --- /dev/null +++ b/rpc/pbrpcchannel.h @@ -0,0 +1,74 @@ +#ifndef _PB_RPC_CHANNEL_H +#define _PB_RPC_CHANNEL_H + +#include +#include + +#include +#include +#include + +#include "pbrpccommon.h" +#include "pbrpccontroller.h" + +class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel +{ + Q_OBJECT + + // If isPending is TRUE, then controller, done, response + // and pendingMethodId correspond to the last method called by + // the service stub + bool isPending; + int pendingMethodId; + + // controller, done, response are set to the corresponding values + // passed by the stub to CallMethod(). They are reset to NULL when + // we get a response back from the server in on_mpSocket_readyRead() + // after calling done->Run(). + // + // TODO(?): change controller, done and response to references + // instead of pointers? + ::google::protobuf::RpcController *controller; + ::google::protobuf::Closure *done; + ::google::protobuf::Message *response; + + QHostAddress mServerAddress; + quint16 mServerPort; + QTcpSocket *mpSocket; + +public: + PbRpcChannel(QHostAddress ip, quint16 port); + ~PbRpcChannel(); + + void establish(); + void establish(QHostAddress ip, quint16 port); + void tearDown(); + + const QHostAddress& serverAddress() const { return mServerAddress; } + quint16 serverPort() const { return mServerPort; } + + QAbstractSocket::SocketState state() const + { return mpSocket->state(); } + + void CallMethod(const ::google::protobuf::MethodDescriptor *method, + ::google::protobuf::RpcController *controller, + const ::google::protobuf::Message *req, + ::google::protobuf::Message *response, + ::google::protobuf::Closure* done); + +signals: + void connected(); + void disconnected(); + void error(QAbstractSocket::SocketError socketError); + void stateChanged(QAbstractSocket::SocketState socketState); + +private slots: + void on_mpSocket_connected(); + void on_mpSocket_disconnected(); + void on_mpSocket_stateChanged(QAbstractSocket::SocketState socketState); + void on_mpSocket_error(QAbstractSocket::SocketError socketError); + + void on_mpSocket_readyRead(); +}; + +#endif diff --git a/rpc/pbrpccommon.h b/rpc/pbrpccommon.h new file mode 100644 index 0000000..5407602 --- /dev/null +++ b/rpc/pbrpccommon.h @@ -0,0 +1,52 @@ +#ifndef _PB_RPC_COMMON_H +#define _PB_RPC_COMMON_H + +// FIXME: check which one is right - wrong one seems to be working!!!!! +#if 0 +#define GET16(p) (quint16)( \ + (*((quint8*)(p)+0) << 8 ) \ + | (*((quint8*)(p)+1))) +#else +#define GET16(p) (quint16)( \ + (*((quint8*)(p)+1) << 8 ) \ + | (*((quint8*)(p)+0))) +#endif + +#define BYTESWAP4(x) \ + (((x & 0xFF000000) >> 24) | \ + ((x & 0x00FF0000) >> 8) | \ + ((x & 0x0000FF00) << 8) | \ + ((x & 0x000000FF) << 24)) + +#define BYTESWAP2(x) \ + (((x & 0xFF00) >> 8) | \ + ((x & 0x00FF) << 8)) + +// TODO: portability +#if 1 +#define HTONL(x) BYTESWAP4(x) +#define NTOHL(x) BYTESWAP4(x) +#define HTONS(x) BYTESWAP2(x) +#define NTOHS(x) BYTESWAP2(x) +#else +#define HTONL(x) (x) +#define NTOHL(x) (x) +#define HTONS(x) (x) +#define NTOHS(x) (x) +#endif + +// Print a HexDump +#define BUFDUMP(ptr, len) qDebug("%s", QString(QByteArray((char*)(ptr), \ + (len)).toHex()).toAscii().data()); + +/* +** RPC Header (8) +** - MSG_TYPE (2) +** - METHOD_ID (2) +** - LEN (2) [not including this header] +** - RSVD (2) +*/ +#define PB_MSG_TYPE_REQUEST 1 +#define PB_MSG_TYPE_RESPONSE 2 + +#endif diff --git a/rpc/pbrpccontroller.h b/rpc/pbrpccontroller.h new file mode 100644 index 0000000..0b67ded --- /dev/null +++ b/rpc/pbrpccontroller.h @@ -0,0 +1,27 @@ +#ifndef _PB_RPC_CONTROLLER_H +#define _PB_RPC_CONTROLLER_H + +#include + +class PbRpcController : public ::google::protobuf::RpcController +{ + bool failed; + std::string errStr; + +public: + PbRpcController() { failed = false; } + + // Client Side Methods + void Reset() { failed=false;} + bool Failed() const { return failed; } + void StartCancel() { /* TODO */} + std::string ErrorText() const { return errStr; } + + // Server Side Methods + void SetFailed(const std::string &reason) + { failed = true; errStr = reason; } + bool IsCanceled() const { return false; }; + void NotifyOnCancel(::google::protobuf::Closure *callback) { /*TODO*/ } +}; + +#endif diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp new file mode 100644 index 0000000..45555bf --- /dev/null +++ b/rpc/rpcserver.cpp @@ -0,0 +1,180 @@ +#include "pbhelper.h" +#include "rpcserver.h" + +RpcServer::RpcServer() +{ + server = NULL; + clientSock = NULL; + + service = NULL; + + isPending = false; + pendingMethodId = -1; // don't care as long as isPending is false +} + +RpcServer::~RpcServer() +{ + if (server) + delete server; +} + +bool RpcServer::registerService(::google::protobuf::Service *service, + quint16 tcpPortNum) +{ + this->service = service; + + server = new QTcpServer(); + connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); + if (!server->listen(QHostAddress::Any, tcpPortNum)) + { + LogInt(tr("Unable to start the server: %1").arg(server->errorString())); + return false; + } + + LogInt(tr("The server is running on %1:%2").arg(server->serverAddress().toString()).arg(server->serverPort())); + return true; +} + +void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController) +{ + char msg[1024]; // FIXME: hardcoding + char *p = (char *)&msg; + int len; + + qDebug("In RpcServer::done"); + + // TODO: check PbRpcController to see if method failed + if (PbRpcController->Failed()) + { + qDebug("rpc failed"); + goto _exit; + } + + *((quint16*)(p+0)) = HTONS(PB_MSG_TYPE_RESPONSE); // type TODO:RESPONSE + *((quint16*)(p+2)) = HTONS(pendingMethodId); // method + *((quint16*)(p+6)) = HTONS(0); // rsvd + + // SerialData is at offset 8 + resp->SerializeToArray((void*) (p+8), sizeof(msg)); + + len = resp->ByteSize(); + (*(quint16*)(p+4)) = HTONS(len); // len + + qDebug("Server(%s): sending %d bytest to client encoding <%s>", + __FUNCTION__, len + 8, resp->DebugString().c_str()); + BUFDUMP(msg, len + 8); + + clientSock->write(msg, len + 8); + +_exit: + delete PbRpcController; + isPending = false; +} + +void RpcServer::when_newConnection() +{ + if (clientSock) + { + QTcpSocket *sock; + + LogInt(tr("already connected, no new connections will be accepted\n")); + + // Accept and close connection + // TODO: Send reason msg to client + sock = server->nextPendingConnection(); + sock->disconnectFromHost(); + sock->deleteLater(); + goto _exit; + } + + clientSock = server->nextPendingConnection(); + LogInt(tr("accepting new connection from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); + + connect(clientSock, SIGNAL(readyRead()), + this, SLOT(when_dataAvail())); + connect(clientSock, SIGNAL(disconnected()), + this, SLOT(when_disconnected())); + connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(when_error(QAbstractSocket::SocketError))); + +_exit: + return; +} + +void RpcServer::when_disconnected() +{ + LogInt(tr("connection closed from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); + + clientSock->deleteLater(); + clientSock = NULL; +} + +void RpcServer::when_error(QAbstractSocket::SocketError socketError) +{ + LogInt(clientSock->errorString()); +} + +void RpcServer::when_dataAvail() +{ + char msg[1024]; // FIXME: hardcoding; + int msgLen; + char *p = (char*) &msg; + quint16 type, method, len, rsvd; + const ::google::protobuf::MethodDescriptor *methodDesc; + ::google::protobuf::Message *req, *resp; + PbRpcController *controller; + + msgLen = clientSock->read(msg, sizeof(msg)); + LogInt(QString(QByteArray(msg, msgLen).toHex())); + + qDebug("Server %s: rcvd %d bytes", __FUNCTION__, msgLen); + BUFDUMP(msg, msgLen); + + type = NTOHS(GET16(p+0)); + qDebug("GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)), type); + method = NTOHS(GET16(p+2)); + len = NTOHS(GET16(p+4)); + rsvd = NTOHS(GET16(p+6)); + + if (type != PB_MSG_TYPE_REQUEST) + { + qDebug("server(%s): unexpected msg type %d (expected %d)", __FUNCTION__, + type, PB_MSG_TYPE_REQUEST); + goto _error_exit; + } + + + methodDesc = service->GetDescriptor()->method(method); + if (!methodDesc) + { + qDebug("server(%s): invalid method id %d", __FUNCTION__, method); + goto _error_exit; // TODO: Return Error to client + } + + if (isPending) + { + qDebug("server(%s): rpc pending, try again", __FUNCTION__); + goto _error_exit; // TODO: Return Error to client + } + + pendingMethodId = method; + isPending = true; + + req = service->GetRequestPrototype(methodDesc).New(); + resp = service->GetResponsePrototype(methodDesc).New(); + + // Serialized data starts from offset 8 + req->ParseFromArray((void*) (msg+8), len); + + controller = new PbRpcController; + + service->CallMethod(methodDesc, controller, req, resp, + NewCallback(this, &RpcServer::done, resp, controller)); + + return; + +_error_exit: + qDebug("server(%s): discarding msg from client", __FUNCTION__); + return; +} + diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h new file mode 100644 index 0000000..9e21587 --- /dev/null +++ b/rpc/rpcserver.h @@ -0,0 +1,44 @@ +#ifndef _RPC_SERVER_H +#define _RPC_SERVER_H + +#include +#include +#include + +#include +#include + +#include "pbrpccommon.h" +#include "pbrpccontroller.h" + + +class RpcServer : public QObject +{ + Q_OBJECT + + QTcpServer *server; + QTcpSocket *clientSock; + + ::google::protobuf::Service *service; + + bool isPending; + int pendingMethodId; + + void LogInt (QString log) {qDebug("%s", log.toAscii().data());} + +public: + RpcServer(); // TODO: use 'parent' param + virtual ~RpcServer(); + + bool registerService(::google::protobuf::Service *service, + quint16 tcpPortNum); + void done(::google::protobuf::Message *resp, PbRpcController *controller); + +private slots: + void when_newConnection(); + void when_disconnected(); + void when_dataAvail(); + void when_error(QAbstractSocket::SocketError socketError); +}; + +#endif diff --git a/server/abstracthost.h b/server/abstracthost.h index 38e266c..862666c 100644 --- a/server/abstracthost.h +++ b/server/abstracthost.h @@ -5,7 +5,9 @@ class AbstractHost { public: virtual void Log(const char* str) = 0; +#if 0 // PB virtual int SendMsg(const void* msg, int size) = 0; +#endif }; #endif diff --git a/server/drone.cpp b/server/drone.cpp index 54bf9cf..98300ee 100644 --- a/server/drone.cpp +++ b/server/drone.cpp @@ -6,13 +6,19 @@ Drone::Drone(QDialog *parent) : QDialog(parent) { ui.setupUi(this); +#if 0 // PB + rxtx = new RxTx(this); +#endif + rpcServer = new RpcServer(); + service = new MyService(this); + rpcServer->registerService(service, myport?myport:7878); + +#if 0 // PB serverPortNum = DRONE_PORT; clientSock = NULL; if (myport) - serverPortNum = myport; - - rxtx = new RxTx(this); + serverPortNum = myport); server = new QTcpServer(this); connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); @@ -21,6 +27,7 @@ Drone::Drone(QDialog *parent) LogInt(tr("Unable to start the server: %1").arg(server->errorString())); else LogInt(tr("The server is running on %1:%2").arg(server->serverAddress().toString()).arg(server->serverPort())); +#endif } void Drone::Log(const char* str) @@ -28,17 +35,20 @@ void Drone::Log(const char* str) ui.teLog->append(QString(str)); } +#if 0 // PB int Drone::SendMsg(const void* msg, int size) { qDebug("Inside SendMsg\n"); clientSock->write((char*) msg, size); } +#endif void Drone::LogInt(const QString &str) { ui.teLog->append(str); } +#if 0 // PB void Drone::when_newConnection() { if (clientSock) @@ -83,3 +93,4 @@ void Drone::when_error(QAbstractSocket::SocketError socketError) { LogInt(clientSock->errorString()); } +#endif diff --git a/server/drone.h b/server/drone.h index f99255b..3c4adba 100644 --- a/server/drone.h +++ b/server/drone.h @@ -5,7 +5,11 @@ #include #include "ui_drone.h" #include "abstracthost.h" +#if 0 // PB #include "rxtx.h" +#endif +#include "rpcserver.h" +#include "myservice.h" class Drone : public QDialog, AbstractHost @@ -13,24 +17,31 @@ class Drone : public QDialog, AbstractHost Q_OBJECT public: + Ui::Drone ui; Drone(QDialog *parent = 0); void Log(const char *msg); +#if 0 // PB int SendMsg(const void* msg, int msgLen); +#endif - Ui::Drone ui; private: +#if 0 // PB RxTx *rxtx; +#endif + RpcServer *rpcServer; + OstProto::OstService *service; + void LogInt(const QString &msg); +#if 0 // PB QTcpServer *server; QTcpSocket *clientSock; #define DRONE_PORT 7878 quint16 serverPortNum; - // Ui::Drone ui; - void LogInt(const QString &msg); + private slots: void when_newConnection(); void when_disconnected(); void when_dataAvail(); void when_error(QAbstractSocket::SocketError socketError); +#endif }; #endif - diff --git a/server/drone.pro b/server/drone.pro index 1fd8862..df79396 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -2,8 +2,14 @@ TEMPLATE = app CONFIG += qt QT += network DEFINES += HAVE_REMOTE +INCLUDEPATH += "c:\msys\1.0\local\include" INCLUDEPATH += "C:\DevelLibs\WpdPack\Include" +INCLUDEPATH += "..\rpc" LIBS += -L"C:\DevelLibs\WpdPack\Lib" -lwpcap -HEADERS += drone.h +LIBS += -L"..\rpc\debug" -lpbrpc +HEADERS += drone.h FORMS += drone.ui -SOURCES += drone_main.cpp drone.cpp rxtx.cpp +SOURCES += drone_main.cpp drone.cpp +SOURCES += myservice.cpp + +SOURCES += "..\common\protocol.pb.cc" diff --git a/server/myservice.cpp b/server/myservice.cpp new file mode 100644 index 0000000..93e625c --- /dev/null +++ b/server/myservice.cpp @@ -0,0 +1,290 @@ +#include "myservice.h" +#include "qdebug.h" + +#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} + +MyService::MyService(AbstractHost *host) +{ + pcap_if_t *dev; + int i=0; + char errbuf[PCAP_ERRBUF_SIZE]; + + // Init Data + this->host = host; + numPorts = 0; + alldevs = NULL; + + LOG("Retrieving the device list from the local machine\n"); + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + LOG("Error in pcap_findalldevs_ex: %s\n", errbuf); + goto _fail; + } + + /* Count number of local ports */ + for(dev = alldevs; dev != NULL; dev = dev->next) + numPorts++; + + portInfo = new PortInfo[numPorts]; + + /* Populate and Print the list */ + for(i=0, dev=alldevs; dev!=NULL; i++, dev=dev->next) + { +#if 0 // PB + //portInfo[i].portId = i; + //portInfo[i].dev = dev; + //portInfo[i].streamHead = NULL; + //portInfo[i].streamTail = NULL; +#endif + portInfo[i].setId(i); + portInfo[i].setPcapDev(dev); +#if 1 + LOG("%d. %s", i, dev->name); + if (dev->description) + { + LOG(" (%s)\n", dev->description); + } + else + LOG(" (No description available)\n"); +#endif + } + + if (i == 0) + { + LOG("\nNo interfaces found! Make sure WinPcap is installed.\n"); + goto _fail; + } + +_fail: + return; +} + +MyService::~MyService() +{ + unsigned int i; +#if 0 // PB????? + for (i = 0; i < numPorts; i++) + DeleteAllStreams(i); +#endif + pcap_freealldevs(alldevs); +} + +void MyService::getPortIdList( + ::google::protobuf::RpcController* controller, + const ::OstProto::Void* request, + ::OstProto::PortIdList* response, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + + for (uint i = 0; i < numPorts; i++) + response->add_port_id(portInfo[i].d.port_id()); + + qDebug("Server(%s): portid count = %d", __FUNCTION__, response->port_id_size()); + + qDebug("Server(%s): %s", __FUNCTION__, response->DebugString().c_str()); + + done->Run(); +} + +void MyService::getPortConfig(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::PortConfigList* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + + for (int i=0; i < request->port_id_size(); i++) + { + unsigned int id; + + id = request->port_id(i); + if (id < numPorts) + { + OstProto::PortConfig *p; + + p = response->add_list(); + p->CopyFrom(portInfo[request->port_id(i)].d); + } + } + + done->Run(); +} + +void MyService::getStreamIdList(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::StreamIdList* response, +::google::protobuf::Closure* done) +{ + + for (int i = 0; i < request->port_id_size(); i++) + { + unsigned int portId; + + portId = request->port_id(i); + if (portId >= numPorts) + { + qDebug("%s: Invalid port id %d", __FUNCTION__, portId); + continue; // TODO: Partial status of RPC + } + + for (int j = 0; j < portInfo[portId].streamList.size(); j++) + { + OstProto::StreamId *s, *q; + + q = portInfo[portId].streamList[j].d.mutable_id(); + assert(q->port_id() == portId); + + s = response->add_id(); + s->set_port_id(portId); + s->set_stream_id(q->stream_id()); + } + } + done->Run(); +} + +void MyService::getStreamConfig(::google::protobuf::RpcController* controller, +const ::OstProto::StreamIdList* request, +::OstProto::StreamConfigList* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + + for (int i = 0; i < request->id_size(); i++) + { + unsigned int portId; + unsigned int streamId; + + portId = request->id(i).port_id(); + if (portId >= numPorts) + { + qDebug("%s: Invalid port id %d", __FUNCTION__, portId); + continue; // TODO: Partial status of RPC + } + + streamId = request->id(i).stream_id(); + if (streamId >= numPorts) + { + qDebug("%s: Invalid port id %d", __FUNCTION__, portId); + continue; // TODO: Partial status of RPC + } + + for (int j = 0; j < portInfo[portId].streamList.size(); j++) + { + OstProto::Stream *s, *q; + +#if 0 + q = portInfo[portId].streamList[j].d.e_stream(); + assert(q->port_id() == portId); + + s = response->add_stream(); + s->set_port_id(portId); + s->set_stream_id(q->stream_id()); +#endif + // TODO: more params + } + } + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::addStream(::google::protobuf::RpcController* controller, +const ::OstProto::StreamIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::deleteStream(::google::protobuf::RpcController* controller, +const ::OstProto::StreamIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::modifyStream(::google::protobuf::RpcController* controller, +const ::OstProto::StreamConfigList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::startTx(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::stopTx(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::startCapture(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::stopCapture(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::getCaptureBuffer(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::CaptureBufferList* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::getStats(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::PortStatsList* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::clearStats(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + diff --git a/server/myservice.h b/server/myservice.h new file mode 100644 index 0000000..83ebc0f --- /dev/null +++ b/server/myservice.h @@ -0,0 +1,146 @@ +#ifndef _MY_SERVICE_H +#define _MY_SERVICE_H + + +#if 0 +#include +#include +#endif + +#include "../common/protocol.pb.h" +#include "abstracthost.h" +#include +#include + +#define MAX_PKT_HDR_SIZE 1536 +#define MAX_STREAM_NAME_SIZE 64 + +class MyService; + +class StreamInfo +{ + friend class MyService; + + OstProto::Stream d; + +#if 0 // PB + unsigned int id; + + char name[MAX_STREAM_NAME_SIZE]; + unsigned char pktHdr[MAX_PKT_HDR_SIZE]; + unsigned short hdrLen; + unsigned short pktLen; + unsigned int dataPattern; + unsigned int flags; +#define STREAM_FLAG_MASK_STATUS 0x00000001 +#define STREAM_FLAG_VALUE_STATUS_DISABLED 0x00000000 +#define STREAM_FLAG_VALUE_STATUS_ENABLED 0x00000001 + + struct _Stream *next; +#endif +}; + + +class PortInfo +{ + friend class MyService; + + OstProto::PortConfig d; + pcap_if_t *dev; + + QList streamList; + +#if 0 // PB + unsigned int portId; // FIXME:need? + Stream *streamHead; + Stream *streamTail; +#endif + +public: + // TODO(LOW): Both setId and setPcapDev() should together form the ctor + void setId(unsigned int id) { d.set_port_id(id); } + void setPcapDev(pcap_if_t *dev) + { + this->dev = dev; + d.set_name("eth"); // FIXME: suffix portid + d.set_description(dev->description); + d.set_is_enabled(true); // FIXME:check + d.set_is_oper_up(true); // FIXME:check + d.set_is_exclusive_control(false); // FIXME: check + } +}; + +class MyService: public OstProto::OstService +{ + AbstractHost *host; + char logStr[1024]; + + unsigned numPorts; + PortInfo *portInfo; + pcap_if_t *alldevs; + +public: + MyService(AbstractHost* host); + virtual ~MyService(); + + //static const ::google::protobuf::ServiceDescriptor* descriptor(); + + virtual void getPortIdList(::google::protobuf::RpcController* controller, + const ::OstProto::Void* request, + ::OstProto::PortIdList* response, + ::google::protobuf::Closure* done); + virtual void getPortConfig(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::PortConfigList* response, + ::google::protobuf::Closure* done); + virtual void getStreamIdList(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::StreamIdList* response, + ::google::protobuf::Closure* done); + virtual void getStreamConfig(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::StreamConfigList* response, + ::google::protobuf::Closure* done); + virtual void addStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void deleteStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void modifyStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamConfigList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void startTx(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void stopTx(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void startCapture(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void stopCapture(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void getCaptureBuffer(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::CaptureBufferList* response, + ::google::protobuf::Closure* done); + virtual void getStats(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::PortStatsList* response, + ::google::protobuf::Closure* done); + virtual void clearStats(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); +}; + +#endif diff --git a/server/rxtx.cpp b/server/rxtx.cpp index 2eab59b..f4b5308 100644 --- a/server/rxtx.cpp +++ b/server/rxtx.cpp @@ -1,6 +1,12 @@ + +File Not used anymore + +#if 0 #include "qtglobal" // FIXME: needed only for qdebug #include "rxtx.h" +#if 0 // PB #include "../common/protocol.h" +#endif @@ -157,7 +163,9 @@ void RxTx::SendCapabilityInfo(void) } host->Log("Sending msg\n"); host->Log(logStr); +#if 0 // PB host->SendMsg(pktBuff, msgLen); +#endif } void RxTx::ProcessPortConfig(const char* msg, int len) @@ -503,4 +511,4 @@ Stream* RxTx::GetStream(unsigned int port, unsigned int streamId) return NULL; } - +#endif diff --git a/server/rxtx.h b/server/rxtx.h index 986b978..fac9331 100644 --- a/server/rxtx.h +++ b/server/rxtx.h @@ -1,9 +1,16 @@ + +File not used anymore + +#if 0 + #ifndef _RXTX_H #define _RXTX_H #include "pcap.h" #include "abstracthost.h" +#include "../common/protocol.h" + #define GET16(x) (UINT16)( \ (*((UINT8*)x+0) << 16 ) \ | (*((UINT8*)x+1))) @@ -74,3 +81,4 @@ class RxTx }; #endif +#endif From c7f4c1dec9e776d5261912a8f0f7deb18ae172e7 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 24 Aug 2008 04:39:08 +0000 Subject: [PATCH 07/98] - StreamModel no longer a friend of Stream - PacketModel refactored by moving protocol specific stuff into Stream and xxxProtocol classes --- Makefile | 9 + client/packetmodel.cpp | 206 +++++--- client/packetmodel.h | 12 +- client/port.cpp | 211 +++++--- client/port.h | 65 ++- client/portgroup.cpp | 413 ++++++++++----- client/portgroup.h | 13 +- client/portgrouplist.h | 1 + client/portstatsmodel.cpp | 3 +- client/portswindow.cpp | 44 +- client/stream.cpp | 953 +++++++++++++++++++++++++++++----- client/stream.h | 508 ++++++++++++++---- client/streamconfigdialog.cpp | 342 +++++++----- client/streamconfigdialog.h | 9 +- client/streamconfigdialog.ui | 5 +- client/streammodel.cpp | 17 +- client/streammodel.h | 2 + common/protocol.proto | 43 +- rpc/pbhelper.h | 92 +++- rpc/pbrpcchannel.cpp | 23 +- rpc/rpcserver.cpp | 33 +- server/myservice.cpp | 278 ++++++---- server/myservice.h | 129 ++--- server/rxtx.cpp | 2 +- server/rxtx.h | 2 +- 25 files changed, 2528 insertions(+), 887 deletions(-) diff --git a/Makefile b/Makefile index c24ac11..8b555c4 100644 --- a/Makefile +++ b/Makefile @@ -3,3 +3,12 @@ all: $(MAKE) -C common $(MAKE) -C server $(MAKE) -C client + +clean: + $(MAKE) -C rpc $@ + $(MAKE) -C common $@ + $(MAKE) -C server $@ + $(MAKE) -C client $@ + +qmake: + for %%d in (rpc common server client) cd %%d; qmake; cd..; diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 8711b53..5800413 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -4,8 +4,11 @@ PacketModel::PacketModel(Stream *pStream, QObject *parent) { mpStream = pStream; +#ifdef NEW_IMPL +// Nothing else +#else populatePacketProtocols(); -#if 1 + registerFrameTypeProto(); registerVlanProto(); registerIpProto(); @@ -23,17 +26,25 @@ int PacketModel::rowCount(const QModelIndex &parent) const { IndexId parentId; - // Parent - Invalid i.e. Invisible Root. - // Children - Protocol (Top Level) Items + // Parent == Invalid i.e. Invisible Root. + // ==> Children are Protocol (Top Level) Items if (!parent.isValid()) +#ifdef NEW_IMPL + return mpStream->numProtocols(); +#else return protoCount(); +#endif // Parent - Valid Item parentId.w = parent.internalId(); switch(parentId.ws.type) { case ITYP_PROTOCOL: +#ifdef NEW_IMPL + return mpStream->protocol(parentId.ws.protocol)->numFields(); +#else return fieldCount(parentId.ws.protocol); +#endif case ITYP_FIELD: return 0; default: @@ -126,7 +137,11 @@ _exit: QVariant PacketModel::data(const QModelIndex &index, int role) const { IndexId id; +#ifdef NEW_IMPL +// Nothing +#else ProtocolInfo proto; +#endif if (!index.isValid()) return QVariant(); @@ -138,12 +153,24 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const switch(id.ws.type) { case ITYP_PROTOCOL: +#ifdef NEW_IMPL + return QString("%1 (%2)") + .arg(mpStream->protocol(id.ws.protocol)->protocolShortName()) + .arg(mpStream->protocol(id.ws.protocol)->protocolName()); +#else return protoName(id.ws.protocol); +#endif case ITYP_FIELD: +#ifdef NEW_IMPL + return mpStream->protocol(id.ws.protocol)->fieldName(index.row()) + + QString(" : ") + + mpStream->protocol(id.ws.protocol)->fieldTextValue(index.row()); +#else return fieldName(id.ws.protocol, index.row()) + QString(" : ") + fieldTextValue(id.ws.protocol, index.row()).toString(); +#endif default: qWarning("%s: Unhandled ItemType", __FUNCTION__); @@ -154,12 +181,29 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const return QVariant(); } - +#ifdef NEW_IMPL +// required methods all part of the Stream class +#else /* ** --------------- Private Stuff ----------------- ** FIXME(MED): Move these to the Stream Class ** */ + +/*! + Looking at the stream's protocols and populate an ordered list of + protocols accordingly. The order of protocols will be in the order of + protocol headers viz. + + - None/Eth2/802.3 (Mac Addr) + - LLC + - SNAP + - SVLAN + - CVLAN + - L3 (IP/ARP) + - L4 (TCP/UDP/ICMP/IGMP) + +*/ void PacketModel::populatePacketProtocols() { int proto; @@ -167,9 +211,8 @@ void PacketModel::populatePacketProtocols() // Clear the protocols list mPacketProtocols.clear(); -#if 0 // FIXME: protobuf // Check and populate L2 Protocol - switch(mpStream->proto.ft) + switch(mpStream->frameType()) { case Stream::e_ft_none: proto = PTYP_L2_NONE; @@ -195,71 +238,80 @@ void PacketModel::populatePacketProtocols() break; default: - qDebug("%s: Unsupported frametype", __FUNCTION__); + qDebug("%s: Unsupported frametype %d", __FUNCTION__, + mpStream->frameType()); proto = PTYP_INVALID; } mPacketProtocols.append(proto); // Check and populate VLANs, if present - if (mpStream->l2.eth.vlanMask & VM_SVLAN_TAGGED) + if (mpStream->vlan()->vlanFlags().testFlag(VlanProtocol::VlanSvlanTagged)) mPacketProtocols.append(PTYP_SVLAN); - if (mpStream->l2.eth.vlanMask & VM_CVLAN_TAGGED) + if (mpStream->vlan()->vlanFlags().testFlag(VlanProtocol::VlanCvlanTagged)) mPacketProtocols.append(PTYP_CVLAN); // Check and populate L3 protocols - if (mpStream->proto.protoMask & PM_L3_PROTO_NONE) - goto _data; - - switch(mpStream->proto.etherType) + switch (mpStream->l3Proto()) { - case ETH_TYP_IP: + case Stream::e_l3_none : + goto _data; + break; + + case Stream::e_l3_ip : proto = PTYP_L3_IP; break; - case ETH_TYP_ARP: + case Stream::e_l3_arp: proto = PTYP_L3_ARP; break; default: - qDebug("%s: Unsupported ethtype", __FUNCTION__); + qDebug("%s: Unsupported L3 Proto %d", __FUNCTION__, + mpStream->l3Proto()); proto = PTYP_INVALID; } mPacketProtocols.append(proto); - if (mpStream->proto.protoMask & PM_L4_PROTO_NONE) - goto _data; - - switch(mpStream->proto.ipProto) + // Check and populate L4 protocol + switch(mpStream->l4Proto()) { - case IP_PROTO_TCP: + case Stream::e_l4_none: + goto _data; + break; + case Stream::e_l4_tcp: proto = PTYP_L4_TCP; break; - case IP_PROTO_UDP: + case Stream::e_l4_udp: proto = PTYP_L4_UDP; break; - case IP_PROTO_ICMP: + case Stream::e_l4_icmp: proto = PTYP_L4_ICMP; break; - case IP_PROTO_IGMP: + case Stream::e_l4_igmp: proto = PTYP_L4_IGMP; break; default: - qDebug("%s: Unsupported ipProto", __FUNCTION__); + qDebug("%s: Unsupported L4 Proto %d", __FUNCTION__, + mpStream->l4Proto()); proto = PTYP_INVALID; }; mPacketProtocols.append(proto); _data: mPacketProtocols.append(PTYP_DATA); -#endif } - +/*! + Returns the count of protocols in the current stream +*/ int PacketModel::protoCount() const { return mPacketProtocols.count(); } +/*! + Returns the count of fields in the given protocol +*/ int PacketModel::fieldCount(int protocol) const { ProtocolInfo proto; @@ -375,25 +427,22 @@ QVariant PacketModel::ethField(int field, int role) const FieldInfo info; // FIXME(MED): Mac Addr formatting -#if 0 // FIXME protobuf switch(field) { case 0: info.name = QString("Destination Mac Address"); - info.textValue = QString("%1%2"). - arg(mpStream->l2.eth.dstMacMshw, 4, BASE_HEX, QChar('0')). - arg(mpStream->l2.eth.dstMacLsw, 8, BASE_HEX, QChar('0')); + info.textValue = QString("%1"). + arg(mpStream->mac()->dstMac(), 12, BASE_HEX, QChar('0')); break; case 1: info.name = QString("Source Mac Address"); - info.textValue = QString("%1%2"). - arg(mpStream->l2.eth.srcMacMshw, 4, BASE_HEX, QChar('0')). - arg(mpStream->l2.eth.srcMacLsw, 8, BASE_HEX, QChar('0')); + info.textValue = QString("%1"). + arg(mpStream->mac()->srcMac(), 12, BASE_HEX, QChar('0')); break; case 2: info.name = QString("Type"); info.textValue = QString("0x%1"). - arg(mpStream->proto.etherType, 4, BASE_HEX, QChar('0')); + arg(mpStream->eth2()->type(), 4, BASE_HEX, QChar('0')); break; default: info.name = QString(); @@ -411,7 +460,6 @@ QVariant PacketModel::ethField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code -#endif return QVariant(); } @@ -419,23 +467,22 @@ QVariant PacketModel::llcField(int field, int role) const { FieldInfo info; -#if 0 // FIXME: protobuf switch(field) { case 0: info.name = QString("DSAP"); info.textValue = QString("0x%1"). - arg(mpStream->proto.dsap, 2, BASE_HEX, QChar('0')); + arg(mpStream->llc()->dsap(), 2, BASE_HEX, QChar('0')); break; case 1: info.name = QString("SSAP"); info.textValue = QString("0x%1"). - arg(mpStream->proto.ssap, 2, BASE_HEX, QChar('0')); + arg(mpStream->llc()->ssap(), 2, BASE_HEX, QChar('0')); break; case 2: info.name = QString("Control"); info.textValue = QString("0x%1"). - arg(mpStream->proto.ctl, 2, BASE_HEX, QChar('0')); + arg(mpStream->llc()->ctl(), 2, BASE_HEX, QChar('0')); break; default: info.name = QString(); @@ -453,7 +500,6 @@ QVariant PacketModel::llcField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code -#endif return QVariant(); } @@ -461,19 +507,17 @@ QVariant PacketModel::snapField(int field, int role) const { FieldInfo info; -#if 0 // FIXME: protobuf switch(field) { case 0: info.name = QString("OUI"); - info.textValue = QString("0x%1%2"). - arg(mpStream->proto.ouiMsb, 2, BASE_HEX, QChar('0')). - arg(mpStream->proto.ouiLshw, 4, BASE_HEX, QChar('0')); + info.textValue = QString("0x%1"). + arg(mpStream->snap()->oui(), 6, BASE_HEX, QChar('0')); break; case 1: info.name = QString("Type"); info.textValue = QString("0x%1"). - arg(mpStream->proto.etherType, 4, BASE_HEX, QChar('0')); + arg(mpStream->eth2()->type(), 4, BASE_HEX, QChar('0')); break; default: info.name = QString(); @@ -491,7 +535,6 @@ QVariant PacketModel::snapField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code -#endif return QVariant(); } @@ -499,28 +542,27 @@ QVariant PacketModel::svlanField(int field, int role) const { FieldInfo info; -#if 0 // FIXME: protobuf switch(field) { case 0: info.name = QString("TPID"); info.textValue = QString("0x%1"). - arg(mpStream->l2.eth.stpid, 4, BASE_HEX, QChar('0')); + arg(mpStream->vlan()->stpid(), 4, BASE_HEX, QChar('0')); break; case 1: info.name = QString("PCP"); info.textValue = QString("%1"). - arg(mpStream->l2.eth.svlanPrio); + arg(mpStream->vlan()->svlanPrio()); break; case 2: info.name = QString("DE"); info.textValue = QString("%1"). - arg(mpStream->l2.eth.svlanCfi); + arg(mpStream->vlan()->svlanCfi()); break; case 3: info.name = QString("VlanId"); info.textValue = QString("%1"). - arg(mpStream->l2.eth.svlanId); + arg(mpStream->vlan()->svlanId()); break; default: info.name = QString(); @@ -538,7 +580,6 @@ QVariant PacketModel::svlanField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code -#endif return QVariant(); } @@ -547,66 +588,65 @@ QVariant PacketModel::ipField(int field, int role) const { FieldInfo info; -#if 0 // FIXME: protobuf switch(field) { case 0: info.name = QString("Version"); info.textValue = QString("%1"). - arg(mpStream->l3.ip.ver); + arg(mpStream->ip()->ver()); break; case 1: info.name = QString("Header Length"); info.textValue = QString("%1"). - arg(mpStream->l3.ip.hdrLen); + arg(mpStream->ip()->hdrLen()); break; case 2: info.name = QString("TOS/DSCP"); info.textValue = QString("0x%1"). - arg(mpStream->l3.ip.tos, 2, BASE_HEX, QChar('0')); + arg(mpStream->ip()->tos(), 2, BASE_HEX, QChar('0')); break; case 3: info.name = QString("Total Length"); info.textValue = QString("%1"). - arg(mpStream->l3.ip.totLen); + arg(mpStream->ip()->totLen()); break; case 4: info.name = QString("ID"); info.textValue = QString("0x%1"). - arg(mpStream->l3.ip.id, 2, BASE_HEX, QChar('0')); + arg(mpStream->ip()->id(), 2, BASE_HEX, QChar('0')); break; case 5: info.name = QString("Flags"); info.textValue = QString("0x%1"). - arg(mpStream->l3.ip.flags, 2, BASE_HEX, QChar('0')); // FIXME(HIGH) + arg(mpStream->ip()->flags(), 2, BASE_HEX, QChar('0')); // FIXME(HIGH) break; case 6: info.name = QString("Fragment Offset"); info.textValue = QString("%1"). - arg(mpStream->l3.ip.fragOfs); + arg(mpStream->ip()->fragOfs()); break; case 7: info.name = QString("TTL"); info.textValue = QString("%1"). - arg(mpStream->l3.ip.ttl); + arg(mpStream->ip()->ttl()); break; case 8: info.name = QString("Protocol Type"); info.textValue = QString("0x%1"). - arg(mpStream->l3.ip.proto, 2, BASE_HEX, QChar('0')); + arg(mpStream->ip()->proto(), 2, BASE_HEX, QChar('0')); break; case 9: info.name = QString("Checksum"); info.textValue = QString("0x%1"). - arg(mpStream->l3.ip.cksum, 4, BASE_HEX, QChar('0')); + arg(mpStream->ip()->cksum(), 4, BASE_HEX, QChar('0')); break; case 10: info.name = QString("Source IP"); - info.textValue = QHostAddress(mpStream->l3.ip.srcIp).toString(); + info.textValue = QHostAddress(mpStream->ip()->srcIp()).toString(); break; case 11: info.name = QString("Destination IP"); - info.textValue = QHostAddress(mpStream->l3.ip.dstIp).toString(); + info.textValue = QHostAddress(mpStream->ip()->dstIp()).toString(); break; default: info.name = QString(); @@ -624,7 +664,6 @@ QVariant PacketModel::ipField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code -#endif return QVariant(); } @@ -633,58 +672,57 @@ QVariant PacketModel::tcpField(int field, int role) const { FieldInfo info; -#if 0 // FIXME: protobuf switch(field) { case 0: info.name = QString("Source Port"); info.textValue = QString("%1"). - arg(mpStream->l4.tcp.srcPort); + arg(mpStream->tcp()->srcPort()); break; case 1: info.name = QString("Destination Port"); info.textValue = QString("%1"). - arg(mpStream->l4.tcp.dstPort); + arg(mpStream->tcp()->dstPort()); break; case 2: info.name = QString("Seq Number"); info.textValue = QString("%1"). - arg(mpStream->l4.tcp.seqNum); + arg(mpStream->tcp()->seqNum()); break; case 3: info.name = QString("Ack Number"); info.textValue = QString("%1"). - arg(mpStream->l4.tcp.ackNum); + arg(mpStream->tcp()->ackNum()); break; case 4: info.name = QString("Header Length"); info.textValue = QString("%1"). - arg(mpStream->l4.tcp.hdrLen); + arg(mpStream->tcp()->hdrLen()); break; case 5: info.name = QString("Reserved"); info.textValue = QString("%1"). - arg(mpStream->l4.tcp.rsvd); + arg(mpStream->tcp()->rsvd()); break; case 6: info.name = QString("Flags"); info.textValue = QString("0x%1"). - arg(mpStream->l4.tcp.flags, 2, BASE_HEX, QChar('0')); + arg(mpStream->tcp()->flags(), 2, BASE_HEX, QChar('0')); break; case 7: info.name = QString("Window"); info.textValue = QString("%1"). - arg(mpStream->l4.tcp.flags); + arg(mpStream->tcp()->flags()); break; case 8: info.name = QString("Checksum"); info.textValue = QString("0x%1"). - arg(mpStream->l4.tcp.cksum, 4, BASE_HEX, QChar('0')); + arg(mpStream->tcp()->cksum(), 4, BASE_HEX, QChar('0')); break; case 9: info.name = QString("Urgent Pointer"); info.textValue = QString("%1"). - arg(mpStream->l4.tcp.urgPtr); + arg(mpStream->tcp()->urgPtr()); break; default: info.name = QString(); @@ -702,7 +740,6 @@ QVariant PacketModel::tcpField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code -#endif return QVariant(); } @@ -711,28 +748,27 @@ QVariant PacketModel::udpField(int field, int role) const { FieldInfo info; -#if 0 // FIXME:protobuf switch(field) { case 0: info.name = QString("Source Port"); info.textValue = QString("%1"). - arg(mpStream->l4.udp.srcPort); + arg(mpStream->udp()->srcPort()); break; case 1: info.name = QString("Destination Port"); info.textValue = QString("%1"). - arg(mpStream->l4.udp.dstPort); + arg(mpStream->udp()->dstPort()); break; case 2: info.name = QString("Total Length"); info.textValue = QString("%1"). - arg(mpStream->l4.udp.totLen); + arg(mpStream->udp()->totLen()); break; case 3: info.name = QString("Checksum"); info.textValue = QString("0x%1"). - arg(mpStream->l4.udp.cksum, 4, BASE_HEX, QChar('0')); + arg(mpStream->udp()->cksum(), 4, BASE_HEX, QChar('0')); break; default: info.name = QString(); @@ -750,7 +786,6 @@ QVariant PacketModel::udpField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code -#endif return QVariant(); } @@ -900,3 +935,4 @@ void PacketModel::registerData() registerProto(PTYP_DATA, "Data", "data"); } +#endif diff --git a/client/packetmodel.h b/client/packetmodel.h index 4f79155..1134a14 100644 --- a/client/packetmodel.h +++ b/client/packetmodel.h @@ -4,6 +4,8 @@ #include #include "stream.h" +#define NEW_IMPL // FIXME(HI) - Use this and remove old one + class PacketModel: public QAbstractItemModel { @@ -27,11 +29,15 @@ private: quint16 type; #define ITYP_PROTOCOL 1 #define ITYP_FIELD 2 - quint16 protocol; + quint16 protocol; // protocol is valid for both ITYPs } ws; } IndexId; Stream *mpStream; + +#ifdef NEW_IMPL +// Nothing - required stuff is part of Stream Class +#else QList mPacketProtocols; typedef struct @@ -49,6 +55,8 @@ private: QList fieldList; } ProtocolInfo; + //! Contains registration info (name, size etc) for all protocols + // and fields within the protocol QList mProtocols; void registerProto(uint handle, char *name, char *abbr); void registerField(uint protoHandle, char *name, char *abbr); @@ -102,6 +110,8 @@ private: #define PTYP_INVALID 0 #define PTYP_DATA 0xFF +#endif // NEW_IMPL + #define FROL_NAME 1 #define FROL_TEXT_VALUE 2 diff --git a/client/port.cpp b/client/port.cpp index 2196e7d..89d94c3 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -5,88 +5,177 @@ #include "port.h" #include "pbhelper.h" +uint Port::mAllocStreamId = 0; + +uint Port::newStreamId() +{ + return mAllocStreamId++; +} Port::Port(quint32 id, quint32 portGroupId) { - d.set_port_id(id); + mPortId = id; + d.mutable_port_id()->set_id(id); mPortGroupId = portGroupId; - - -#if 0 // PB - // FIXME(HI): TEST only - for(int i = 0; i < 10; i++) - mPortStats[i] = mPortGroupId*10000+mPortId*100+i; -#endif } -void Port::updatePortConfig(OstProto::PortConfig *portConfig) +void Port::updatePortConfig(OstProto::Port *port) { + d.MergeFrom(*port); +} - PbHelper pbh; +void Port::updateStreamOrdinalsFromIndex() +{ + for (int i=0; i < mStreams.size(); i++) + mStreams[i].setOrdinal(i); +} - pbh.update(&d, portConfig); -#if 0 - const ::google::protobuf::Message::Reflection *ref1; - ::google::protobuf::Message::Reflection *ref2; - std::vector list; +void Port::reorderStreamsByOrdinals() +{ + qSort(mStreams); +} - qDebug("In %s", __FUNCTION__); +bool Port::newStreamAt(int index) +{ + Stream s; - ref1 = portConfig.GetReflection(); - ref1->ListFields(&list); + if (index > mStreams.size()) + return false; - ref2 = d.GetReflection(); + s.setId(newStreamId()); + mStreams.insert(index, s); + updateStreamOrdinalsFromIndex(); - for (uint i=0; i < list.size(); i++) + return true; +} + +bool Port::deleteStreamAt(int index) +{ + if (index >= mStreams.size()) + return false; + + mStreams.removeAt(index); + updateStreamOrdinalsFromIndex(); + + return true; +} + +bool Port::insertStream(uint streamId) +{ + Stream s; + + s.setId(streamId); + + // FIXME(MED): If a stream with id already exists, what do we do? + mStreams.append(s); + + // Update mAllocStreamId to take into account the stream id received + // from server + if (mAllocStreamId <= streamId) + mAllocStreamId = streamId + 1; + + return true; +} + +bool Port::updateStream(uint streamId, OstProto::Stream *stream) +{ + int i, streamIndex; + + for (i = 0; i < mStreams.size(); i++) { - const ::google::protobuf::FieldDescriptor *f1, *f2; + if (streamId == mStreams[i].id()) + goto _found; + } - f1 = list[i]; - f2 = d.GetDescriptor()->FindFieldByName(f1->name()); - switch(f2->type()) + qDebug("%s: Invalid stream id %d", __FUNCTION__, streamId); + return false; + +_found: + streamIndex = i; + + mStreams[streamIndex].update(stream); + reorderStreamsByOrdinals(); + + return true; +} + +void Port::getDeletedStreamsSinceLastSync( + OstProto::StreamIdList &streamIdList) +{ + streamIdList.clear_stream_id(); + for (int i = 0; i < mLastSyncStreamList.size(); i++) + { + int j; + + for (j = 0; j < mStreams.size(); j++) { - case ::google::protobuf::FieldDescriptor::TYPE_UINT32: - ref2->SetUInt32(f2, ref1->GetUInt32(f1)); - break; - case ::google::protobuf::FieldDescriptor::TYPE_BOOL: - ref2->SetBool(f2, ref1->GetBool(f1)); - break; - case ::google::protobuf::FieldDescriptor::TYPE_STRING: - ref2->SetString(f2, ref1->GetString(f1)); - break; - default: - qDebug("unhandled Field Type"); - break; + if (mLastSyncStreamList[i] == mStreams[j].id()) + break; + } + + if (j < mStreams.size()) + { + // stream still exists! + continue; + } + else + { + // stream has been deleted since last sync + OstProto::StreamId *s; + + s = streamIdList.add_stream_id(); + s->set_id(mLastSyncStreamList.at(i)); } } - - if (msg->GetDescriptor() != OstProto::PortConfig::descriptor()) - { - qDebug("%s: invalid Message Descriptor (%s)", __FUNCTION__, - msg->GetDescriptor()->name()); - goto _error_exit; - } - - portConfig = msg; - - // check for "required" param - if (!portConfig.has_port_id()) - { - qDebug("%s: invalid Message Descriptor (%s)", __FUNCTION__, - msg->GetDescriptor()->name()); - goto _error_exit; - } -#endif } -void Port::insertDummyStreams() +void Port::getNewStreamsSinceLastSync( + OstProto::StreamIdList &streamIdList) { - mStreams.append(*(new Stream)); - mStreams[0].setName(QString("%1:%2:0").arg(portGroupId()).arg(id())); -#if 1 - mStreams.append(*(new Stream)); - mStreams[1].setName(QString("%1:%2:1").arg(portGroupId()).arg(id())); -#endif + streamIdList.clear_stream_id(); + for (int i = 0; i < mStreams.size(); i++) + { + if (mLastSyncStreamList.contains(mStreams[i].id())) + { + // existing stream! + continue; + } + else + { + // new stream! + OstProto::StreamId *s; + + s = streamIdList.add_stream_id(); + s->set_id(mStreams[i].id()); + } + } +} + +void Port::getModifiedStreamsSinceLastSync( + OstProto::StreamConfigList &streamConfigList) +{ + qDebug("In %s", __FUNCTION__); + + //streamConfigList.mutable_port_id()->set_id(mPortId); + for (int i = 0; i < mStreams.size(); i++) + { + OstProto::Stream *s; + + s = streamConfigList.add_stream(); + mStreams[i].getConfig(mPortId, s); + } } +// +// ----------- SLOTS ------------- +// +void Port::when_syncComplete() +{ + qSort(mStreams); + + mLastSyncStreamList.clear(); + for (int i=0; i #include "stream.h" -class StreamModel; +//class StreamModel; class Port { -#if 0 // PB - friend class PortStatsModel; -#endif - friend class StreamModel; - - //friend class PbHelper; - - // FIXME: non-friend mechanism - //friend QList* StreamModel::currentPortStreamList(void); + //friend class StreamModel; private: - OstProto::PortConfig d; + static uint mAllocStreamId; + OstProto::Port d; + // FIXME(HI): consider removing mPortId as it is duplicated inside 'd' quint32 mPortId; quint32 mPortGroupId; QString mUserAlias; // user defined - QList mStreams; - -#if 0 // PB - quint32 mPortId; - QString mName; - QString mDescription; - AdminStatus mAdminStatus; - OperStatus mOperStatus; - ControlMode mControlMode; - - quint32 mPortStats[10]; // FIXME(HI):Hardcoding -#endif + QList mLastSyncStreamList; + QList mStreams; // sorted by stream's ordinal value + uint newStreamId(); + void updateStreamOrdinalsFromIndex(); + void reorderStreamsByOrdinals(); public: enum AdminStatus { AdminDisable, AdminEnable }; enum OperStatus { OperDown, OperUp }; @@ -52,7 +39,7 @@ public: const QString& userAlias() const { return mUserAlias; } quint32 id() const - { return d.port_id(); } + { return d.port_id().id(); } const QString name() const { return QString().fromStdString(d.name()); } const QString description() const @@ -75,10 +62,34 @@ public: void setAlias(QString &alias) { mUserAlias = alias; } //void setExclusive(bool flag); - void updatePortConfig(OstProto::PortConfig *portConfig); + int numStreams() { return mStreams.size(); } + Stream& streamByIndex(int index) + { + Q_ASSERT(index < mStreams.size()); + return mStreams[index]; + } - // FIXME(HIGH): Only for testing - void insertDummyStreams(); + // FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal + void updatePortConfig(OstProto::Port *port); + + //! Used by StreamModel + //@{ + bool newStreamAt(int index); + bool deleteStreamAt(int index); + //@} + + //! Used by MyService::Stub to update from config received from server + //@{ + bool insertStream(uint streamId); + bool updateStream(uint streamId, OstProto::Stream *stream); + //@} + + void getDeletedStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); + void getNewStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); + void getModifiedStreamsSinceLastSync( + OstProto::StreamConfigList &streamConfigList); + + void when_syncComplete(); }; #endif diff --git a/client/portgroup.cpp b/client/portgroup.cpp index fa5fa0e..3de90cc 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -10,29 +10,12 @@ PortGroup::PortGroup(QHostAddress ip, quint16 port) // Allocate an id for self mPortGroupId = PortGroup::mPortGroupAllocId++; -#if 0 // PB - // Init attributes for which we values were passed to us - mServerAddress = ip; - mServerPort = port; - - // Init remaining attributes with defaults - mpSocket = new QTcpSocket(this); -#endif - rpcChannel = new PbRpcChannel(ip, port); rpcController = new PbRpcController(); serviceStub = new OstProto::OstService::Stub(rpcChannel, OstProto::OstService::STUB_OWNS_CHANNEL); -#if 0 // PB - // TODO: consider using QT's signal-slot autoconnect - connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(on_mpSocket_stateChanged())); - connect(mpSocket, SIGNAL(connected()), this, SLOT(when_connected())); - connect(mpSocket, SIGNAL(disconnected()), this, SLOT(when_disconnected())); - connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(when_error(QAbstractSocket::SocketError))); - connect(mpSocket, SIGNAL(readyRead()), this, SLOT(when_dataAvail())); -#endif - // FIXME:Can't for my life figure out why this ain't working! + // FIXME(LOW):Can't for my life figure out why this ain't working! //QMetaObject::connectSlotsByName(this); connect(rpcChannel, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(on_rpcChannel_stateChanged())); @@ -52,92 +35,6 @@ PortGroup::~PortGroup() delete serviceStub; } -#if 0 // PB -void PortGroup::connectToHost(QHostAddress ip, quint16 port) -{ - rpcChannel->establish(ip, port) -} - -void PortGroup::connectToHost() -{ - qDebug("PortGroup::connectToHost()"); - rpcChannel->establish() -} - -void PortGroup::disconnectFromHost() -{ - mpSocket->disconnectFromHost(); -} -#endif - -#if 0 // PB -// -------------------------------------------- -// Private Methods -// -------------------------------------------- -void PortGroup::ProcessMsg(const char *msg, quint32 size) -{ - tCommHdr *hdr; - // TODO: For now, assuming we'll get a complete msg - // but need to fix this as this is a TCP stream - - hdr = (tCommHdr*) msg; - - if (hdr->ver != 1) // FIXME:hardcoding - { - qDebug("Rcvd msg with invalid version %d\n", hdr->ver); - goto _exit; - } - - qDebug("msgType - %x\n", NTOHS(hdr->msgType)); - switch (NTOHS(hdr->msgType)) - { - case e_MT_CapabilityInfo: - ProcessCapabilityInfo(msg+sizeof(tCommHdr), - NTOHS(hdr->msgLen)-sizeof(tCommHdr)); - break; - - default: - qDebug("Rcvd msg with unrecognized msgType %d\n", NTOHS(hdr->msgType)); - } - -_exit: - return; -} - -void PortGroup::ProcessCapabilityInfo(const char *msg, qint32 size) -{ - tTlvPortCapability *cap = (tTlvPortCapability*) msg; - Port *p; - - emit portListAboutToBeChanged(mPortGroupId); - - while (size) - { - qDebug("size = %d, tlvType = %d, tlvLen = %d\n", - size, NTOHS(cap->tlvType), NTOHS(cap->tlvLen)); - if (NTOHS(cap->tlvType) != e_TT_PortCapability) - { - qDebug("Unrecognized TLV Type %d\n", NTOHS(cap->tlvType)); - goto _next; - } - - p = new Port(NTOHL(cap->portId), mPortGroupId); - p->setName(cap->portName); - p->setDescription(cap->portDesc); - p->insertDummyStreams(); // FIXME: only for testing - qDebug("before port append\n"); - mPorts.append(*p); - -_next: - size -= NTOHS(cap->tlvLen); - cap = (tTlvPortCapability*)((char *)(cap) + NTOHS(cap->tlvLen)); - } - - emit portListChanged(mPortGroupId); - - return; -} -#endif // ------------------------------------------------ // Slots @@ -161,18 +58,6 @@ void PortGroup::on_rpcChannel_connected() rpcController->Reset(); serviceStub->getPortIdList(rpcController, &void_, portIdList, NewCallback(this, &PortGroup::processPortIdList, portIdList)); - -#if 0 // PB - // Ask for Port Capability - tCommHdr pkt; - pkt.ver = 1; - pkt.resv1 = 0; - pkt.resv2 = 0; - pkt.msgType = HTONS(e_MT_GetCapability); - pkt.msgLen = HTONS(8); - - mpSocket->write((char*) &pkt, sizeof(pkt)); -#endif } void PortGroup::on_rpcChannel_disconnected() @@ -190,20 +75,94 @@ void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) emit portGroupDataChanged(this); } -#if 0 // PB -void PortGroup::when_dataAvail() +void PortGroup::when_configApply(int portIndex, uint *cookie) { - qDebug("dataAvail\n"); - - QByteArray msg = mpSocket->read(1024); // FIXME: hardcoding - ProcessMsg(msg.constData(), msg.size()); + uint *op; + OstProto::Ack *ack; + + Q_ASSERT(portIndex < mPorts.size()); + + if (cookie == NULL) + { + // cookie[0]: op [0 - delete, 1 - add, 2 - modify, 3 - Done!] + // cookie[1]: *ack + cookie = new uint[2]; + ack = new OstProto::Ack; + + cookie[0] = (uint) 0; + cookie[1] = (uint) ack; + } + else + { + ack = (OstProto::Ack*) cookie[1]; + } + + Q_ASSERT(cookie != NULL); + op = &cookie[0]; + + switch (*op) + { + case 0: + { + OstProto::StreamIdList streamIdList; + + qDebug("applying 'deleted streams' ..."); + + streamIdList.mutable_port_id()->set_id(mPorts[portIndex].id()); + mPorts[portIndex].getDeletedStreamsSinceLastSync(streamIdList); + + (*op)++; + rpcController->Reset(); + serviceStub->deleteStream(rpcController, &streamIdList, ack, + ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); + break; + } + + case 1: + { + OstProto::StreamIdList streamIdList; + + qDebug("applying 'new streams' ..."); + + streamIdList.mutable_port_id()->set_id(mPorts[portIndex].id()); + mPorts[portIndex].getNewStreamsSinceLastSync(streamIdList); + + (*op)++; + rpcController->Reset(); + serviceStub->addStream(rpcController, &streamIdList, ack, + ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); + break; + } + + case 2: + { + OstProto::StreamConfigList streamConfigList; + + qDebug("applying 'modified streams' ..."); + + streamConfigList.mutable_port_id()->set_id(mPorts[portIndex].id()); + mPorts[portIndex].getModifiedStreamsSinceLastSync(streamConfigList); + + (*op)++; + rpcController->Reset(); + serviceStub->modifyStream(rpcController, &streamConfigList, ack, + ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); + break; + } + + case 3: + qDebug("apply completed"); + delete cookie; + break; + + default: + qDebug("%s: Unknown Op!!!", __FUNCTION__); + break; + } } -#endif void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) { - int count; - qDebug("got a portlist ..."); if (rpcController->Failed()) @@ -212,26 +171,21 @@ void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) goto _error_exit; } - count = portIdList->port_id_size(); - qDebug("%s: portid count = %d", __FUNCTION__, count); - qDebug("%s: %s", __FUNCTION__, portIdList->DebugString().c_str()); - emit portListAboutToBeChanged(mPortGroupId); - for(int i = 0; i < count; i++) + for(int i = 0; i < portIdList->port_id_size(); i++) { Port *p; - p = new Port(portIdList->port_id(i), mPortGroupId); - //p->setName("name"); - //p->setDescription("Desc"); - p->insertDummyStreams(); // FIXME: only for testing + p = new Port(portIdList->port_id(i).id(), mPortGroupId); qDebug("before port append\n"); mPorts.append(*p); } emit portListChanged(mPortGroupId); + this->portIdList.CopyFrom(*portIdList); + // Request PortConfigList { OstProto::PortConfigList *portConfigList; @@ -253,8 +207,6 @@ _exit: void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) { - int count; - qDebug("In %s", __FUNCTION__); if (rpcController->Failed()) @@ -263,19 +215,15 @@ void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) goto _error_exit; } - count = portConfigList->list_size(); - qDebug("%s: count = %d", __FUNCTION__, count); - qDebug("%s: <%s>", __FUNCTION__, portConfigList->DebugString().c_str()); - emit portListAboutToBeChanged(mPortGroupId); - for(int i = 0; i < count; i++) + for(int i = 0; i < portConfigList->port_size(); i++) { uint id; - id = portConfigList->list(i).port_id(); + id = portConfigList->port(i).port_id().id(); // FIXME: don't mix port id & index into mPorts[] - mPorts[id].updatePortConfig(portConfigList->mutable_list(i)); + mPorts[id].updatePortConfig(portConfigList->mutable_port(i)); } emit portListChanged(mPortGroupId); @@ -283,6 +231,185 @@ void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) // FIXME: check if we need new signals since we are not changing the // number of ports, just the port data + if (numPorts() > 0) + getStreamIdList(); + _error_exit: delete portConfigList; } + +void PortGroup::getStreamIdList(int portIndex, + OstProto::StreamIdList *streamIdList) +{ + ::OstProto::PortId portId; + + qDebug("In %s", __FUNCTION__); + + if (streamIdList == NULL) + { + // First invocation (uses default params) - + // request StreamIdList for first port + + Q_ASSERT(portIndex == 0); + Q_ASSERT(numPorts() > 0); + streamIdList = new ::OstProto::StreamIdList(); + + goto _request; + } + + qDebug("got a streamIdlist ..."); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _next_port; // FIXME(MED): Partial RPC + } + + Q_ASSERT(portIndex < numPorts()); + + if (streamIdList->port_id().id() != mPorts[portIndex].id()) + { + qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", + __FUNCTION__, streamIdList->port_id().id(), mPorts[portIndex].id(), + portIndex); + goto _next_port; // FIXME(MED): Partial RPC + } + + // FIXME(MED): need to mPorts.clear()??? + for(int i = 0; i < streamIdList->stream_id_size(); i++) + { + uint streamId; + + streamId = streamIdList->stream_id(i).id(); + mPorts[portIndex].insertStream(streamId); + } + +_next_port: + // FIXME(HI): ideally we shd use signals/slots but this means + // we will have to use Port* instead of Port with QList<> - + // need to find a way for this + mPorts[portIndex].when_syncComplete(); + portIndex++; + if (portIndex >= numPorts()) + { + // We're done for all ports !!! + + // FIXME(HI): some way to reset streammodel + + delete streamIdList; + + if (numPorts() > 0) + getStreamConfigList(); + + goto _exit; + } + +_request: + portId.set_id(mPorts[portIndex].id()); + streamIdList->Clear(); + + rpcController->Reset(); + serviceStub->getStreamIdList(rpcController, &portId, streamIdList, + NewCallback(this, &PortGroup::getStreamIdList, + portIndex, streamIdList)); + + goto _exit; + + + +_exit: + return; +} + +void PortGroup::getStreamConfigList(int portIndex, + OstProto::StreamConfigList *streamConfigList) +{ + OstProto::StreamIdList streamIdList; + + qDebug("In %s", __PRETTY_FUNCTION__); + + if (streamConfigList == NULL) + { + // First invocation using default params + // - request for first port + + Q_ASSERT(portIndex == 0); + Q_ASSERT(numPorts() > 0); + + streamConfigList = new OstProto::StreamConfigList; + + goto _request; + } + + qDebug("got a streamconfiglist"); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _next_port; + } + + Q_ASSERT(portIndex < numPorts()); + + if (streamConfigList->port_id().id() != mPorts[portIndex].id()) + { + qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", + __FUNCTION__, streamConfigList->port_id().id(), + mPorts[portIndex].id(), portIndex); + goto _next_port; // FIXME(MED): Partial RPC + } + + // FIXME(MED): need to mStreams.clear()??? + for(int i = 0; i < streamConfigList->stream_size(); i++) + { + uint streamId; + + streamId = streamConfigList->stream(i).stream_id().id(); + mPorts[portIndex].updateStream(streamId, + streamConfigList->mutable_stream(i)); + } + +_next_port: + portIndex++; + + if (portIndex >= numPorts()) + { + // We're done for all ports !!! + + // FIXME(HI): some way to reset streammodel + + delete streamConfigList; + goto _exit; + } + +_request: + qDebug("requesting stream config list ..."); + + streamIdList.Clear(); + streamIdList.mutable_port_id()->set_id(mPorts[portIndex].id()); + for (int j = 0; j < mPorts[portIndex].numStreams(); j++) + { + OstProto::StreamId *s; + + s = streamIdList.add_stream_id(); + s->set_id(mPorts[portIndex].streamByIndex(j).id()); + } + streamConfigList->Clear(); + + rpcController->Reset(); + serviceStub->getStreamConfig(rpcController, + &streamIdList, streamConfigList, NewCallback(this, + &PortGroup::getStreamConfigList, portIndex, streamConfigList)); + +_exit: + return; +} + +void PortGroup::processModifyStreamAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + qDebug("Modify Successful!!"); + + // TODO(HI): Apply Button should now be disabled???!!!!??? +} diff --git a/client/portgroup.h b/client/portgroup.h index 528f48b..89c02af 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -31,7 +31,9 @@ private: #endif PbRpcChannel *rpcChannel; ::google::protobuf::RpcController *rpcController; - OstProto::OstService::Stub *serviceStub; + ::OstProto::OstService::Stub *serviceStub; + + ::OstProto::PortIdList portIdList; public: // FIXME(HIGH): member access QList mPorts; @@ -61,6 +63,12 @@ public: void processPortIdList(OstProto::PortIdList *portIdList); void processPortConfigList(OstProto::PortConfigList *portConfigList); + void getStreamIdList(int portIndex = 0, + OstProto::StreamIdList *streamIdList = NULL); + void getStreamConfigList(int portIndex = 0, + OstProto::StreamConfigList *streamConfigList = NULL); + + void processModifyStreamAck(OstProto::Ack *ack); signals: void portGroupDataChanged(PortGroup* portGroup); void portListAboutToBeChanged(quint32 portGroupId); @@ -71,6 +79,9 @@ private slots: void on_rpcChannel_connected(); void on_rpcChannel_disconnected(); void on_rpcChannel_error(QAbstractSocket::SocketError socketError); + +public slots: + void when_configApply(int portIndex, uint *cookie = NULL); #if 0 // PB void on_rpcChannel_when_dataAvail(); #endif diff --git a/client/portgrouplist.h b/client/portgrouplist.h index 1e5add9..84bdb9c 100644 --- a/client/portgrouplist.h +++ b/client/portgrouplist.h @@ -31,6 +31,7 @@ public: PortModel* getPortModel() { return &mPortGroupListModel; } PortStatsModel* getPortStatsModel() { return &mPortStatsModel; } StreamModel* getStreamModel() { return &mStreamListModel; } + bool isPortGroup(const QModelIndex& index); bool isPort(const QModelIndex& index); PortGroup& portGroup(const QModelIndex& index); diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 435344c..5da586b 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -73,7 +73,8 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const { #if 0 // PB return pgl->mPortGroups.at(pgidx)->mPorts.at(pidx).mPortStats[index.row()]; -#endif return 0; //FIXME: Get actual port stats +#endif + return 0; //FIXME: Get actual port stats } else return QVariant(); diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 2e6df17..f711f55 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -56,9 +56,13 @@ void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) qDebug("%s: invalid index", __FUNCTION__); return; } +#if 0 // CleanedUp! // FIXME(MED): This way of passing params must be changed scd = new StreamConfigDialog(plm->getStreamModel()->currentPortStreamList(), (uint) index.row(), this); +#endif + scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()), + index.row(), this); qDebug("stream list activated\n"); scd->exec(); // TODO: chk retval delete scd; @@ -206,7 +210,43 @@ _EXIT: void PortsWindow::on_pbApply_clicked() { -{ + QModelIndex curPort; + QModelIndex curPortGroup; + + curPort = tvPortList->selectionModel()->currentIndex(); + if (!curPort.isValid()) + { + qDebug("%s: curPort is invalid", __FUNCTION__); + goto _exit; + } + + if (!plm->isPort(curPort)) + { + qDebug("%s: curPort is not a port", __FUNCTION__); + goto _exit; + } + + curPortGroup = plm->getPortModel()->parent(curPort); + if (!curPortGroup.isValid()) + { + qDebug("%s: curPortGroup is invalid", __FUNCTION__); + goto _exit; + } + if (!plm->isPortGroup(curPortGroup)) + { + qDebug("%s: curPortGroup is not a portGroup", __FUNCTION__); + goto _exit; + } + + // FIXME(HI): shd this be a signal? + //portGroup.when_configApply(port); + // FIXME(MED): mixing port id and index!!! + plm->portGroup(curPortGroup).when_configApply(plm->port(curPort).id()); + +_exit: + return; + +#if 0 // TODO (LOW): This block is for testing only QModelIndex current = tvPortList->selectionModel()->currentIndex(); @@ -214,7 +254,7 @@ void PortsWindow::on_pbApply_clicked() qDebug("current = %llx", current.internalId()); else qDebug("current is invalid"); -} +#endif } void PortsWindow::on_actionNew_Port_Group_triggered() diff --git a/client/stream.cpp b/client/stream.cpp index e153b8e..30568e5 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -1,134 +1,851 @@ -#include +#include + +#include "stream.h" + +#include + +#define BASE_HEX 16 + +QString MacProtocol::fieldName(int index) +{ + QString name; + + switch(index) + { + case 0: + name = QString("Destination Mac Address"); + break; + case 1: + name = QString("Source Mac Address"); + break; + default: + name = QString(); + break; + } + + return name; +} + +QString MacProtocol::fieldTextValue(int index) +{ + QString textValue; + + // FIXME(MED): Mac Addr formatting + switch(index) + { + case 0: + textValue = QString("%1"). + arg(dstMac(), 12, BASE_HEX, QChar('0')); + break; + case 1: + textValue = QString("%1"). + arg(srcMac(), 12, BASE_HEX, QChar('0')); + break; + default: + textValue = QString(); + break; + } + + return textValue; +} + +QByteArray MacProtocol::fieldRawValue(int index) +{ + QByteArray rawValue; + + return rawValue; +} + +QString LlcProtocol::fieldName(int index) +{ + QString name; + + switch(index) + { + case 0: + name = QString("DSAP"); + break; + case 1: + name = QString("SSAP"); + break; + case 2: + name = QString("Control"); + break; + default: + name = QString(); + break; + } + + return name; +} + +QString LlcProtocol::fieldTextValue(int index) +{ + QString textValue; + + switch(index) + { + case 0: + textValue = QString("0x%1"). + arg(dsap(), 2, BASE_HEX, QChar('0')); + break; + case 1: + textValue = QString("0x%1"). + arg(ssap(), 2, BASE_HEX, QChar('0')); + break; + case 2: + textValue = QString("0x%1"). + arg(ctl(), 2, BASE_HEX, QChar('0')); + break; + default: + textValue = QString(); + break; + } + + return textValue; +} + +QByteArray LlcProtocol::fieldRawValue(int index) +{ + QByteArray rawValue; + + return rawValue; +} + +QString SnapProtocol::fieldName(int index) +{ + QString name; + + switch(index) + { + case 0: + name = QString("OUI"); + break; + default: + name = QString(); + break; + } + + return name; +} + +QString SnapProtocol::fieldTextValue(int index) +{ + QString textValue; + + switch(index) + { + case 0: + textValue = QString("0x%1"). + arg(oui(), 6, BASE_HEX, QChar('0')); + break; + default: + textValue = QString(); + break; + } + + return textValue; +} + +QByteArray SnapProtocol::fieldRawValue(int index) +{ + QByteArray rawValue; + + return rawValue; +} + +QString Eth2Protocol::fieldName(int index) +{ + QString name; + + switch(index) + { + case 0: + name = QString("Type"); + break; + default: + name = QString(); + break; + } + return name; +} + +QString Eth2Protocol::fieldTextValue(int index) +{ + QString textValue; + + switch(index) + { + case 0: + textValue = QString("0x%1"). + arg(type(), 4, BASE_HEX, QChar('0')); + break; + default: + textValue = QString(); + break; + } + return textValue; +} + +QByteArray Eth2Protocol::fieldRawValue(int index) +{ + QByteArray rawValue; + + return rawValue; +} + +int VlanProtocol::numFields() +{ + if (isSingleTagged()) + return 4; + else if (isDoubleTagged()) + return 8; + else + { + Q_ASSERT(isUntagged()); + return 0; + } +} + +QString VlanProtocol::fieldName(int index) +{ + QString name; + + if (isDoubleTagged()) + { + switch(index) + { + case 0: + name = QString("TPID"); + break; + case 1: + name = QString("PCP"); + break; + case 2: + name = QString("DE"); + break; + case 3: + name = QString("VlanId"); + break; + default: + index -= 4; + goto _single_tag; + } + + goto _exit; + } + +_single_tag: + switch(index) + { + case 0: + name = QString("TPID"); + break; + case 1: + name = QString("Priority"); + break; + case 2: + name = QString("CFI"); + break; + case 3: + name = QString("VlanId"); + break; + default: + name = QString(); + break; + } + +_exit: + return name; +} + +QString VlanProtocol::fieldTextValue(int index) +{ + QString textValue; + + if (isDoubleTagged()) + { + switch(index) + { + case 0: + textValue = QString("0x%1"). + arg(stpid(), 4, BASE_HEX, QChar('0')); + break; + case 1: + textValue = QString("%1"). + arg(svlanPrio()); + break; + case 2: + textValue = QString("%1"). + arg(svlanCfi()); + break; + case 3: + textValue = QString("%1"). + arg(svlanId()); + break; + default: + index -= 4; + goto _single_tag; + } + + goto _exit; + } + +_single_tag: + switch(index) + { + case 0: + textValue = QString("0x%1"). + arg(ctpid(), 4, BASE_HEX, QChar('0')); + break; + case 1: + textValue = QString("%1"). + arg(cvlanPrio()); + break; + case 2: + textValue = QString("%1"). + arg(cvlanCfi()); + break; + case 3: + textValue = QString("%1"). + arg(cvlanId()); + break; + default: + textValue = QString(); + break; + } + +_exit: + return textValue; +} + +QByteArray VlanProtocol::fieldRawValue(int index) +{ + QByteArray rawValue; + + return rawValue; +} + +QString IpProtocol::fieldName(int index) +{ + QString name; + + switch(index) + { + case 0: + name = QString("Version"); + break; + case 1: + name = QString("Header Length"); + break; + case 2: + name = QString("TOS/DSCP"); + break; + case 3: + name = QString("Total Length"); + break; + case 4: + name = QString("ID"); + break; + case 5: + name = QString("Flags"); + break; + case 6: + name = QString("Fragment Offset"); + break; + case 7: + name = QString("TTL"); + break; + case 8: + name = QString("Protocol Type"); + break; + case 9: + name = QString("Checksum"); + break; + case 10: + name = QString("Source IP"); + break; + case 11: + name = QString("Destination IP"); + break; + default: + name = QString(); + } + + return name; +} + +QString IpProtocol::fieldTextValue(int index) +{ + QString textValue; + + switch(index) + { + case 0: + textValue = QString("%1"). + arg(ver()); + break; + case 1: + textValue = QString("%1"). + arg(hdrLen()); + break; + case 2: + textValue = QString("0x%1"). + arg(tos(), 2, BASE_HEX, QChar('0')); + break; + case 3: + textValue = QString("%1"). + arg(totLen()); + break; + case 4: + textValue = QString("0x%1"). + arg(id(), 2, BASE_HEX, QChar('0')); + break; + case 5: + textValue = QString("0x%1"). + arg(flags(), 2, BASE_HEX, QChar('0')); // FIXME(MED): bitmap? + break; + case 6: + textValue = QString("%1"). + arg(fragOfs()); + break; + case 7: + textValue = QString("%1"). + arg(ttl()); + break; + case 8: + textValue = QString("0x%1"). + arg(proto(), 2, BASE_HEX, QChar('0')); + break; + case 9: + textValue = QString("0x%1"). + arg(cksum(), 4, BASE_HEX, QChar('0')); + break; + case 10: + textValue = QHostAddress(srcIp()).toString(); + break; + case 11: + textValue = QHostAddress(dstIp()).toString(); + break; + default: + textValue = QString(); + } + + return textValue; +} + +QByteArray IpProtocol::fieldRawValue(int index) +{ + QByteArray rawValue; + + return rawValue; +} + +QString TcpProtocol::fieldName(int index) +{ + QString name; + + switch(index) + { + case 0: + name = QString("Source Port"); + break; + case 1: + name = QString("Destination Port"); + break; + case 2: + name = QString("Seq Number"); + break; + case 3: + name = QString("Ack Number"); + break; + case 4: + name = QString("Header Length"); + break; + case 5: + name = QString("Reserved"); + break; + case 6: + name = QString("Flags"); + break; + case 7: + name = QString("Window"); + break; + case 8: + name = QString("Checksum"); + break; + case 9: + name = QString("Urgent Pointer"); + break; + default: + name = QString(); + } + + return name; +} + +QString TcpProtocol::fieldTextValue(int index) +{ + QString textValue; + + switch(index) + { + case 0: + textValue = QString("%1"). + arg(srcPort()); + break; + case 1: + textValue = QString("%1"). + arg(dstPort()); + break; + case 2: + textValue = QString("%1"). + arg(seqNum()); + break; + case 3: + textValue = QString("%1"). + arg(ackNum()); + break; + case 4: + textValue = QString("%1"). + arg(hdrLen()); + break; + case 5: + textValue = QString("%1"). + arg(rsvd()); + break; + case 6: + textValue = QString("0x%1"). + arg(flags(), 2, BASE_HEX, QChar('0')); + break; + case 7: + textValue = QString("%1"). + arg(flags()); + break; + case 8: + textValue = QString("0x%1"). + arg(cksum(), 4, BASE_HEX, QChar('0')); + break; + case 9: + textValue = QString("%1"). + arg(urgPtr()); + break; + default: + textValue = QString(); + } + + return textValue; +} + +QByteArray TcpProtocol::fieldRawValue(int index) +{ + QByteArray rawValue; + + return rawValue; +} + +QString UdpProtocol::fieldName(int index) +{ + QString name; + + switch(index) + { + case 0: + name = QString("Source Port"); + break; + case 1: + name = QString("Destination Port"); + break; + case 2: + name = QString("Total Length"); + break; + case 3: + name = QString("Checksum"); + break; + default: + name = QString(); + } + + return name; +} + +QString UdpProtocol::fieldTextValue(int index) +{ + QString textValue; + + switch(index) + { + case 0: + textValue = QString("%1"). + arg(srcPort()); + break; + case 1: + textValue = QString("%1"). + arg(dstPort()); + break; + case 2: + textValue = QString("%1"). + arg(totLen()); + break; + case 3: + textValue = QString("0x%1"). + arg(cksum(), 4, BASE_HEX, QChar('0')); + break; + default: + textValue = QString(); + } + + return textValue; +} + +QByteArray UdpProtocol::fieldRawValue(int index) +{ + QByteArray rawValue; + + return rawValue; +} + + + +//----------------------------------------------------- +// Stream Class Methods +//----------------------------------------------------- -quint32 Stream::mAllocId = 0; Stream::Stream() { - mId = mAllocId++; - + mId = 0xFFFFFFFF; + mCore = new OstProto::StreamCore; + +// mCore->set_port_id(0xFFFFFFFF); +// mCore->set_stream_id(mId); + + mUnknown = new UnknownProtocol; + mMac = new MacProtocol; + + mLlc = new LlcProtocol; + mSnap = new SnapProtocol; + mEth2 = new Eth2Protocol; + mVlan = new VlanProtocol; + mIp = new IpProtocol; -#if 0 - // Default constructor - InitDefaultMeta(); - InitDefaultProto(); - InitDefaultL2(); - InitDefaultL3(); - InitDefaultL4(); -#endif + mArp = new ArpProtocol; + + mTcp = new TcpProtocol; + mUdp = new UdpProtocol; + mIcmp = new IcmpProtocol; + mIgmp = new IgmpProtocol; +} + +void Stream::getConfig(uint portId, OstProto::Stream *s) +{ + s->mutable_stream_id()->set_id(mId); + + s->mutable_core()->CopyFrom(*mCore); + + mMac->getConfig(s->mutable_mac()); + mMac->getConfig(s->mutable_mac()); + mLlc->getConfig(s->mutable_llc()); + mSnap->getConfig(s->mutable_snap()); + mEth2->getConfig(s->mutable_eth2()); + mVlan->getConfig(s->mutable_vlan()); + + mIp->getConfig(s->mutable_ip()); + mArp->getConfig(s->mutable_arp()); + + mTcp->getConfig(s->mutable_tcp()); + mUdp->getConfig(s->mutable_udp()); + mIcmp->getConfig(s->mutable_icmp()); + mIgmp->getConfig(s->mutable_igmp()); +} + +// FIXME(HIGH): Replace this by some Protocol Registration mechanism at Init +#define PTYP_L2_NONE 1 +#define PTYP_L2_ETH_2 2 +#define PTYP_L2_802_3_RAW 3 + +#define PTYP_L2_802_3_LLC 4 +#define PTYP_L2_SNAP 5 + +#define PTYP_VLAN 10 + +#define PTYP_L3_IP 30 +#define PTYP_L3_ARP 31 + +#define PTYP_L4_TCP 40 +#define PTYP_L4_UDP 41 +#define PTYP_L4_ICMP 42 +#define PTYP_L4_IGMP 43 + +#define PTYP_INVALID 0 +#define PTYP_DATA 0xFF + +void Stream::updateSelectedProtocols() +{ + int proto; + + // Clear the selected protocols list + selectedProtocols.clear(); + + // Check and populate L2 Protocol + switch(frameType()) + { + case Stream::e_ft_none: + proto = PTYP_L2_NONE; + break; + + case Stream::e_ft_eth_2: + selectedProtocols.append(PTYP_L2_NONE); + proto = PTYP_L2_ETH_2; + break; + + case Stream::e_ft_802_3_raw: + selectedProtocols.append(PTYP_L2_NONE); + proto = PTYP_L2_802_3_RAW; + break; + + case Stream::e_ft_802_3_llc: + selectedProtocols.append(PTYP_L2_NONE); + proto = PTYP_L2_802_3_LLC; + break; + + case Stream::e_ft_snap: + selectedProtocols.append(PTYP_L2_NONE); + selectedProtocols.append(PTYP_L2_802_3_LLC); + proto = PTYP_L2_SNAP; + break; + + default: + qDebug("%s: Unsupported frametype %d", __FUNCTION__, + frameType()); + proto = PTYP_INVALID; + } + selectedProtocols.append(proto); + + // Check and populate VLANs, if present + if (!vlan()->isUntagged()) + selectedProtocols.append(PTYP_VLAN); + + // Check and populate L3 protocols + switch (l3Proto()) + { + case Stream::e_l3_none : + goto _data; + break; + + case Stream::e_l3_ip : + proto = PTYP_L3_IP; + break; + + case Stream::e_l3_arp: + proto = PTYP_L3_ARP; + break; + + default: + qDebug("%s: Unsupported L3 Proto %d", __FUNCTION__, + l3Proto()); + proto = PTYP_INVALID; + } + selectedProtocols.append(proto); + + // Check and populate L4 protocol + switch(l4Proto()) + { + case Stream::e_l4_none: + goto _data; + break; + case Stream::e_l4_tcp: + proto = PTYP_L4_TCP; + break; + case Stream::e_l4_udp: + proto = PTYP_L4_UDP; + break; + case Stream::e_l4_icmp: + proto = PTYP_L4_ICMP; + break; + case Stream::e_l4_igmp: + proto = PTYP_L4_IGMP; + break; + default: + qDebug("%s: Unsupported L4 Proto %d", __FUNCTION__, + l4Proto()); + proto = PTYP_INVALID; + }; + selectedProtocols.append(proto); + +_data: + selectedProtocols.append(PTYP_DATA); +} + +int Stream::numProtocols() +{ + updateSelectedProtocols(); // FIXME(HI): shd not happen everytime + return selectedProtocols.size(); } #if 0 -void Stream::InitDefaultMeta() +int Stream::protocolId(int index) { - // TODO(LOW): Use #defines - meta.patternMode = e_dp_fixed; - meta.pattern = 0x00000000; - meta.dataStartOfs = 0; // FIXME(HIGH): this has to calculated - meta.lenMode = e_fl_fixed; - meta.frameLen = 64; - meta.frameLenMin = 64; - meta.frameLenMax = 1518; + updateSelectedProtocols(); // FIXME(HI): shd not happen everytime + if (index < selectedProtocols.size()) + return selectedProtocols.at(index); + else + return -1; } - -void Stream::InitDefaultProto() +int Stream::protocolIndex(int id) { - // TODO(LOW): Use #defines - proto.ft = e_ft_eth_2; - proto.dsap = 0x00; - proto.ssap = 0x00; - proto.ctl = 0x00; - proto.ouiMsb = 0x00; - proto.ouiLshw = 0x0000; - proto.protoMask = PM_L3_PROTO_NONE | PM_L4_PROTO_NONE; - proto.etherType = ETH_TYP_IP; - proto.ipProto = IP_PROTO_TCP; -} - - -void Stream::InitDefaultL2() -{ - // TODO(LOW): Use #defines - l2.eth.dstMacMshw = 0x0000; - l2.eth.dstMacLsw = 0x00000001; - l2.eth.dstMacMode = e_mm_fixed; - l2.eth.dstMacCount = 16; - l2.eth.dstMacStep = 1; - - l2.eth.srcMacMshw = 0x0000; - l2.eth.srcMacLsw = 0x00000002; - l2.eth.srcMacMode = e_mm_fixed; - l2.eth.srcMacCount = 16; - l2.eth.srcMacStep = 1; - - l2.eth.vlanMask = VM_UNTAGGED; - l2.eth.ctpid = 0x8100; - l2.eth.cvlanPrio = 0; - l2.eth.cvlanCfi = 0; - l2.eth.cvlanId = 2; - l2.eth.stpid = 0x88a8; - l2.eth.svlanPrio = 0; - l2.eth.svlanCfi = 0; - l2.eth.svlanId = 2; -} - -void Stream::InitDefaultL3() -{ - InitDefaultL3Ip(); -} - -void Stream::InitDefaultL3Ip() -{ - l3.ip.ipMask = STREAM_DEF_IP_MASK; - l3.ip.ver = STREAM_DEF_L3_IP_VER; - l3.ip.hdrLen = STREAM_DEF_L3_IP_HDR_LEN; - l3.ip.tos = STREAM_DEF_L3_IP_TOS; - l3.ip.totLen = STREAM_DEF_L3_IP_TOT_LEN; - l3.ip.id = STREAM_DEF_L3_IP_ID; - l3.ip.flags = STREAM_DEF_L3_IP_FLAGS; - l3.ip.fragOfs = STREAM_DEF_L3_IP_FRAG_OFS; - l3.ip.ttl = STREAM_DEF_L3_IP_TTL; - l3.ip.proto = STREAM_DEF_L3_IP_PROTO; - l3.ip.cksum = STREAM_DEF_L3_IP_CKSUM; - l3.ip.srcIp = STREAM_DEF_L3_IP_SRC_IP; - l3.ip.srcIpMode = STREAM_DEF_L3_IP_SRC_IP_MODE; - l3.ip.srcIpCount = STREAM_DEF_L3_IP_SRC_IP_COUNT; - l3.ip.srcIpMask = STREAM_DEF_L3_IP_SRC_IP_MASK; - l3.ip.dstIp = STREAM_DEF_L3_IP_DST_IP; - l3.ip.dstIpMode = STREAM_DEF_L3_IP_DST_IP_MODE; - l3.ip.dstIpCount = STREAM_DEF_L3_IP_DST_IP_COUNT; - l3.ip.dstIpMask = STREAM_DEF_L3_IP_DST_IP_MASK; -} - -void Stream::InitDefaultL4() -{ - InitDefaultL4Tcp(); - InitDefaultL4Udp(); -} - -void Stream::InitDefaultL4Tcp() -{ - l4.tcp.tcpMask = STREAM_DEF_L4_TCP_TCP_MASK; - l4.tcp.srcPort = STREAM_DEF_L4_TCP_SRC_PORT; - l4.tcp.dstPort = STREAM_DEF_L4_TCP_DST_PORT; - l4.tcp.seqNum = STREAM_DEF_L4_TCP_SEQ_NUM; - l4.tcp.ackNum = STREAM_DEF_L4_TCP_ACK_NUM; - l4.tcp.hdrLen = STREAM_DEF_L4_TCP_HDR_LEN; - l4.tcp.rsvd = STREAM_DEF_L4_TCP_RSVD; - l4.tcp.flags = STREAM_DEF_L4_TCP_FLAGS; - l4.tcp.window = STREAM_DEF_L4_TCP_WINDOW; - l4.tcp.cksum = STREAM_DEF_L4_TCP_CKSUM; - l4.tcp.urgPtr = STREAM_DEF_L4_TCP_URG_PTR; -} - -void Stream::InitDefaultL4Udp() -{ - l4.udp.udpMask = STREAM_DEF_L4_UDP_UDP_MASK; - l4.udp.srcPort = STREAM_DEF_L4_UDP_SRC_PORT; - l4.udp.dstPort = STREAM_DEF_L4_UDP_DST_PORT; - l4.udp.totLen = STREAM_DEF_L4_UDP_TOT_LEN; - l4.udp.cksum = STREAM_DEF_L4_UDP_CKSUM; } #endif + +AbstractProtocol* Stream::protocol(int index) +{ + int id; + + updateSelectedProtocols(); // FIXME(HI): shd not happen everytime + + id = selectedProtocols.at(index); + + switch(id) + { + case PTYP_L2_NONE: + return mac(); + case PTYP_L2_ETH_2: + return eth2(); + case PTYP_L2_802_3_RAW: + return eth2(); // FIXME(HI): define a dot3 protocol? + + case PTYP_L2_802_3_LLC: + return llc(); + + case PTYP_L2_SNAP: + return snap(); + + case PTYP_VLAN: + return vlan(); + + case PTYP_L3_IP: + return ip(); + case PTYP_L3_ARP: + return arp(); + + case PTYP_L4_TCP: + return tcp(); + case PTYP_L4_UDP: + return udp(); + case PTYP_L4_ICMP: + return icmp(); + case PTYP_L4_IGMP: + return igmp(); + + case PTYP_INVALID: + return mUnknown; + case PTYP_DATA: + return mUnknown; // FIXME(MED) define a "data" protocol? + default: + return mUnknown; + } +} + diff --git a/client/stream.h b/client/stream.h index 4b134cb..0bb35cd 100644 --- a/client/stream.h +++ b/client/stream.h @@ -3,6 +3,7 @@ #include #include +#include #include "../common/protocol.pb.h" class StreamConfigDialog; @@ -15,44 +16,55 @@ class PacketModel; #define IP_PROTO_TCP 0x06 #define IP_PROTO_UDP 0x11 -#if 0 - // Protocols - struct { - FrameType ft; - - - - quint16 protoMask; -#define PM_L3_PROTO_NONE 0x0001 -#define PM_L3_PROTO_OTHER 0x0002 -#define PM_L4_PROTO_NONE 0x0004 -#define PM_L4_PROTO_OTHER 0x0008 - - quint16 etherType; -#define ETH_TYP_IP 0x0800 -#define ETH_TYP_ARP 0x0806 - - quint16 ipProto; -#define IP_PROTO_ICMP 0x01 -#define IP_PROTO_IGMP 0x02 -#define IP_PROTO_TCP 0x06 -#define IP_PROTO_UDP 0x11 - } proto; - - // L2 - struct { - // Ethernet - - - - - } eth; - } l2; -#endif class AbstractProtocol { - // TODO + // TODO(LOW) +public: + /*! + Subclasses should return reference to their protocol specific + ::google::protobuf::Message + */ + virtual ::google::protobuf::Message& data() = 0; + /*! Subclasses can directly use this method. No need for overload */ + void getConfig(::google::protobuf::Message *msg) + { msg->CopyFrom(data()); } + + virtual QString protocolName() + { return QString("AbstractProtocol"); } + virtual QString protocolShortName() + { return QString("AbsProto"); } + virtual int numFields() + { return 1; } + virtual QString fieldName(int index) + { return QString("AbstractField"); } + virtual QString fieldTextValue(int index) + { return QString("AbstractFieldValue"); } + virtual QByteArray fieldRawValue(int index) + { return QByteArray(4, '\0'); } +}; + +class UnknownProtocol: public AbstractProtocol +{ + OstProto::Ack d; // FIXME(HI): replace 'Ack' with something else + +public: + virtual ~UnknownProtocol() {} + + virtual ::google::protobuf::Message& data() { return d; } + + virtual QString protocolName() + { return QString("UnknownProtocol"); } + QString protocolShortName() + { return QString("???Proto"); } + int numFields() + { return 1; } + QString fieldName(int index) + { return QString("UnknownField"); } + QString fieldTextValue(int index) + { return QString("UnknownFieldValue"); } + QByteArray fieldRawValue(int index) + { return QByteArray(4, '\0'); } }; class MacProtocol : public AbstractProtocol @@ -66,6 +78,10 @@ public: MacAddrInc, MacAddrDec }; + virtual ~MacProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + + bool update(OstProto::Mac mac) { d.MergeFrom(mac); return true; } // Dst Mac quint64 dstMac() @@ -110,6 +126,17 @@ public: { return d.src_mac_step(); } bool setSrcMacStep(quint16 srcMacStep) { d.set_src_mac_step(srcMacStep); return true; } + + + virtual QString protocolName() + { return QString("Media Access Control"); } + QString protocolShortName() + { return QString("MAC"); } + int numFields() + { return 2; } + QString fieldName(int index); + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); }; class LlcProtocol : public AbstractProtocol @@ -118,6 +145,11 @@ private: OstProto::Llc d; public: + virtual ~LlcProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + + bool update(OstProto::Llc llc) { d.MergeFrom(llc); return true; } + quint8 dsap() { return d.dsap(); } bool setDsap(quint8 dsap) @@ -133,6 +165,16 @@ public: bool setCtl(quint8 ctl) { d.set_ctl(ctl); return true; } + + virtual QString protocolName() + { return QString("802.3 Logical Link Control"); } + QString protocolShortName() + { return QString("LLC"); } + int numFields() + { return 3; } + QString fieldName(int index); + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); }; class SnapProtocol : public AbstractProtocol @@ -141,54 +183,179 @@ private: OstProto::Snap d; public: + virtual ~SnapProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + bool update(OstProto::Snap snap) { d.MergeFrom(snap); return true; } + quint32 oui() { return d.oui(); } bool setOui(quint32 oui) { d.set_oui(oui); return true; } +// "Type" field: use from eth2 +#if 0 quint16 type() { return d.type(); } bool setType(quint16 type) { d.set_type(type); return true; } +#endif + virtual QString protocolName() + { return QString("SubNetwork Access Protocol"); } + QString protocolShortName() + { return QString("SNAP"); } + int numFields() + { return 1; } + QString fieldName(int index); + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); }; + class Eth2Protocol : public AbstractProtocol { private: OstProto::Eth2 d; public: + virtual ~Eth2Protocol() {} + virtual ::google::protobuf::Message& data() {return d;} + bool update(OstProto::Eth2 eth2) { d.MergeFrom(eth2); return true; } + quint16 type() { return d.type(); } bool setType(quint16 type) { d.set_type(type); return true; } + + + virtual QString protocolName() + { return QString("Protocol Type"); } + QString protocolShortName() + { return QString("TYPE"); } + int numFields() + { return 1; } + QString fieldName(int index); + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); }; class VlanProtocol : public AbstractProtocol { -// TODO -#if 0 - quint16 vlanMask; -#define VM_UNTAGGED 0x0000 -#define VM_CVLAN_TAGGED 0x0001 -#define VM_CVLAN_TPID_OVERRIDE 0x0002 -#define VM_SVLAN_TAGGED 0x0100 -#define VM_SVLAN_TPID_OVERRIDE 0x0200 + OstProto::Vlan d; +public: + virtual ~VlanProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + bool update(OstProto::Vlan vlan) { d.MergeFrom(vlan); return true; } -#define VM_SINGLE_TAGGED(mask) \ -((mask & VM_CVLAN_TAGGED ) | (mask & VM_SVLAN_TAGGED)) -#define VM_DOUBLE_TAGGED(mask) \ -(mask & (VM_CVLAN_TAGGED | VM_SVLAN_TAGGED)) + enum VlanFlag { + VlanCvlanTagged = 0x01, + VlanCtpidOverride = 0x02, + VlanSvlanTagged = 0x04, + VlanStpidOverride = 0x08, + }; + Q_DECLARE_FLAGS(VlanFlags, VlanFlag); - quint16 ctpid; - quint16 cvlanPrio : 3; - quint16 cvlanCfi : 1; - quint16 cvlanId : 13; - quint16 stpid; - quint16 svlanPrio : 3; - quint16 svlanCfi : 1; - quint16 svlanId : 13; -#endif + VlanFlags vlanFlags() + { + VlanFlags f; + + if (d.is_cvlan_tagged()) f|= VlanCvlanTagged; + if (d.is_ctpid_override()) f|= VlanCtpidOverride; + if (d.is_svlan_tagged()) f|= VlanSvlanTagged; + if (d.is_stpid_override()) f|= VlanStpidOverride; + + return f; + } + + bool setVlanFlags(VlanFlags vlanFlags) + { + d.set_is_cvlan_tagged(vlanFlags.testFlag(VlanCvlanTagged)); + d.set_is_ctpid_override(vlanFlags.testFlag(VlanCtpidOverride)); + d.set_is_svlan_tagged(vlanFlags.testFlag(VlanSvlanTagged)); + d.set_is_stpid_override(vlanFlags.testFlag(VlanStpidOverride)); + + return true; + } + + bool isUntagged() + { + if (!d.is_cvlan_tagged() && !d.is_svlan_tagged()) + return true; + else + return false; + } + + bool isSingleTagged() + { + if (( d.is_cvlan_tagged() && !d.is_svlan_tagged()) || + (!d.is_cvlan_tagged() && d.is_svlan_tagged()) ) + return true; + else + return false; + } + + bool isDoubleTagged() + { + if (d.is_cvlan_tagged() && d.is_svlan_tagged()) + return true; + else + return false; + } + + // CVLAN + quint16 ctpid() + { return d.ctpid(); } + bool setCtpid(quint16 ctpid) + { d.set_ctpid(ctpid); return true; } + + quint8 cvlanPrio() + { return (d.cvlan_tag() >> 13); } + bool setCvlanPrio(quint8 cvlanPrio) + { d.set_cvlan_tag((d.cvlan_tag() & 0x1FFF) | ((cvlanPrio & 0x3) << 13)); + return true; } + + quint8 cvlanCfi() + { return ((d.cvlan_tag() & 0x1000) >> 12); } + bool setCvlanCfi(quint8 cvlanCfi) + { d.set_cvlan_tag((d.cvlan_tag() & 0xEFFF) | ((cvlanCfi & 0x01) << 12)); + return true; } + + quint16 cvlanId() + { return (d.cvlan_tag() & 0x0FFF); } + bool setCvlanId(quint16 cvlanId) + { d.set_cvlan_tag((d.cvlan_tag() & 0xF000) | ((cvlanId & 0x0FFF))); + return true; } + + // SVLAN + quint16 stpid() + { return d.stpid(); } + bool setStpid(quint16 stpid) + { d.set_stpid(stpid); return true; } + quint8 svlanPrio() + { return (d.svlan_tag() >> 13); } + bool setSvlanPrio(quint8 svlanPrio) + { d.set_svlan_tag((d.svlan_tag() & 0x1FFF) | ((svlanPrio & 0x3) << 13)); + return true; } + + quint8 svlanCfi() + { return ((d.svlan_tag() & 0x1000) >> 12); } + bool setSvlanCfi(quint8 svlanCfi) + { d.set_svlan_tag((d.svlan_tag() & 0xEFFF) | ((svlanCfi & 0x01) << 12)); + return true; } + + quint16 svlanId() + { return (d.svlan_tag() & 0x0FFF); } + bool setSvlanId(quint16 svlanId) + { d.set_svlan_tag((d.svlan_tag() & 0xF000) | ((svlanId & 0x0FFF))); + return true; } + + virtual QString protocolName() + { return QString("Virtual Local Access Network"); } + QString protocolShortName() + { return QString("VLAN"); } + int numFields(); + QString fieldName(int index); + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); }; // IP @@ -198,6 +365,10 @@ private: OstProto::Ip d; public: + virtual ~IpProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + + bool update(OstProto::Ip ip) { d.MergeFrom(ip); return true; } enum IpAddrMode { IpAddrFixed, @@ -209,8 +380,8 @@ public: enum IpFlag { IpOverrideVersion = 0x01, IpOverrideHdrLen = 0x02, - IpOverrideTotLen = 0x03, - IpOverrideCksum = 0x04 + IpOverrideTotLen = 0x04, + IpOverrideCksum = 0x08 }; Q_DECLARE_FLAGS(IpFlags, IpFlag); @@ -346,14 +517,31 @@ public: bool setDstIpMask(quint32 dstIpMask) { d.set_dst_ip_mask(dstIpMask); return true; } - // TODO: Options + // TODO(LOW): Options + + + virtual QString protocolName() + { return QString("Internet Protocol version 4"); } + QString protocolShortName() + { return QString("IPv4"); } + int numFields() + { return 12; } + QString fieldName(int index); + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); }; Q_DECLARE_OPERATORS_FOR_FLAGS(IpProtocol::IpFlags) class ArpProtocol: public AbstractProtocol { - // TODO: ARP + // TODO(LOW): ARP + OstProto::Arp d; + +public: + virtual ~ArpProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + bool update(OstProto::Arp arp) { d.MergeFrom(arp); return true; } }; // TCP @@ -363,6 +551,11 @@ private: OstProto::Tcp d; public: + virtual ~TcpProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + + bool update(OstProto::Tcp tcp) { d.MergeFrom(tcp); return true; } + enum TcpFlag { TcpOverrideHdrLen = 0x01, @@ -402,7 +595,7 @@ public: quint16 dstPort() { return d.dst_port(); } - bool setdstPort(quint16 dstPort) + bool setDstPort(quint16 dstPort) { d.set_dst_port(dstPort); return true; } quint32 seqNum() @@ -426,7 +619,7 @@ public: { d.set_hdrlen_rsvd((d.hdrlen_rsvd() & 0xF0) | rsvd); return true; } - // TODO: convert to enum maybe? + // TODO(MED): convert to enum maybe? quint8 flags() { return d.flags(); } bool setFlags(quint8 flags) @@ -448,11 +641,21 @@ public: bool setCksum(quint16 cksum) { d.set_cksum(cksum); return true; } - quint16 urg_ptr() + quint16 urgPtr() { return d.urg_ptr(); } - bool seturg_ptr(quint16 urg_ptr) + bool setUrgPtr(quint16 urg_ptr) { d.set_urg_ptr(urg_ptr); return true; } + + virtual QString protocolName() + { return QString("Transmission Control Protocol"); } + QString protocolShortName() + { return QString("TCP"); } + int numFields() + { return 10; } + QString fieldName(int index); + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); }; Q_DECLARE_OPERATORS_FOR_FLAGS(TcpProtocol::TcpFlags) @@ -464,6 +667,11 @@ private: OstProto::Udp d; public: + virtual ~UdpProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + + bool update(OstProto::Udp udp) { d.MergeFrom(udp); return true; } + enum UdpFlag { UdpOverrideTotLen = 0x01, @@ -503,7 +711,7 @@ public: quint16 dstPort() { return d.dst_port(); } - bool setdstPort(quint16 dstPort) + bool setDstPort(quint16 dstPort) { d.set_dst_port(dstPort); return true; } quint16 totLen() @@ -516,32 +724,78 @@ public: bool setCksum(quint16 cksum) { d.set_cksum(cksum); return true; } + + virtual QString protocolName() + { return QString("User Datagram Protocol"); } + QString protocolShortName() + { return QString("UDP"); } + int numFields() + { return 4; } + QString fieldName(int index); + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); }; -class IcmpProtocol { -// TODO: ICMP +class IcmpProtocol : public AbstractProtocol +{ +// TODO(LOW): ICMP + OstProto::Icmp d; + +public: + virtual ~IcmpProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + bool update(OstProto::Icmp icmp) { d.MergeFrom(icmp); return true; } }; -class IgmpProtocol { -// TODO: IGMP +class IgmpProtocol : public AbstractProtocol +{ +// TODO(LOW): IGMP + OstProto::Igmp d; + +public: + virtual ~IgmpProtocol() {} + virtual ::google::protobuf::Message& data() {return d;} + bool update(OstProto::Igmp igmp) { d.MergeFrom(igmp); return true; } }; class Stream { - static quint32 mAllocId; - quint32 mId; OstProto::StreamCore *mCore; - MacProtocol *mMac; - IpProtocol *mIp; + UnknownProtocol *mUnknown; + MacProtocol *mMac; + + LlcProtocol *mLlc; + SnapProtocol *mSnap; + Eth2Protocol *mEth2; + VlanProtocol *mVlan; + + IpProtocol *mIp; + ArpProtocol *mArp; + + TcpProtocol *mTcp; + UdpProtocol *mUdp; + IcmpProtocol *mIcmp; + IgmpProtocol *mIgmp; + +public: + MacProtocol* mac() { return mMac; } + + LlcProtocol* llc() { return mLlc; } + SnapProtocol* snap() { return mSnap; } + Eth2Protocol* eth2() { return mEth2; } + VlanProtocol* vlan() { return mVlan; } + + IpProtocol* ip() { return mIp; } + ArpProtocol* arp() { return mArp; } + + TcpProtocol* tcp() { return mTcp; } + UdpProtocol* udp() { return mUdp; } + IcmpProtocol* icmp() { return mIcmp; } + IgmpProtocol* igmp() { return mIgmp; } -#if 0 - friend class StreamConfigDialog; - friend class StreamModel; - friend class PacketModel; -#endif public: enum FrameType { @@ -566,17 +820,68 @@ public: e_fl_random }; + enum L3Proto { + e_l3_none, + e_l3_ip, + e_l3_arp, + }; + + enum L4Proto { + e_l4_none, + e_l4_tcp, + e_l4_udp, + e_l4_icmp, + e_l4_igmp, + }; + // ------------------------------------------------------- // Methods // ------------------------------------------------------- Stream(); + bool operator < (const Stream &s) const + { return(mCore->ordinal() < s.mCore->ordinal()); } + + bool update(OstProto::Stream *stream) + { + mCore->MergeFrom(stream->core()); + mMac->update(stream->mac()); + + mLlc->update(stream->llc()); + mSnap->update(stream->snap()); + mEth2->update(stream->eth2()); + mVlan->update(stream->vlan()); + + mIp->update(stream->ip()); + mArp->update(stream->arp()); + + mTcp->update(stream->tcp()); + mUdp->update(stream->udp()); + mIcmp->update(stream->icmp()); + mIgmp->update(stream->igmp()); + + // FIXME(MED): Re-eval why not store complete OstProto::Stream + // instead of components + return true; + } + + void getConfig(uint portId, OstProto::Stream *s); + quint32 id() { return mId;} + bool setId(quint32 id) + { mId = id; return true;} + +#if 0 // FIXME(HI): needed? + quint32 portId() + { return mCore->port_id();} + bool setPortId(quint32 id) + { mCore->set_port_id(id); return true;} +#endif quint32 ordinal() { return mCore->ordinal();} - bool setOrderdinal(quint32 ordinal) + bool setOrdinal(quint32 ordinal) { mCore->set_ordinal(ordinal); return true; } bool isEnabled() const @@ -606,6 +911,11 @@ public: bool setPattern(quint32 pattern) { mCore->set_pattern(pattern); return true; } +// TODO(HI) : ????? +#if 0 + quint16 dataStartOfs; +#endif + // Frame Length (includes CRC) FrameLengthMode lenMode() { return (FrameLengthMode) mCore->len_mode(); } @@ -628,25 +938,33 @@ public: bool setFrameLenMax(quint16 frameLenMax) { mCore->set_frame_len_max(frameLenMax); return true; } -// TODO + L3Proto l3Proto() + { return (L3Proto) mCore->l3_proto(); } + bool setL3Proto(L3Proto l3Proto) + { mCore->set_l3_proto((OstProto::StreamCore::L3Proto) l3Proto); + return true; } + + L4Proto l4Proto() + { return (L4Proto) mCore->l4_proto(); } + bool setL4Proto(L4Proto l4Proto) + { mCore->set_l4_proto((OstProto::StreamCore::L4Proto) l4Proto); + return true; } + + + //--------------------------------------------------------------- + // Methods for use by Packet Model + //--------------------------------------------------------------- + QList selectedProtocols; + + int numProtocols(); #if 0 - quint16 dataStartOfs; + int protocolId(int index); + int protocolIndex(int id); #endif - - MacProtocol* mac() { return mMac; } - IpProtocol* ip() { return mIp; } - + AbstractProtocol* protocol(int index); private: -#if 0 - void InitDefaultMeta(); - void InitDefaultProto(); - void InitDefaultL2(); - void InitDefaultL3(); - void InitDefaultL3Ip(); - void InitDefaultL4(); - void InitDefaultL4Tcp(); - void InitDefaultL4Udp(); -#endif + void updateSelectedProtocols(); + }; #endif diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 8e6a8a6..a881dce 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -2,34 +2,31 @@ #include "streamconfigdialog.h" #include "stream.h" -// TODO(LOW): Remove #include "modeltest.h" -StreamConfigDialog::StreamConfigDialog(QList *streamList, - uint streamIndex, QWidget *parent) : QDialog (parent) +// TODO(HI): Write HexLineEdit::setNum() and num() and use it in +// Load/Store stream methods + +StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, + QWidget *parent) : QDialog (parent), mPort(port) { setupUi(this); setupUiExtra(); - // FIXME(MED): Assumption that streamlist and streamIndex are valid - mpStreamList = streamList; + //mpStreamList = streamList; mCurrentStreamIndex = streamIndex; LoadCurrentStream(); - mpPacketModel = new PacketModel(&((*mpStreamList)[mCurrentStreamIndex]), + mpPacketModel = new PacketModel(&mPort.streamByIndex(mCurrentStreamIndex), this); tvPacketTree->setModel(mpPacketModel); mpPacketModelTester = new ModelTest(mpPacketModel); tvPacketTree->header()->hide(); - qDebug("stream %p %d/%d loaded", - mpStreamList, mCurrentStreamIndex, mpStreamList->size()); -// FIXME(MED): Enable this navigation -#if 0 - pbPrev->setDisabled((currStreamIdx == 0)); - pbNext->setDisabled((currStreamIdx == 2)); -#endif + // FIXME(MED): Enable this navigation + pbPrev->setDisabled(true); + pbNext->setDisabled(true); } void StreamConfigDialog::setupUiExtra() @@ -304,7 +301,7 @@ void StreamConfigDialog::on_lePattern_editingFinished() void StreamConfigDialog::LoadCurrentStream() { - Stream *pStream = &((*mpStreamList)[mCurrentStreamIndex]); + Stream *pStream = &mPort.streamByIndex(mCurrentStreamIndex); QString str; qDebug("loading pStream %p", pStream); @@ -342,19 +339,56 @@ void StreamConfigDialog::LoadCurrentStream() break; } -// TODO + leDsap->setText(uintToHexStr(pStream->llc()->dsap(), str, 1)); + leSsap->setText(uintToHexStr(pStream->llc()->ssap(), str, 1)); + leControl->setText(uintToHexStr(pStream->llc()->ctl(), str, 1)); + leOui->setText(uintToHexStr(pStream->snap()->oui(), str, 3)); + + leType->setText(uintToHexStr(pStream->eth2()->type(), str, 2)); + + switch(pStream->l3Proto()) + { + case Stream::e_l3_none: + rbL3None->setChecked(true); + break; + case Stream::e_l3_ip: + rbL3Ipv4->setChecked(true); + break; + case Stream::e_l3_arp: + rbL3Arp->setChecked(true); + break; + default: + qDebug("%s: unknown L3 Protocol %d", __FUNCTION__, + pStream->l3Proto()); + } + + switch(pStream->l4Proto()) + { + case Stream::e_l4_none: + rbL4None->setChecked(true); + break; + case Stream::e_l4_tcp: + rbL4Tcp->setChecked(true); + break; + case Stream::e_l4_udp: + rbL4Udp->setChecked(true); + break; + case Stream::e_l4_icmp: + rbL4Icmp->setChecked(true); + break; + case Stream::e_l4_igmp: + rbL4Igmp->setChecked(true); + break; + default: + qDebug("%s: unknown l4 Protocol %d", __FUNCTION__, + pStream->l4Proto()); + } +// PB (not needed anymore?) #if 0 - leDsap->setText(uintToHexStr(pStream->proto.dsap, str, 1)); - leSsap->setText(uintToHexStr(pStream->proto.ssap, str, 1)); - leControl->setText(uintToHexStr(pStream->proto.ctl, str, 1)); - leOui->setText(uintToHexStr((pStream->proto.ouiMsb << 16 + pStream->proto.ouiLshw), str, 3)); - - leType->setText(uintToHexStr(pStream->proto.etherType, str, 2)); - // Check for specific supported protocols first ... - if (pStream->proto.etherType == ETH_TYP_IP) + if (pStream->eth2()->type() == ETH_TYP_IP) rbL3Ipv4->setChecked(TRUE); - else if (pStream->proto.etherType == ETH_TYP_ARP) + else if (pStream->eth2()->type() == ETH_TYP_ARP) rbL3Arp->setChecked(TRUE); // ... then for None/Other @@ -390,21 +424,29 @@ void StreamConfigDialog::LoadCurrentStream() cmbSrcMacMode->setCurrentIndex(pStream->mac()->srcMacMode()); leSrcMacCount->setText(str.setNum(pStream->mac()->srcMacCount())); leSrcMacStep->setText(str.setNum(pStream->mac()->srcMacStep())); -#if 0 - cmbCvlanPrio->setCurrentIndex(pStream->l2.eth.cvlanPrio); - cmbCvlanCfi->setCurrentIndex(pStream->l2.eth.cvlanCfi); - leCvlanId->setText(str.setNum(pStream->l2.eth.cvlanId)); - leCvlanTpid->setText(str.setNum(pStream->l2.eth.ctpid)); - cbCvlanTpidOverride->setChecked((pStream->l2.eth.vlanMask & VM_CVLAN_TPID_OVERRIDE) > 0); - gbCvlan->setChecked((pStream->l2.eth.vlanMask & VM_CVLAN_TAGGED) > 0); - cmbSvlanPrio->setCurrentIndex(pStream->l2.eth.svlanPrio); - cmbSvlanCfi->setCurrentIndex(pStream->l2.eth.svlanCfi); - leSvlanId->setText(str.setNum(pStream->l2.eth.svlanId)); - leSvlanTpid->setText(str.setNum(pStream->l2.eth.stpid)); - cbSvlanTpidOverride->setChecked((pStream->l2.eth.vlanMask & VM_SVLAN_TPID_OVERRIDE) > 0); - gbSvlan->setChecked((pStream->l2.eth.vlanMask & VM_SVLAN_TAGGED) > 0); -#endif + { + VlanProtocol *vlan = pStream->vlan(); + VlanProtocol::VlanFlags f; + + cmbCvlanPrio->setCurrentIndex(vlan->cvlanPrio()); + cmbCvlanCfi->setCurrentIndex(vlan->cvlanCfi()); + leCvlanId->setText(str.setNum(vlan->cvlanId())); + leCvlanTpid->setText(str.setNum(vlan->ctpid())); + cbCvlanTpidOverride->setChecked(vlan->vlanFlags().testFlag( + VlanProtocol::VlanCtpidOverride)); + gbCvlan->setChecked(vlan->vlanFlags().testFlag( + VlanProtocol::VlanCvlanTagged)); + + cmbSvlanPrio->setCurrentIndex(vlan->svlanPrio()); + cmbSvlanCfi->setCurrentIndex(vlan->svlanCfi()); + leSvlanId->setText(str.setNum(vlan->svlanId())); + leSvlanTpid->setText(str.setNum(vlan->stpid())); + cbSvlanTpidOverride->setChecked(vlan->vlanFlags().testFlag( + VlanProtocol::VlanStpidOverride)); + gbSvlan->setChecked(vlan->vlanFlags().testFlag( + VlanProtocol::VlanSvlanTagged)); + } } } @@ -450,73 +492,75 @@ void StreamConfigDialog::LoadCurrentStream() // L3 | ARP { - // TODO + // TODO(LOW) } } -#if 0 // L4 { // L4 | TCP { - leTcpSrcPort->setText(str.setNum(pStream->l4.tcp.srcPort)); - leTcpDstPort->setText(str.setNum(pStream->l4.tcp.dstPort)); + leTcpSrcPort->setText(str.setNum(pStream->tcp()->srcPort())); + leTcpDstPort->setText(str.setNum(pStream->tcp()->dstPort())); - leTcpSeqNum->setText(str.setNum(pStream->l4.tcp.seqNum)); - leTcpAckNum->setText(str.setNum(pStream->l4.tcp.ackNum)); + leTcpSeqNum->setText(str.setNum(pStream->tcp()->seqNum())); + leTcpAckNum->setText(str.setNum(pStream->tcp()->ackNum())); - leTcpHdrLen->setText(str.setNum(pStream->l4.tcp.hdrLen)); - cbTcpHdrLenOverride->setChecked((pStream->l4.tcp.tcpMask & TM_OVERRIDE_HDRLEN) > 0); + leTcpHdrLen->setText(str.setNum(pStream->tcp()->hdrLen())); + cbTcpHdrLenOverride->setChecked((pStream->tcp()->tcpFlags(). + testFlag(TcpProtocol::TcpOverrideHdrLen))); - leTcpWindow->setText(str.setNum(pStream->l4.tcp.window)); + leTcpWindow->setText(str.setNum(pStream->tcp()->window())); - leTcpCksum->setText(str.setNum(pStream->l4.tcp.cksum)); - cbTcpCksumOverride->setChecked((pStream->l4.tcp.tcpMask & TM_OVERRIDE_CKSUM) > 0); + leTcpCksum->setText(str.setNum(pStream->tcp()->cksum())); + cbTcpCksumOverride->setChecked((pStream->tcp()->tcpFlags(). + testFlag(TcpProtocol::TcpOverrideCksum))); - leTcpUrgentPointer->setText(str.setNum(pStream->l4.tcp.urgPtr)); + leTcpUrgentPointer->setText(str.setNum(pStream->tcp()->urgPtr())); - cbTcpFlagsUrg->setChecked((pStream->l4.tcp.flags & TCP_FLAG_URG) > 0); - cbTcpFlagsAck->setChecked((pStream->l4.tcp.flags & TCP_FLAG_ACK) > 0); - cbTcpFlagsPsh->setChecked((pStream->l4.tcp.flags & TCP_FLAG_PSH) > 0); - cbTcpFlagsRst->setChecked((pStream->l4.tcp.flags & TCP_FLAG_RST) > 0); - cbTcpFlagsSyn->setChecked((pStream->l4.tcp.flags & TCP_FLAG_SYN) > 0); - cbTcpFlagsFin->setChecked((pStream->l4.tcp.flags & TCP_FLAG_FIN) > 0); + cbTcpFlagsUrg->setChecked((pStream->tcp()->flags() & TCP_FLAG_URG) > 0); + cbTcpFlagsAck->setChecked((pStream->tcp()->flags() & TCP_FLAG_ACK) > 0); + cbTcpFlagsPsh->setChecked((pStream->tcp()->flags() & TCP_FLAG_PSH) > 0); + cbTcpFlagsRst->setChecked((pStream->tcp()->flags() & TCP_FLAG_RST) > 0); + cbTcpFlagsSyn->setChecked((pStream->tcp()->flags() & TCP_FLAG_SYN) > 0); + cbTcpFlagsFin->setChecked((pStream->tcp()->flags() & TCP_FLAG_FIN) > 0); } // L4 | UDP { - leUdpSrcPort->setText(str.setNum(pStream->l4.udp.srcPort)); - leUdpDstPort->setText(str.setNum(pStream->l4.udp.dstPort)); + leUdpSrcPort->setText(str.setNum(pStream->udp()->srcPort())); + leUdpDstPort->setText(str.setNum(pStream->udp()->dstPort())); - leUdpLength->setText(str.setNum(pStream->l4.udp.totLen)); - cbUdpLengthOverride->setChecked((pStream->l4.udp.udpMask & UM_OVERRIDE_TOTLEN) > 0); + leUdpLength->setText(str.setNum(pStream->udp()->totLen())); + cbUdpLengthOverride->setChecked((pStream->udp()->udpFlags(). + testFlag(UdpProtocol::UdpOverrideTotLen))); - leUdpCksum->setText(str.setNum(pStream->l4.udp.cksum)); - cbUdpCksumOverride->setChecked((pStream->l4.udp.udpMask & UM_OVERRIDE_CKSUM) > 0); + + leUdpCksum->setText(str.setNum(pStream->udp()->cksum())); + cbUdpCksumOverride->setChecked((pStream->udp()->udpFlags(). + testFlag(UdpProtocol::UdpOverrideCksum))); } // L4 | ICMP { - // TODO + // TODO(LOW) } // L4 | IGMP { - // TODO + // TODO(LOW) } } -#endif } void StreamConfigDialog::StoreCurrentStream() { - Stream *pStream = &(*mpStreamList)[mCurrentStreamIndex]; + Stream *pStream = &mPort.streamByIndex(mCurrentStreamIndex); QString str; bool isOk; qDebug("storing pStream %p", pStream); -#if 1 // FIXME: Temp till we use protobuff accessors // Meta Data pStream->setPatternMode((Stream::DataPatternMode) cmbPatternMode->currentIndex()); pStream->setPattern(lePattern->text().remove(QChar(' ')).toULong(&isOk, 16)); @@ -525,7 +569,7 @@ void StreamConfigDialog::StoreCurrentStream() pStream->setFrameLen(lePktLen->text().toULong(&isOk)); pStream->setFrameLenMin(lePktLenMin->text().toULong(&isOk)); pStream->setFrameLenMax(lePktLenMax->text().toULong(&isOk)); -#endif + // Protocols { if (rbFtNone->isChecked()) @@ -540,28 +584,39 @@ void StreamConfigDialog::StoreCurrentStream() pStream->setFrameType(Stream::e_ft_snap); qDebug("store ft(%d)\n", pStream->frameType()); -#if 0 - pStream->proto.dsap = leDsap->text().remove(QChar(' ')).toULong(&isOk, 16); - pStream->proto.ssap = leSsap->text().remove(QChar(' ')).toULong(&isOk, 16); - pStream->proto.ctl = leControl->text().remove(QChar(' ')).toULong(&isOk, 16); - pStream->proto.ouiMsb = leOui->text().remove(QChar(' ')).toULong(&isOk, 16) >> 16; - pStream->proto.ouiLshw = 0x0000FFFF & leOui->text().remove(QChar(' ')).toULong(&isOk, 16); - pStream->proto.etherType = leType->text().remove(QChar(' ')).toULong(&isOk, 16); + pStream->llc()->setDsap(leDsap->text().remove(QChar(' ')).toULong(&isOk, 16)); + pStream->llc()->setSsap(leSsap->text().remove(QChar(' ')).toULong(&isOk, 16)); + pStream->llc()->setCtl(leControl->text().remove(QChar(' ')).toULong(&isOk, 16)); + pStream->snap()->setOui(leOui->text().remove(QChar(' ')).toULong(&isOk, 16)); + pStream->eth2()->setType(leType->text().remove(QChar(' ')).toULong(&isOk, 16)); - pStream->proto.ipProto = leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16); - - // Just check for None/Other - no need to do anything for specific supported protocols - pStream->proto.protoMask = 0; if (rbL3None->isChecked()) - pStream->proto.protoMask |= PM_L3_PROTO_NONE; - else if (rbL3Other->isChecked()) - pStream->proto.protoMask |= PM_L3_PROTO_OTHER; + pStream->setL3Proto(Stream::e_l3_none); + else if (rbL3Ipv4->isChecked()) + pStream->setL3Proto(Stream::e_l3_ip); + else if (rbL3Arp->isChecked()) + pStream->setL3Proto(Stream::e_l3_arp); + else + { + qCritical("No L3 Protocol??? Problem in Code!!!"); + pStream->setL3Proto(Stream::e_l3_none); + } if (rbL4None->isChecked()) - pStream->proto.protoMask |= PM_L4_PROTO_NONE; - else if (rbL4Other->isChecked()) - pStream->proto.protoMask |= PM_L4_PROTO_OTHER; -#endif + pStream->setL4Proto(Stream::e_l4_none); + else if (rbL4Tcp->isChecked()) + pStream->setL4Proto(Stream::e_l4_tcp); + else if (rbL4Udp->isChecked()) + pStream->setL4Proto(Stream::e_l4_udp); + else if (rbL4Icmp->isChecked()) + pStream->setL4Proto(Stream::e_l4_icmp); + else if (rbL4Igmp->isChecked()) + pStream->setL4Proto(Stream::e_l4_igmp); + else + { + qCritical("No L4 Protocol??? Problem in Code!!!"); + pStream->setL4Proto(Stream::e_l4_none); + } } // L2 @@ -587,27 +642,30 @@ void StreamConfigDialog::StoreCurrentStream() leSrcMacStep->text().toULong(&isOk)); -#if 0 - pStream->l2.eth.vlanMask = 0; + { + VlanProtocol *vlan = pStream->vlan(); + VlanProtocol::VlanFlags f = 0; - pStream->l2.eth.cvlanPrio = cmbCvlanPrio->currentIndex(); - pStream->l2.eth.cvlanCfi = cmbCvlanCfi->currentIndex(); - pStream->l2.eth.cvlanId = leCvlanId->text().toULong(&isOk); - pStream->l2.eth.ctpid = leCvlanTpid->text().remove(QChar(' ')).toULong(&isOk); - if (cbCvlanTpidOverride->isChecked()) - pStream->l2.eth.vlanMask |= VM_CVLAN_TPID_OVERRIDE; - if (gbCvlan->isChecked()) - pStream->l2.eth.vlanMask |= VM_CVLAN_TAGGED; + vlan->setCvlanPrio(cmbCvlanPrio->currentIndex()); + vlan->setCvlanCfi(cmbCvlanCfi->currentIndex()); + vlan->setCvlanId(leCvlanId->text().toULong(&isOk)); + vlan->setCtpid(leCvlanTpid->text().remove(QChar(' ')).toULong(&isOk)); + if (cbCvlanTpidOverride->isChecked()) + f |= VlanProtocol::VlanCtpidOverride; + if (gbCvlan->isChecked()) + f |= VlanProtocol::VlanCvlanTagged; - pStream->l2.eth.svlanPrio = cmbSvlanPrio->currentIndex(); - pStream->l2.eth.svlanCfi = cmbSvlanCfi->currentIndex(); - pStream->l2.eth.svlanId = leSvlanId->text().toULong(&isOk); - pStream->l2.eth.stpid = leSvlanTpid->text().remove(QChar(' ')).toULong(&isOk); - if (cbSvlanTpidOverride->isChecked()) - pStream->l2.eth.vlanMask |= VM_SVLAN_TPID_OVERRIDE; - if (gbSvlan->isChecked()) - pStream->l2.eth.vlanMask |= VM_SVLAN_TAGGED; -#endif + vlan->setSvlanPrio(cmbSvlanPrio->currentIndex()); + vlan->setSvlanCfi(cmbSvlanCfi->currentIndex()); + vlan->setSvlanId(leSvlanId->text().toULong(&isOk)); + vlan->setStpid(leSvlanTpid->text().remove(QChar(' ')).toULong(&isOk)); + if (cbSvlanTpidOverride->isChecked()) + f |= VlanProtocol::VlanStpidOverride; + if (gbSvlan->isChecked()) + f |= VlanProtocol::VlanSvlanTagged; + + vlan->setVlanFlags(f); + } } } @@ -616,7 +674,8 @@ void StreamConfigDialog::StoreCurrentStream() // L3 | IP { IpProtocol *ip = pStream->ip(); - IpProtocol::IpFlags f; + IpProtocol::IpFlags f = 0; + int ff = 0; ip->setVer(leIpVersion->text().toULong(&isOk)); if (cbIpVersionOverride->isChecked()) @@ -634,7 +693,6 @@ void StreamConfigDialog::StoreCurrentStream() ip->setId(leIpId->text().remove(QChar(' ')).toULong(&isOk, 16)); ip->setFragOfs(leIpFragOfs->text().toULong(&isOk)); - int ff; if (cbIpFlagsDf->isChecked()) ff |= IP_FLAG_DF; if (cbIpFlagsMf->isChecked()) ff |= IP_FLAG_MF; ip->setFlags(ff); @@ -661,71 +719,79 @@ void StreamConfigDialog::StoreCurrentStream() // L3 | ARP { - // TODO + // TODO(LOW) } } -// TODO -#if 0 // L4 { // L4 | TCP { - pStream->l4.tcp.tcpMask = 0; + TcpProtocol *tcp = pStream->tcp(); + TcpProtocol::TcpFlags f = 0; + int ff = 0; - pStream->l4.tcp.srcPort = leTcpSrcPort->text().toULong(&isOk); - pStream->l4.tcp.dstPort = leTcpDstPort->text().toULong(&isOk); + tcp->setSrcPort(leTcpSrcPort->text().toULong(&isOk)); + tcp->setDstPort(leTcpDstPort->text().toULong(&isOk)); - pStream->l4.tcp.seqNum = leTcpSeqNum->text().toULong(&isOk); - pStream->l4.tcp.ackNum = leTcpAckNum->text().toULong(&isOk); + tcp->setSeqNum(leTcpSeqNum->text().toULong(&isOk)); + tcp->setAckNum(leTcpAckNum->text().toULong(&isOk)); - pStream->l4.tcp.hdrLen = leTcpHdrLen->text().toULong(&isOk); + tcp->setHdrLen(leTcpHdrLen->text().toULong(&isOk)); if (cbTcpHdrLenOverride->isChecked()) - pStream->l4.tcp.tcpMask |= TM_OVERRIDE_HDRLEN; + f |= TcpProtocol::TcpOverrideHdrLen; - pStream->l4.tcp.window = leTcpWindow->text().toULong(&isOk); + tcp->setWindow(leTcpWindow->text().toULong(&isOk)); - pStream->l4.tcp.cksum = leTcpCksum->text().remove(QChar(' ')).toULong(&isOk); + tcp->setCksum(leTcpCksum->text().remove(QChar(' ')).toULong(&isOk)); if (cbTcpCksumOverride->isChecked()) - pStream->l4.tcp.tcpMask |= TM_OVERRIDE_CKSUM; + f |= TcpProtocol::TcpOverrideCksum; - pStream->l4.tcp.urgPtr = leTcpUrgentPointer->text().toULong(&isOk); + tcp->setUrgPtr(leTcpUrgentPointer->text().toULong(&isOk)); - pStream->l4.tcp.flags = 0; - if (cbTcpFlagsUrg->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_URG; - if (cbTcpFlagsAck->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_ACK; - if (cbTcpFlagsPsh->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_PSH; - if (cbTcpFlagsRst->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_RST; - if (cbTcpFlagsSyn->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_SYN; - if (cbTcpFlagsFin->isChecked()) pStream->l4.tcp.flags |= TCP_FLAG_FIN; + if (cbTcpFlagsUrg->isChecked()) ff |= TCP_FLAG_URG; + if (cbTcpFlagsAck->isChecked()) ff |= TCP_FLAG_ACK; + if (cbTcpFlagsPsh->isChecked()) ff |= TCP_FLAG_PSH; + if (cbTcpFlagsRst->isChecked()) ff |= TCP_FLAG_RST; + if (cbTcpFlagsSyn->isChecked()) ff |= TCP_FLAG_SYN; + if (cbTcpFlagsFin->isChecked()) ff |= TCP_FLAG_FIN; + tcp->setFlags(ff); + + tcp->setTcpFlags(f); } // L4 | UDP { - pStream->l4.udp.udpMask = 0; + UdpProtocol *udp = pStream->udp(); + UdpProtocol::UdpFlags f = 0; - pStream->l4.udp.srcPort = leUdpSrcPort->text().toULong(&isOk); - pStream->l4.udp.dstPort = leUdpDstPort->text().toULong(&isOk); + udp->setSrcPort(leUdpSrcPort->text().toULong(&isOk)); + udp->setDstPort(leUdpDstPort->text().toULong(&isOk)); - pStream->l4.udp.totLen = leUdpLength->text().toULong(&isOk); - if (cbUdpLengthOverride->isChecked()) pStream->l4.udp.udpMask |= UM_OVERRIDE_TOTLEN; + udp->setTotLen(leUdpLength->text().toULong(&isOk)); - pStream->l4.udp.cksum = leUdpCksum->text().remove(QChar(' ')).toULong(&isOk); - if (cbUdpCksumOverride->isChecked()) pStream->l4.udp.udpMask |= UM_OVERRIDE_CKSUM; + if (cbUdpLengthOverride->isChecked()) + f |= UdpProtocol::UdpOverrideTotLen; + + udp->setCksum(leUdpCksum->text().remove(QChar(' ')).toULong(&isOk)); + if (cbUdpCksumOverride->isChecked()) + f |= UdpProtocol::UdpOverrideCksum; + + udp->setUdpFlags(f); } // L4 | ICMP { - // TODO + // TODO)(LOW) } // L4 | IGMP { - // TODO + // TODO(LOW) } } -#endif } + void StreamConfigDialog::on_pbOk_clicked() { // Store dialog contents into stream diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 1d3c99b..2485011 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -3,6 +3,7 @@ #include #include "ui_streamconfigdialog.h" +#include "port.h" #include "stream.h" #include "packetmodel.h" #include "modeltest.h" @@ -17,16 +18,18 @@ ** */ + class StreamConfigDialog : public QDialog, public Ui::StreamConfigDialog { Q_OBJECT public: - StreamConfigDialog(QList *streamList, uint streamIndex, - QWidget *parent = 0); + StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent = 0); ~StreamConfigDialog(); private: - QList *mpStreamList; + //QList *mpStreamList; + + Port& mPort; uint mCurrentStreamIndex; PacketModel *mpPacketModel; ModelTest *mpPacketModelTester; diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index a9c1ba4..b568d52 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -191,7 +191,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 1 + 0 @@ -390,6 +390,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + false + Other diff --git a/client/streammodel.cpp b/client/streammodel.cpp index d56f4ee..3ee9136 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -15,7 +15,7 @@ int StreamModel::rowCount(const QModelIndex &parent) const return 0; if (mCurrentPort) - return mCurrentPort->mStreams.size(); + return mCurrentPort->numStreams(); else return 0; } @@ -53,7 +53,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const return QVariant(); // Check for row/column limits - if (index.row() >= mCurrentPort->mStreams.size()) + if (index.row() >= mCurrentPort->numStreams()) return QVariant(); if (index.column() >= StreamMaxFields) @@ -80,7 +80,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const case StreamName: { if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) - return mCurrentPort->mStreams[index.row()].name(); + return mCurrentPort->streamByIndex(index.row()).name(); else return QVariant(); break; @@ -94,7 +94,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const #endif if ((role == Qt::CheckStateRole) || (role == Qt::EditRole)) { - if (mCurrentPort->mStreams[index.row()].isEnabled()) + if (mCurrentPort->streamByIndex(index.row()).isEnabled()) return Qt::Checked; else return Qt::Unchecked; @@ -121,11 +121,11 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r switch (index.column()) { case StreamName: - mCurrentPort->mStreams[index.row()].setName(value.toString()); + mCurrentPort->streamByIndex(index.row()).setName(value.toString()); return true; break; case StreamStatus: - mCurrentPort->mStreams[index.row()].setIsEnabled(value.toBool()); + mCurrentPort->streamByIndex(index.row()).setIsEnabled(value.toBool()); return true; break; @@ -178,7 +178,7 @@ bool StreamModel::insertRows(int row, int count, const QModelIndex &parent) qDebug("insertRows() count = %d", count); beginInsertRows(QModelIndex(), row, row+count-1); for (int i = 0; i < count; i++) - mCurrentPort->mStreams.insert(row, Stream()); + mCurrentPort->newStreamAt(row); endInsertRows(); return true; @@ -191,8 +191,7 @@ bool StreamModel::removeRows(int row, int count, const QModelIndex &parent) beginRemoveRows(QModelIndex(), row, row+count-1); for (int i = 0; i < count; i++) { - // FIXME(HIGH): do we need to free the removed stream? - mCurrentPort->mStreams.removeAt(row); + mCurrentPort->deleteStreamAt(row); } endRemoveRows(); diff --git a/client/streammodel.h b/client/streammodel.h index de648a2..697517d 100644 --- a/client/streammodel.h +++ b/client/streammodel.h @@ -37,9 +37,11 @@ class StreamModel : public QAbstractTableModel bool removeRows (int row, int count, const QModelIndex & parent = QModelIndex()); +#if 0 // CleanedUp! // FIXME(HIGH): This *is* like a kludge QList* currentPortStreamList() { return &mCurrentPort->mStreams; } +#endif public slots: void setCurrentPortIndex(const QModelIndex ¤t); diff --git a/common/protocol.proto b/common/protocol.proto index 4fa777d..e620b2d 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -151,18 +151,18 @@ message StreamCore { enum L3Proto { e_l3_none = 0; - e_l3_other = 1; - e_l3_ip = 2; - e_l3_arp = 3; + e_l3_ip = 1; + e_l3_arp = 2; + //e_l3_other = 3; } enum L4Proto { e_l4_none = 0; - e_l4_other = 1; - e_l4_tcp = 2; - e_l4_udp = 3; - e_l4_icmp = 4; - e_l4_igmp = 5; + e_l4_tcp = 1; + e_l4_udp = 2; + e_l4_icmp = 3; + e_l4_igmp = 4; + //e_l4_other = 5; } enum DataPatternMode { @@ -202,20 +202,21 @@ message StreamCore { } message StreamId { - required uint32 port_id = 1; - required uint32 stream_id = 2; + required uint32 id = 1; } message Stream { - required StreamId id = 1; + required StreamId stream_id = 1; optional StreamCore core = 2; // Protocol data - L2 optional Mac mac = 51; + optional Llc llc = 52; optional Snap snap = 53; optional Eth2 eth2 = 54; + optional Vlan vlan = 55; // Protocol data - L3 optional Ip ip = 61; @@ -237,17 +238,22 @@ message Ack { // TODO } +message PortId { + required uint32 id = 1; +} + message PortIdList { - repeated uint32 port_id = 1; + repeated PortId port_id = 1; } message StreamIdList { - repeated StreamId id = 1; + required PortId port_id = 1; + repeated StreamId stream_id = 2; } -message PortConfig { - required uint32 port_id = 1; +message Port { + required PortId port_id = 1; optional string name = 2; optional string description = 3; optional bool is_enabled = 4; @@ -256,11 +262,12 @@ message PortConfig { } message PortConfigList { - repeated PortConfig list = 1; + repeated Port port = 1; } message StreamConfigList { - repeated Stream stream = 1; + required PortId port_id = 1; + repeated Stream stream = 2; } message CaptureBuffer { @@ -283,7 +290,7 @@ service OstService { rpc getPortIdList(Void) returns (PortIdList); rpc getPortConfig(PortIdList) returns (PortConfigList); - rpc getStreamIdList(PortIdList) returns (StreamIdList); + rpc getStreamIdList(PortId) returns (StreamIdList); rpc getStreamConfig(StreamIdList) returns (StreamConfigList); rpc addStream(StreamIdList) returns (Ack); rpc deleteStream(StreamIdList) returns (Ack); diff --git a/rpc/pbhelper.h b/rpc/pbhelper.h index 19e3daf..21afefa 100644 --- a/rpc/pbhelper.h +++ b/rpc/pbhelper.h @@ -9,15 +9,100 @@ class PbHelper { public: + // FIXME: Change msg from * to & + void ForceSetSingularDefault(::google::protobuf::Message *msg) + { + const ::google::protobuf::Descriptor *desc; + ::google::protobuf::Message::Reflection *refl; + + qDebug("In %s", __FUNCTION__); + + desc = msg->GetDescriptor(); + refl = msg->GetReflection(); + + for (int i=0; i < desc->field_count(); i++) + { + const ::google::protobuf::FieldDescriptor *f; + + f = desc->field(i); + + // Ensure field is singular and not already set + if (f->label() == + ::google::protobuf::FieldDescriptor::LABEL_REPEATED) + continue; + if (refl->HasField(f)) + continue; + + switch(f->type()) + { + case ::google::protobuf::FieldDescriptor::TYPE_DOUBLE: + refl->SetDouble(f, refl->GetDouble(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_FLOAT: + refl->SetFloat(f, refl->GetFloat(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_INT32: + case ::google::protobuf::FieldDescriptor::TYPE_SINT32: + case ::google::protobuf::FieldDescriptor::TYPE_SFIXED32: + refl->SetInt32(f, refl->GetInt32(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_INT64: + case ::google::protobuf::FieldDescriptor::TYPE_SINT64: + case ::google::protobuf::FieldDescriptor::TYPE_SFIXED64: + refl->SetInt64(f, refl->GetInt64(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_UINT32: + case ::google::protobuf::FieldDescriptor::TYPE_FIXED32: + refl->SetUInt32(f, refl->GetUInt32(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_UINT64: + case ::google::protobuf::FieldDescriptor::TYPE_FIXED64: + refl->SetUInt64(f, refl->GetUInt64(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_BOOL: + refl->SetBool(f, refl->GetBool(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_ENUM: + refl->SetEnum(f, refl->GetEnum(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_STRING: + case ::google::protobuf::FieldDescriptor::TYPE_BYTES: + refl->SetString(f, refl->GetString(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_MESSAGE: + case ::google::protobuf::FieldDescriptor::TYPE_GROUP: + ForceSetSingularDefault(refl->MutableMessage(f)); // recursion! + break; + + default: + qDebug("unhandled Field Type"); + break; + } + } + } + bool update( ::google::protobuf::Message *target, ::google::protobuf::Message *source) { + // FIXME(HI): Depracate: use MergeFrom() directly + qDebug("In %s", __FUNCTION__); + target->MergeFrom(*source); + return true; +#if 0 ::google::protobuf::Message::Reflection *sourceRef; ::google::protobuf::Message::Reflection *targetRef; std::vector srcFieldList; - qDebug("In %s", __FUNCTION__); if (source->GetDescriptor()->full_name() != target->GetDescriptor()->full_name()) @@ -54,13 +139,10 @@ public: break; } } - - return true; - _error_exit: qDebug("%s: error!", __FUNCTION__); return false; +#endif } - }; #endif diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index 0d6226b..366ca6f 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -65,12 +65,22 @@ void PbRpcChannel::CallMethod( ::google::protobuf::Message *response, ::google::protobuf::Closure* done) { - char msg[1024]; // FIXME: hardcoding + char msg[4096]; // FIXME: hardcoding char *p = (char *)&msg; int len; qDebug("In %s", __FUNCTION__); + if (!req->IsInitialized()) + { + qDebug("RpcChannel: missing required fields in request"); + qDebug(req->InitializationErrorString().c_str()); + + controller->SetFailed("Required fields missing"); + done->Run(); + return; + } + pendingMethodId = method->index(); this->controller=controller; this->done=done; @@ -91,7 +101,7 @@ void PbRpcChannel::CallMethod( *((quint16*)(p+4)) = HTONS(len); // len qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, len+8, - req->ShortDebugString().c_str()); + req->DebugString().c_str()); BUFDUMP(msg, len+8); mpSocket->write(msg, len + 8); @@ -99,7 +109,7 @@ void PbRpcChannel::CallMethod( void PbRpcChannel::on_mpSocket_readyRead() { - char msg[1024]; // FIXME: hardcoding; + char msg[4096]; // FIXME: hardcoding; char *p = (char*)&msg; int msgLen; quint16 type, method, len, rsvd; @@ -146,6 +156,13 @@ void PbRpcChannel::on_mpSocket_readyRead() qDebug("client(%s): Parsed as %s", __FUNCTION__, response->DebugString().c_str()); + if (!response->IsInitialized()) + { + qDebug("RpcChannel: missing required fields in response"); + qDebug(response->InitializationErrorString().c_str()); + + controller->SetFailed("Required fields missing"); + } pendingMethodId = -1; controller = NULL; diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index 45555bf..7b6335b 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -37,7 +37,7 @@ bool RpcServer::registerService(::google::protobuf::Service *service, void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController) { - char msg[1024]; // FIXME: hardcoding + char msg[4096]; // FIXME: hardcoding char *p = (char *)&msg; int len; @@ -50,6 +50,13 @@ void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcCo goto _exit; } + if (!resp->IsInitialized()) + { + qDebug("response missing required fields!!"); + qDebug(resp->InitializationErrorString().c_str()); + goto _exit; + } + *((quint16*)(p+0)) = HTONS(PB_MSG_TYPE_RESPONSE); // type TODO:RESPONSE *((quint16*)(p+2)) = HTONS(pendingMethodId); // method *((quint16*)(p+6)) = HTONS(0); // rsvd @@ -60,9 +67,9 @@ void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcCo len = resp->ByteSize(); (*(quint16*)(p+4)) = HTONS(len); // len - qDebug("Server(%s): sending %d bytest to client encoding <%s>", + qDebug("Server(%s): sending %d bytes to client encoding <%s>", __FUNCTION__, len + 8, resp->DebugString().c_str()); - BUFDUMP(msg, len + 8); + //BUFDUMP(msg, len + 8); clientSock->write(msg, len + 8); @@ -116,7 +123,7 @@ void RpcServer::when_error(QAbstractSocket::SocketError socketError) void RpcServer::when_dataAvail() { - char msg[1024]; // FIXME: hardcoding; + char msg[4096]; // FIXME: hardcoding; int msgLen; char *p = (char*) &msg; quint16 type, method, len, rsvd; @@ -128,13 +135,14 @@ void RpcServer::when_dataAvail() LogInt(QString(QByteArray(msg, msgLen).toHex())); qDebug("Server %s: rcvd %d bytes", __FUNCTION__, msgLen); - BUFDUMP(msg, msgLen); + //BUFDUMP(msg, msgLen); type = NTOHS(GET16(p+0)); - qDebug("GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)), type); method = NTOHS(GET16(p+2)); len = NTOHS(GET16(p+4)); rsvd = NTOHS(GET16(p+6)); + qDebug("type = %d, method = %d, len = %d, rsvd = %d", + type, method, len, rsvd); if (type != PB_MSG_TYPE_REQUEST) { @@ -165,9 +173,22 @@ void RpcServer::when_dataAvail() // Serialized data starts from offset 8 req->ParseFromArray((void*) (msg+8), len); + if (!req->IsInitialized()) + { + qDebug("Missing required fields in request"); + qDebug(req->InitializationErrorString().c_str()); + delete req; + delete resp; + + goto _error_exit; + } + qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, + resp->DebugString().c_str()); controller = new PbRpcController; + qDebug("before service->callmethod()"); + service->CallMethod(methodDesc, controller, req, resp, NewCallback(this, &RpcServer::done, resp, controller)); diff --git a/server/myservice.cpp b/server/myservice.cpp index 93e625c..de438e1 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -3,6 +3,28 @@ #define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} +int MyService::getStreamIndex(unsigned int portIdx, + unsigned int streamId) +{ + int i; + + // note: index and id are interchageable for port but not for stream + + Q_ASSERT(portIdx < numPorts); + + for (i = 0; i < portInfo[portIdx].streamList.size(); i++) + { + if (streamId == portInfo[portIdx].streamList.at(i).d.stream_id().id()) + goto _found; + } + + qDebug("%s: stream id %d not found", __PRETTY_FUNCTION__, streamId); + return -1; + +_found: + return i; +} + MyService::MyService(AbstractHost *host) { pcap_if_t *dev; @@ -24,18 +46,12 @@ MyService::MyService(AbstractHost *host) /* Count number of local ports */ for(dev = alldevs; dev != NULL; dev = dev->next) numPorts++; - + portInfo = new PortInfo[numPorts]; /* Populate and Print the list */ - for(i=0, dev=alldevs; dev!=NULL; i++, dev=dev->next) + for(i=0, dev=alldevs; (i < numPorts) && (dev!=NULL); i++, dev=dev->next) { -#if 0 // PB - //portInfo[i].portId = i; - //portInfo[i].dev = dev; - //portInfo[i].streamHead = NULL; - //portInfo[i].streamTail = NULL; -#endif portInfo[i].setId(i); portInfo[i].setPcapDev(dev); #if 1 @@ -44,8 +60,17 @@ MyService::MyService(AbstractHost *host) { LOG(" (%s)\n", dev->description); } - else - LOG(" (No description available)\n"); +#endif +#if 0 + // FIXME(HI): Testing only!!!! + { + StreamInfo s; + + s.d.mutable_stream_id()->set_id(0); + portInfo[i].streamList.append(s); + s.d.mutable_stream_id()->set_id(1); + portInfo[i].streamList.append(s); + } #endif } @@ -61,11 +86,7 @@ _fail: MyService::~MyService() { - unsigned int i; -#if 0 // PB????? - for (i = 0; i < numPorts; i++) - DeleteAllStreams(i); -#endif + delete portInfo; pcap_freealldevs(alldevs); } @@ -75,14 +96,15 @@ void MyService::getPortIdList( ::OstProto::PortIdList* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); for (uint i = 0; i < numPorts; i++) - response->add_port_id(portInfo[i].d.port_id()); + { + ::OstProto::PortId *p; - qDebug("Server(%s): portid count = %d", __FUNCTION__, response->port_id_size()); - - qDebug("Server(%s): %s", __FUNCTION__, response->DebugString().c_str()); + p = response->add_port_id(); + p->set_id(portInfo[i].d.port_id().id()); + } done->Run(); } @@ -92,19 +114,19 @@ const ::OstProto::PortIdList* request, ::OstProto::PortConfigList* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); for (int i=0; i < request->port_id_size(); i++) { - unsigned int id; + unsigned int idx; - id = request->port_id(i); - if (id < numPorts) + idx = request->port_id(i).id(); + if (idx < numPorts) { - OstProto::PortConfig *p; + OstProto::Port *p; - p = response->add_list(); - p->CopyFrom(portInfo[request->port_id(i)].d); + p = response->add_port(); + p->CopyFrom(portInfo[idx].d); } } @@ -112,34 +134,34 @@ const ::OstProto::PortIdList* request, } void MyService::getStreamIdList(::google::protobuf::RpcController* controller, -const ::OstProto::PortIdList* request, +const ::OstProto::PortId* request, ::OstProto::StreamIdList* response, ::google::protobuf::Closure* done) { + unsigned int portIdx; - for (int i = 0; i < request->port_id_size(); i++) + qDebug("In %s", __PRETTY_FUNCTION__); + + portIdx = request->id(); + if (portIdx >= numPorts) { - unsigned int portId; - - portId = request->port_id(i); - if (portId >= numPorts) - { - qDebug("%s: Invalid port id %d", __FUNCTION__, portId); - continue; // TODO: Partial status of RPC - } - - for (int j = 0; j < portInfo[portId].streamList.size(); j++) - { - OstProto::StreamId *s, *q; - - q = portInfo[portId].streamList[j].d.mutable_id(); - assert(q->port_id() == portId); - - s = response->add_id(); - s->set_port_id(portId); - s->set_stream_id(q->stream_id()); - } + qDebug("%s: Invalid port id %d", __PRETTY_FUNCTION__, portIdx); + controller->SetFailed("Invalid Port Id"); + goto _exit; // TODO(LOW): Partial status of RPC } + + response->mutable_port_id()->set_id(portIdx); + for (int j = 0; j < portInfo[portIdx].streamList.size(); j++) + { + OstProto::StreamId *s, *q; + + q = portInfo[portIdx].streamList[j].d.mutable_stream_id(); + + s = response->add_stream_id(); + s->CopyFrom(*q); + } + +_exit: done->Run(); } @@ -148,43 +170,32 @@ const ::OstProto::StreamIdList* request, ::OstProto::StreamConfigList* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + unsigned int portIdx; - for (int i = 0; i < request->id_size(); i++) + qDebug("In %s", __PRETTY_FUNCTION__); + + portIdx = request->port_id().id(); + if (portIdx >= numPorts) { - unsigned int portId; - unsigned int streamId; - - portId = request->id(i).port_id(); - if (portId >= numPorts) - { - qDebug("%s: Invalid port id %d", __FUNCTION__, portId); - continue; // TODO: Partial status of RPC - } - - streamId = request->id(i).stream_id(); - if (streamId >= numPorts) - { - qDebug("%s: Invalid port id %d", __FUNCTION__, portId); - continue; // TODO: Partial status of RPC - } - - for (int j = 0; j < portInfo[portId].streamList.size(); j++) - { - OstProto::Stream *s, *q; - -#if 0 - q = portInfo[portId].streamList[j].d.e_stream(); - assert(q->port_id() == portId); - - s = response->add_stream(); - s->set_port_id(portId); - s->set_stream_id(q->stream_id()); -#endif - // TODO: more params - } + controller->SetFailed("invalid portid"); + goto _exit; } - controller->SetFailed("Not Implemented"); + + response->mutable_port_id()->set_id(portIdx); + for (int i = 0; i < request->stream_id_size(); i++) + { + int streamIndex; + OstProto::Stream *s; + + streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); + if (streamIndex < 0) + continue; // TODO(LOW): Partial status of RPC + + s = response->add_stream(); + s->CopyFrom(portInfo[portIdx].streamList[streamIndex].d); + } + +_exit: done->Run(); } @@ -193,8 +204,36 @@ const ::OstProto::StreamIdList* request, ::OstProto::Ack* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); - controller->SetFailed("Not Implemented"); + unsigned int portIdx; + + qDebug("In %s", __PRETTY_FUNCTION__); + + portIdx = request->port_id().id(); + if (portIdx >= numPorts) + { + controller->SetFailed("invalid portid"); + goto _exit; + } + + for (int i = 0; i < request->stream_id_size(); i++) + { + int streamIndex; + StreamInfo s; + + // If stream with same id as in request exists already ==> error!! + streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); + if (streamIndex >= 0) + continue; // TODO(LOW): Partial status of RPC + + // Append a new "default" stream - actual contents of the new stream is + // expected in a subsequent "modifyStream" request - set the stream id + // now itself however!!! + s.d.mutable_stream_id()->CopyFrom(request->stream_id(i)); + portInfo[portIdx].streamList.append(s); + + // TODO(LOW): fill-in response "Ack"???? + } +_exit: done->Run(); } @@ -203,8 +242,31 @@ const ::OstProto::StreamIdList* request, ::OstProto::Ack* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); - controller->SetFailed("Not Implemented"); + unsigned int portIdx; + + qDebug("In %s", __PRETTY_FUNCTION__); + + portIdx = request->port_id().id(); + if (portIdx >= numPorts) + { + controller->SetFailed("invalid portid"); + goto _exit; + } + + for (int i = 0; i < request->stream_id_size(); i++) + { + int streamIndex; + StreamInfo s; + + streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); + if (streamIndex < 0) + continue; // TODO(LOW): Partial status of RPC + + portInfo[portIdx].streamList.removeAt(streamIndex); + + // TODO(LOW): fill-in response "Ack"???? + } +_exit: done->Run(); } @@ -213,8 +275,32 @@ const ::OstProto::StreamConfigList* request, ::OstProto::Ack* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); - controller->SetFailed("Not Implemented"); + unsigned int portIdx; + + qDebug("In %s", __PRETTY_FUNCTION__); + + portIdx = request->port_id().id(); + if (portIdx >= numPorts) + { + controller->SetFailed("invalid portid"); + goto _exit; + } + + for (int i = 0; i < request->stream_size(); i++) + { + int streamIndex; + + streamIndex = getStreamIndex(portIdx, + request->stream(i).stream_id().id()); + if (streamIndex < 0) + continue; // TODO(LOW): Partial status of RPC + + portInfo[portIdx].streamList[streamIndex].d.MergeFrom( + request->stream(i)); + + // TODO(LOW): fill-in response "Ack"???? + } +_exit: done->Run(); } @@ -223,7 +309,7 @@ const ::OstProto::PortIdList* request, ::OstProto::Ack* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); controller->SetFailed("Not Implemented"); done->Run(); } @@ -233,7 +319,7 @@ const ::OstProto::PortIdList* request, ::OstProto::Ack* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); controller->SetFailed("Not Implemented"); done->Run(); } @@ -243,7 +329,7 @@ const ::OstProto::PortIdList* request, ::OstProto::Ack* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); controller->SetFailed("Not Implemented"); done->Run(); } @@ -253,7 +339,7 @@ const ::OstProto::PortIdList* request, ::OstProto::Ack* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); controller->SetFailed("Not Implemented"); done->Run(); } @@ -263,7 +349,7 @@ const ::OstProto::PortIdList* request, ::OstProto::CaptureBufferList* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); controller->SetFailed("Not Implemented"); done->Run(); } @@ -273,7 +359,7 @@ const ::OstProto::PortIdList* request, ::OstProto::PortStatsList* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); controller->SetFailed("Not Implemented"); done->Run(); } @@ -283,7 +369,7 @@ const ::OstProto::PortIdList* request, ::OstProto::Ack* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); controller->SetFailed("Not Implemented"); done->Run(); } diff --git a/server/myservice.h b/server/myservice.h index 83ebc0f..45577be 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -12,6 +12,8 @@ #include #include +#include "../rpc/pbhelper.h" + #define MAX_PKT_HDR_SIZE 1536 #define MAX_STREAM_NAME_SIZE 64 @@ -23,21 +25,7 @@ class StreamInfo OstProto::Stream d; -#if 0 // PB - unsigned int id; - - char name[MAX_STREAM_NAME_SIZE]; - unsigned char pktHdr[MAX_PKT_HDR_SIZE]; - unsigned short hdrLen; - unsigned short pktLen; - unsigned int dataPattern; - unsigned int flags; -#define STREAM_FLAG_MASK_STATUS 0x00000001 -#define STREAM_FLAG_VALUE_STATUS_DISABLED 0x00000000 -#define STREAM_FLAG_VALUE_STATUS_ENABLED 0x00000001 - - struct _Stream *next; -#endif + StreamInfo() { PbHelper pbh; pbh.ForceSetSingularDefault(&d); } }; @@ -45,28 +33,23 @@ class PortInfo { friend class MyService; - OstProto::PortConfig d; + OstProto::Port d; pcap_if_t *dev; + /*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */ QList streamList; -#if 0 // PB - unsigned int portId; // FIXME:need? - Stream *streamHead; - Stream *streamTail; -#endif - public: // TODO(LOW): Both setId and setPcapDev() should together form the ctor - void setId(unsigned int id) { d.set_port_id(id); } + void setId(unsigned int id) { d.mutable_port_id()->set_id(id); } void setPcapDev(pcap_if_t *dev) { this->dev = dev; - d.set_name("eth"); // FIXME: suffix portid + d.set_name("eth"); // FIXME(MED): suffix portid d.set_description(dev->description); - d.set_is_enabled(true); // FIXME:check - d.set_is_oper_up(true); // FIXME:check - d.set_is_exclusive_control(false); // FIXME: check + d.set_is_enabled(true); // FIXME(MED):check + d.set_is_oper_up(true); // FIXME(MED):check + d.set_is_exclusive_control(false); // FIXME(MED): check } }; @@ -75,72 +58,74 @@ class MyService: public OstProto::OstService AbstractHost *host; char logStr[1024]; - unsigned numPorts; + uint numPorts; + /*! PortInfo::d::port_id and index into portInfo[] are same! */ PortInfo *portInfo; pcap_if_t *alldevs; + int getStreamIndex(unsigned int portIdx,unsigned int streamId); + public: MyService(AbstractHost* host); virtual ~MyService(); - //static const ::google::protobuf::ServiceDescriptor* descriptor(); - + /* Methods provided by the service */ virtual void getPortIdList(::google::protobuf::RpcController* controller, - const ::OstProto::Void* request, - ::OstProto::PortIdList* response, - ::google::protobuf::Closure* done); + const ::OstProto::Void* request, + ::OstProto::PortIdList* response, + ::google::protobuf::Closure* done); virtual void getPortConfig(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::PortConfigList* response, - ::google::protobuf::Closure* done); + const ::OstProto::PortIdList* request, + ::OstProto::PortConfigList* response, + ::google::protobuf::Closure* done); virtual void getStreamIdList(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::StreamIdList* response, - ::google::protobuf::Closure* done); + const ::OstProto::PortId* request, + ::OstProto::StreamIdList* response, + ::google::protobuf::Closure* done); virtual void getStreamConfig(::google::protobuf::RpcController* controller, - const ::OstProto::StreamIdList* request, - ::OstProto::StreamConfigList* response, - ::google::protobuf::Closure* done); + const ::OstProto::StreamIdList* request, + ::OstProto::StreamConfigList* response, + ::google::protobuf::Closure* done); virtual void addStream(::google::protobuf::RpcController* controller, - const ::OstProto::StreamIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); virtual void deleteStream(::google::protobuf::RpcController* controller, - const ::OstProto::StreamIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); virtual void modifyStream(::google::protobuf::RpcController* controller, - const ::OstProto::StreamConfigList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); + const ::OstProto::StreamConfigList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); virtual void startTx(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); virtual void stopTx(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); virtual void startCapture(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); virtual void stopCapture(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); virtual void getCaptureBuffer(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::CaptureBufferList* response, - ::google::protobuf::Closure* done); + const ::OstProto::PortIdList* request, + ::OstProto::CaptureBufferList* response, + ::google::protobuf::Closure* done); virtual void getStats(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::PortStatsList* response, - ::google::protobuf::Closure* done); + const ::OstProto::PortIdList* request, + ::OstProto::PortStatsList* response, + ::google::protobuf::Closure* done); virtual void clearStats(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); }; #endif diff --git a/server/rxtx.cpp b/server/rxtx.cpp index f4b5308..11789f1 100644 --- a/server/rxtx.cpp +++ b/server/rxtx.cpp @@ -1,5 +1,5 @@ -File Not used anymore +FIXME(HI): File Not used anymore #if 0 #include "qtglobal" // FIXME: needed only for qdebug diff --git a/server/rxtx.h b/server/rxtx.h index fac9331..7b86991 100644 --- a/server/rxtx.h +++ b/server/rxtx.h @@ -1,5 +1,5 @@ -File not used anymore +FIXME(HI): File not used anymore #if 0 From 9e7b3239730c221231952b2699cc675fb1bc7340 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 30 Aug 2008 08:49:08 +0000 Subject: [PATCH 08/98] Rewrote DumpView as a subclass of QAbstractItemView (as it should be). Correspondingly reworked PacketModel to work with DumpView. Added Dot3Protocol and PayloadProtocol to Stream class --- client/dumpview.cpp | 265 +++++++++-- client/dumpview.h | 34 +- client/packetmodel.cpp | 816 +--------------------------------- client/stream.cpp | 356 ++++++++++++++- client/stream.h | 83 +++- client/streamconfigdialog.cpp | 12 +- client/streamconfigdialog.ui | 5 +- common/protocol.proto | 4 +- 8 files changed, 718 insertions(+), 857 deletions(-) diff --git a/client/dumpview.cpp b/client/dumpview.cpp index a238e95..79edab9 100644 --- a/client/dumpview.cpp +++ b/client/dumpview.cpp @@ -1,11 +1,10 @@ #include "dumpview.h" +//public: DumpView::DumpView(QWidget *parent) { int w, h; - data.resize(73); - // NOTE: Monospaced fonts only !!!!!!!!!!! setFont(QFont("Courier")); w = fontMetrics().width('X'); @@ -17,6 +16,7 @@ DumpView::DumpView(QWidget *parent) mSelectedRow = mSelectedCol = -1; // calculate width for offset column and the whitespace that follows it + // 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ mOffsetPaneTopRect = QRect(0, 0, w*4, h); mDumpPaneTopRect = QRect(mOffsetPaneTopRect.right()+w*3, 0, w*((8*3-1)+2+(8*3-1)), h); @@ -25,15 +25,10 @@ DumpView::DumpView(QWidget *parent) qDebug("DumpView::DumpView"); } +QModelIndex DumpView::indexAt( const QPoint &point ) const +{ #if 0 -QSize DumpView::sizeHint() const -{ -} -#endif - -void DumpView::mousePressEvent(QMouseEvent *event) -{ - int x = event->x(); + int x = point.x(); int row, col; if (x > mAsciiPaneTopRect.left()) @@ -48,12 +43,12 @@ void DumpView::mousePressEvent(QMouseEvent *event) { col = (x - mDumpPaneTopRect.left()) / (mCharWidth*3); } - row = event->y()/mLineHeight; + row = point.y()/mLineHeight; if ((col < 16) && (row < ((data.size()+16)/16))) { - mSelectedRow = row; - mSelectedCol = col; + selrow = row; + selcol = col; } else goto _exit; @@ -62,26 +57,163 @@ void DumpView::mousePressEvent(QMouseEvent *event) if ((row == (((data.size()+16)/16) - 1)) && (col >= (data.size() % 16))) goto _exit; - qDebug("dumpview::selection(%d, %d)", mSelectedRow, mSelectedCol); - update(); - return; + qDebug("dumpview::selection(%d, %d)", selrow, selcol); + + offset = selrow * 16 + selcol; +#if 0 + for(int i = 0; i < model()->rowCount(parent); i++) + { + QModelIndex index = model()->index(i, 0, parent); + + if (model()->hasChildren(index)) + indexAtOffset(offset, index); // Non Leaf + else + if ( + dump.append(model()->data(index, Qt::UserRole).toByteArray()); // Leaf + // FIXME: Use RawValueRole instead of UserRole + } +#endif +} _exit: // Clear existing selection - mSelectedRow = -1; + selrow = -1; +#endif + + return QModelIndex(); +} + +void DumpView::scrollTo( const QModelIndex &index, ScrollHint hint ) +{ + // FIXME: implement scrolling +} + +QRect DumpView::visualRect( const QModelIndex &index ) const +{ + // FIXME: calculate actual rect + return rect(); +} + +//protected: +int DumpView::horizontalOffset() const +{ + return horizontalScrollBar()->value(); +} + +bool DumpView::isIndexHidden( const QModelIndex &index ) const +{ + return false; +} + +QModelIndex DumpView::moveCursor( CursorAction cursorAction, + Qt::KeyboardModifiers modifiers ) +{ + // FIXME(MED): need to implement movement using cursor + return currentIndex(); +} + +void DumpView::setSelection( const QRect &rect, + QItemSelectionModel::SelectionFlags flags ) +{ + // FIXME(HI): calculate indexes using rect + selectionModel()->select(QModelIndex(), flags); +} + +int DumpView::verticalOffset() const +{ + return verticalScrollBar()->value(); +} + +QRegion DumpView::visualRegionForSelection( const QItemSelection &selection ) const +{ + // FIXME(HI) + return QRegion(rect()); +} + +//protected slots: +void DumpView::dataChanged( const QModelIndex &topLeft, + const QModelIndex &bottomRight ) +{ + // FIXME(HI) update(); } +void DumpView::selectionChanged( const QItemSelection &selected, + const QItemSelection &deselected ) +{ + // FIXME(HI) + update(); +} + +void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize, + QModelIndex parent) +{ + // TODO(LOW): Assumption - only single selection - enforce/ensure this + + for(int i = 0; i < model()->rowCount(parent); i++) + { + QModelIndex index = model()->index(i, 0, parent); + + if (model()->hasChildren(index)) + { + // Non Leaf + + // A non-leaf has no dump data of its own but is rather a + // container for its children. So we calculate ofs/size based + // on this fact + if (selectionModel()->isSelected(index)) + { + selOfs = dump.size(); + populateDump(dump, selOfs, selSize, index); + selSize = dump.size() - selOfs; + } + else + { + populateDump(dump, selOfs, selSize, index); + } + } + else + { + // Leaf + if (selectionModel()->isSelected(index)) + { + int size, j; + + selOfs = dump.size(); + size = model()->data(index, Qt::UserRole).toByteArray().size(); + + // Take care of multiple indexes (2 or more) mapping onto + // same dump byte(s) + j = i-1; + while ((size == 0) && (j >= 0)) + { + size = model()->data(index.sibling(j,0), Qt::UserRole). + toByteArray().size(); + selOfs -= size; + j++; + } + selSize = size; + } + dump.append(model()->data(index, Qt::UserRole).toByteArray()); + } + // FIXME: Use RawValueRole instead of UserRole + } +} + +// TODO(LOW): rewrite this function - it's a mess! void DumpView::paintEvent(QPaintEvent* event) { - QStylePainter painter(this); + QStylePainter painter(viewport()); QRect offsetRect = mOffsetPaneTopRect; QRect dumpRect = mDumpPaneTopRect; QRect asciiRect = mAsciiPaneTopRect; QPalette pal = palette(); - QByteArray ba; + QByteArray data; + //QByteArray ba; + int selOfs = -1, selSize; + int curSelOfs, curSelSize; - //qDebug("dumpview::paintEvent"); + qDebug("dumpview::paintEvent"); // FIXME(LOW): unable to set the self widget's font in constructor painter.setFont(QFont("Courier")); @@ -89,12 +221,15 @@ void DumpView::paintEvent(QPaintEvent* event) // set a white background painter.fillRect(rect(), QBrush(QColor(Qt::white))); + if (model()) + populateDump(data, selOfs, selSize); + // display the offset, dump and ascii panes 8 + 8 bytes on a line for (int i = 0; i < data.size(); i+=16) - { + { QString dumpStr, asciiStr; - ba = data.mid(i, 16); + //ba = data.mid(i, 16); // display offset painter.drawItemText(offsetRect, Qt::AlignLeft | Qt::AlignTop, pal, @@ -128,48 +263,102 @@ void DumpView::paintEvent(QPaintEvent* event) painter.drawItemText(asciiRect, Qt::AlignLeft | Qt::AlignTop, pal, true, asciiStr, QPalette::WindowText); - // overpaint selection (if any) - if ((i/16) == mSelectedRow) + // if no selection, skip selection painting + if (selOfs < 0) + goto _next; + + // Check overlap between current row and selection + { + QRect r1(i, 0, qMin(16, data.size()-i), 8); + QRect s1(selOfs, 0, selSize, 8); + if (r1.intersects(s1)) + { + QRect t = r1.intersected(s1); + + curSelOfs = t.x(); + curSelSize = t.width(); + } + else + curSelSize = 0; + + } + + // overpaint selection on current row (if any) + if (curSelSize > 0) { QRect r; - unsigned char c = data.at(mSelectedRow*16+mSelectedCol); QString selectedAsciiStr, selectedDumpStr; qDebug("dumpview::paintEvent - Highlighted"); - selectedDumpStr.append(QString("%1").arg((uint) c, 2, 16, QChar('0')).toUpper()); + // construct the dumpStr and asciiStr + for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++) + { + unsigned char c = data.at(k); - if (isPrintable(c)) - selectedAsciiStr.append(QChar(c)); - else - selectedAsciiStr.append(QChar('.')); + // extra space after 8 bytes + if (((k+8) % 16) == 0) + { + // Avoid adding space at the start for fields starting + // at second column 8 byte boundary + if (k!=curSelOfs) + { + selectedDumpStr.append(" "); + selectedAsciiStr.append(" "); + } + } + + selectedDumpStr.append(QString("%1").arg((uint)c, 2, 16, + QChar('0')).toUpper()).append(" "); + + if (isPrintable(c)) + selectedAsciiStr.append(QChar(c)); + else + selectedAsciiStr.append(QChar('.')); + } // display dump r = dumpRect; - if (mSelectedCol < 8) - r.translate(mCharWidth*(mSelectedCol*3), 0); + if ((curSelOfs - i) < 8) + r.translate(mCharWidth*(curSelOfs-i)*3, 0); else - r.translate(mCharWidth*(mSelectedCol*3+1), 0); - r.setWidth(mCharWidth*2); + r.translate(mCharWidth*((curSelOfs-i)*3+1), 0); + + // adjust width taking care of selection stretching between + // the two 8byte columns + if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) + r.setWidth((curSelSize * 3 + 1) * mCharWidth); + else + r.setWidth((curSelSize * 3) * mCharWidth); + painter.fillRect(r, pal.highlight()); painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, true, selectedDumpStr, QPalette::HighlightedText); // display ascii r = asciiRect; - if (mSelectedCol < 8) - r.translate(mCharWidth*(mSelectedCol), 0); + if ((curSelOfs - i) < 8) + r.translate(mCharWidth*(curSelOfs-i)*1, 0); else - r.translate(mCharWidth*(mSelectedCol+1), 0); - r.setWidth(mCharWidth); + r.translate(mCharWidth*((curSelOfs-i)*1+1), 0); + + // adjust width taking care of selection stretching between + // the two 8byte columns + if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) + r.setWidth((curSelSize * 1 + 1) * mCharWidth); + else + r.setWidth((curSelSize * 1) * mCharWidth); + painter.fillRect(r, pal.highlight()); painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, true, selectedAsciiStr, QPalette::HighlightedText); } +_next: // move the rects down offsetRect.translate(0, mLineHeight); dumpRect.translate(0, mLineHeight); asciiRect.translate(0, mLineHeight); } } + diff --git a/client/dumpview.h b/client/dumpview.h index 4578a91..cdbcde7 100644 --- a/client/dumpview.h +++ b/client/dumpview.h @@ -1,25 +1,33 @@ #include // FIXME: High -class DumpView: public QWidget // QAbstractItemView // FIXME + +class DumpView: public QAbstractItemView { -public: +public: DumpView(QWidget *parent=0); - // bool setBase(uint base); // valid values: 16, 8, 10, 2 etc. - // void hideAsciiPane(void); - // void showAsciiPane(void); - // void hideOffsetPane(void); - // void showOffsetPane(void); - - //QSize sizeHint() const; + QModelIndex indexAt( const QPoint &point ) const; + void scrollTo( const QModelIndex &index, ScrollHint hint = EnsureVisible ); + QRect visualRect( const QModelIndex &index ) const; protected: - void mousePressEvent(QMouseEvent *event); - //void mouseMoveEvent(QMouseEvent *event); + int horizontalOffset() const; + bool isIndexHidden( const QModelIndex &index ) const; + QModelIndex moveCursor( CursorAction cursorAction, + Qt::KeyboardModifiers modifiers ); + void setSelection( const QRect &rect, QItemSelectionModel::SelectionFlags flags ); + int verticalOffset() const; + QRegion visualRegionForSelection( const QItemSelection &selection ) const; +protected slots: + void dataChanged( const QModelIndex &topLeft, + const QModelIndex &bottomRight ); + void selectionChanged( const QItemSelection &selected, + const QItemSelection &deselected ); void paintEvent(QPaintEvent *event); private: - QString toAscii(QByteArray ba); + void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize, + QModelIndex parent = QModelIndex()); bool inline isPrintable(char c) {if ((c > 48) && (c < 126)) return true; else return false; } @@ -27,8 +35,8 @@ private: QRect mOffsetPaneTopRect; QRect mDumpPaneTopRect; QRect mAsciiPaneTopRect; - QByteArray data; int mSelectedRow, mSelectedCol; int mLineHeight; int mCharWidth; }; + diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 5800413..a1d4b7f 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -4,22 +4,6 @@ PacketModel::PacketModel(Stream *pStream, QObject *parent) { mpStream = pStream; -#ifdef NEW_IMPL -// Nothing else -#else - populatePacketProtocols(); - - registerFrameTypeProto(); - registerVlanProto(); - registerIpProto(); - registerArpProto(); - registerTcpProto(); - registerUdpProto(); - registerIcmpProto(); - registerIgmpProto(); - registerData(); - registerInvalidProto(); -#endif } int PacketModel::rowCount(const QModelIndex &parent) const @@ -29,22 +13,14 @@ int PacketModel::rowCount(const QModelIndex &parent) const // Parent == Invalid i.e. Invisible Root. // ==> Children are Protocol (Top Level) Items if (!parent.isValid()) -#ifdef NEW_IMPL return mpStream->numProtocols(); -#else - return protoCount(); -#endif // Parent - Valid Item parentId.w = parent.internalId(); switch(parentId.ws.type) { case ITYP_PROTOCOL: -#ifdef NEW_IMPL return mpStream->protocol(parentId.ws.protocol)->numFields(); -#else - return fieldCount(parentId.ws.protocol); -#endif case ITYP_FIELD: return 0; default: @@ -137,40 +113,44 @@ _exit: QVariant PacketModel::data(const QModelIndex &index, int role) const { IndexId id; -#ifdef NEW_IMPL -// Nothing -#else - ProtocolInfo proto; -#endif if (!index.isValid()) return QVariant(); + id.w = index.internalId(); + + // FIXME(HI): Relook at this completely + if (role == Qt::UserRole) + { + switch(id.ws.type) + { + case ITYP_PROTOCOL: + return QByteArray(); + + case ITYP_FIELD: + return mpStream->protocol(id.ws.protocol)->fieldRawValue( + index.row()); + + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + return QByteArray(); + } + if (role != Qt::DisplayRole) return QVariant(); - id.w = index.internalId(); switch(id.ws.type) { case ITYP_PROTOCOL: -#ifdef NEW_IMPL return QString("%1 (%2)") .arg(mpStream->protocol(id.ws.protocol)->protocolShortName()) .arg(mpStream->protocol(id.ws.protocol)->protocolName()); -#else - return protoName(id.ws.protocol); -#endif case ITYP_FIELD: -#ifdef NEW_IMPL return mpStream->protocol(id.ws.protocol)->fieldName(index.row()) + QString(" : ") + mpStream->protocol(id.ws.protocol)->fieldTextValue(index.row()); -#else - return fieldName(id.ws.protocol, index.row()) + - QString(" : ") + - fieldTextValue(id.ws.protocol, index.row()).toString(); -#endif default: qWarning("%s: Unhandled ItemType", __FUNCTION__); @@ -180,759 +160,3 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const return QVariant(); } - -#ifdef NEW_IMPL -// required methods all part of the Stream class -#else -/* -** --------------- Private Stuff ----------------- -** FIXME(MED): Move these to the Stream Class -** -*/ - -/*! - Looking at the stream's protocols and populate an ordered list of - protocols accordingly. The order of protocols will be in the order of - protocol headers viz. - - - None/Eth2/802.3 (Mac Addr) - - LLC - - SNAP - - SVLAN - - CVLAN - - L3 (IP/ARP) - - L4 (TCP/UDP/ICMP/IGMP) - -*/ -void PacketModel::populatePacketProtocols() -{ - int proto; - - // Clear the protocols list - mPacketProtocols.clear(); - - // Check and populate L2 Protocol - switch(mpStream->frameType()) - { - case Stream::e_ft_none: - proto = PTYP_L2_NONE; - break; - - case Stream::e_ft_eth_2: - proto = PTYP_L2_ETH_2; - break; - - case Stream::e_ft_802_3_raw: - proto = PTYP_L2_802_3_RAW; - break; - - case Stream::e_ft_802_3_llc: - mPacketProtocols.append(PTYP_L2_NONE); - proto = PTYP_L2_802_3_LLC; - break; - - case Stream::e_ft_snap: - mPacketProtocols.append(PTYP_L2_NONE); - mPacketProtocols.append(PTYP_L2_802_3_LLC); - proto = PTYP_L2_SNAP; - break; - - default: - qDebug("%s: Unsupported frametype %d", __FUNCTION__, - mpStream->frameType()); - proto = PTYP_INVALID; - } - mPacketProtocols.append(proto); - - // Check and populate VLANs, if present - if (mpStream->vlan()->vlanFlags().testFlag(VlanProtocol::VlanSvlanTagged)) - mPacketProtocols.append(PTYP_SVLAN); - - if (mpStream->vlan()->vlanFlags().testFlag(VlanProtocol::VlanCvlanTagged)) - mPacketProtocols.append(PTYP_CVLAN); - - // Check and populate L3 protocols - switch (mpStream->l3Proto()) - { - case Stream::e_l3_none : - goto _data; - break; - - case Stream::e_l3_ip : - proto = PTYP_L3_IP; - break; - - case Stream::e_l3_arp: - proto = PTYP_L3_ARP; - break; - - default: - qDebug("%s: Unsupported L3 Proto %d", __FUNCTION__, - mpStream->l3Proto()); - proto = PTYP_INVALID; - } - mPacketProtocols.append(proto); - - // Check and populate L4 protocol - switch(mpStream->l4Proto()) - { - case Stream::e_l4_none: - goto _data; - break; - case Stream::e_l4_tcp: - proto = PTYP_L4_TCP; - break; - case Stream::e_l4_udp: - proto = PTYP_L4_UDP; - break; - case Stream::e_l4_icmp: - proto = PTYP_L4_ICMP; - break; - case Stream::e_l4_igmp: - proto = PTYP_L4_IGMP; - break; - default: - qDebug("%s: Unsupported L4 Proto %d", __FUNCTION__, - mpStream->l4Proto()); - proto = PTYP_INVALID; - }; - mPacketProtocols.append(proto); - -_data: - mPacketProtocols.append(PTYP_DATA); -} -/*! - Returns the count of protocols in the current stream -*/ -int PacketModel::protoCount() const -{ - return mPacketProtocols.count(); -} - -/*! - Returns the count of fields in the given protocol -*/ -int PacketModel::fieldCount(int protocol) const -{ - ProtocolInfo proto; - - if (protocol >= mPacketProtocols.count()) - return 0; - - foreach(proto, mProtocols) - { - if (proto.handle == mPacketProtocols.at(protocol)) - { - qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data()); - qDebug("fieldcount = %d", proto.fieldList.size()); - return proto.fieldList.count(); - } - } - - return 0; -} - -QString PacketModel::protoName(int protocol) const -{ - ProtocolInfo proto; - - if (protocol >= mPacketProtocols.count()) - return 0; - - foreach(proto, mProtocols) - { - if (proto.handle == mPacketProtocols.at(protocol)) - { - qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data()); - qDebug("fieldcount = %d", proto.fieldList.size()); - return proto.name; - } - } - - return QString(); -} - -QString PacketModel::fieldName(int protocol, int field) const -{ - ProtocolInfo proto; - - if (protocol >= mPacketProtocols.count()) - return 0; - - foreach(proto, mProtocols) - { - if (proto.handle == mPacketProtocols.at(protocol)) - { - qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data()); - qDebug("fieldcount = %d", proto.fieldList.size()); - if (field >= proto.fieldList.count()) - return QString(); - - return proto.fieldList.at(field).name; - } - } - - return QString(); -} - -QVariant PacketModel::fieldTextValue(int protocol, int field) const -{ - if (protocol >= mPacketProtocols.count()) - return QVariant(); - - switch(mPacketProtocols.at(protocol)) - { - case PTYP_L2_NONE: - case PTYP_L2_ETH_2: - return ethField(field, FROL_TEXT_VALUE); - case PTYP_L2_802_3_RAW: - //return dot3Field(field, FROL_TEXT_VALUE); // FIXME(HIGH) - return ethField(field, FROL_TEXT_VALUE); - case PTYP_L2_802_3_LLC: - return llcField(field, FROL_TEXT_VALUE); - case PTYP_L2_SNAP: - return snapField(field, FROL_TEXT_VALUE); - - case PTYP_SVLAN: - return svlanField(field, FROL_TEXT_VALUE); - case PTYP_CVLAN: - // return cvlanField(field, FROL_TEXT_VALUE); // FIXME(HIGH) - return svlanField(field, FROL_TEXT_VALUE); - - case PTYP_L3_IP: - return ipField(field, FROL_TEXT_VALUE); - case PTYP_L3_ARP: - return QString(); // FIXME(HIGH) - - case PTYP_L4_TCP: - return tcpField(field, FROL_TEXT_VALUE); - case PTYP_L4_UDP: - return udpField(field, FROL_TEXT_VALUE); - case PTYP_L4_ICMP: - return QString(); // FIXME(HIGH) - case PTYP_L4_IGMP: - return QString(); // FIXME(HIGH) - - case PTYP_INVALID: - return QString(); // FIXME(HIGH) - case PTYP_DATA: - return QString(); // FIXME(HIGH) - } - - return QString(); -} - -QVariant PacketModel::ethField(int field, int role) const -{ - FieldInfo info; - - // FIXME(MED): Mac Addr formatting - switch(field) - { - case 0: - info.name = QString("Destination Mac Address"); - info.textValue = QString("%1"). - arg(mpStream->mac()->dstMac(), 12, BASE_HEX, QChar('0')); - break; - case 1: - info.name = QString("Source Mac Address"); - info.textValue = QString("%1"). - arg(mpStream->mac()->srcMac(), 12, BASE_HEX, QChar('0')); - break; - case 2: - info.name = QString("Type"); - info.textValue = QString("0x%1"). - arg(mpStream->eth2()->type(), 4, BASE_HEX, QChar('0')); - break; - default: - info.name = QString(); - info.textValue = QString(); - } - - switch(role) - { - case FROL_NAME: - return info.name; - case FROL_TEXT_VALUE: - return info.textValue; - default: - ; - } - - Q_ASSERT(1 == 1); // Unreachable code - return QVariant(); -} - -QVariant PacketModel::llcField(int field, int role) const -{ - FieldInfo info; - - switch(field) - { - case 0: - info.name = QString("DSAP"); - info.textValue = QString("0x%1"). - arg(mpStream->llc()->dsap(), 2, BASE_HEX, QChar('0')); - break; - case 1: - info.name = QString("SSAP"); - info.textValue = QString("0x%1"). - arg(mpStream->llc()->ssap(), 2, BASE_HEX, QChar('0')); - break; - case 2: - info.name = QString("Control"); - info.textValue = QString("0x%1"). - arg(mpStream->llc()->ctl(), 2, BASE_HEX, QChar('0')); - break; - default: - info.name = QString(); - info.textValue = QString(); - } - - switch(role) - { - case FROL_NAME: - return info.name; - case FROL_TEXT_VALUE: - return info.textValue; - default: - ; - } - - Q_ASSERT(1 == 1); // Unreachable code - return QVariant(); -} - -QVariant PacketModel::snapField(int field, int role) const -{ - FieldInfo info; - - switch(field) - { - case 0: - info.name = QString("OUI"); - info.textValue = QString("0x%1"). - arg(mpStream->snap()->oui(), 6, BASE_HEX, QChar('0')); - break; - case 1: - info.name = QString("Type"); - info.textValue = QString("0x%1"). - arg(mpStream->eth2()->type(), 4, BASE_HEX, QChar('0')); - break; - default: - info.name = QString(); - info.textValue = QString(); - } - - switch(role) - { - case FROL_NAME: - return info.name; - case FROL_TEXT_VALUE: - return info.textValue; - default: - ; - } - - Q_ASSERT(1 == 1); // Unreachable code - return QVariant(); -} - -QVariant PacketModel::svlanField(int field, int role) const -{ - FieldInfo info; - - switch(field) - { - case 0: - info.name = QString("TPID"); - info.textValue = QString("0x%1"). - arg(mpStream->vlan()->stpid(), 4, BASE_HEX, QChar('0')); - break; - case 1: - info.name = QString("PCP"); - info.textValue = QString("%1"). - arg(mpStream->vlan()->svlanPrio()); - break; - case 2: - info.name = QString("DE"); - info.textValue = QString("%1"). - arg(mpStream->vlan()->svlanCfi()); - break; - case 3: - info.name = QString("VlanId"); - info.textValue = QString("%1"). - arg(mpStream->vlan()->svlanId()); - break; - default: - info.name = QString(); - info.textValue = QString(); - } - - switch(role) - { - case FROL_NAME: - return info.name; - case FROL_TEXT_VALUE: - return info.textValue; - default: - ; - } - - Q_ASSERT(1 == 1); // Unreachable code - return QVariant(); -} - - -QVariant PacketModel::ipField(int field, int role) const -{ - FieldInfo info; - - switch(field) - { - case 0: - info.name = QString("Version"); - info.textValue = QString("%1"). - arg(mpStream->ip()->ver()); - break; - case 1: - info.name = QString("Header Length"); - info.textValue = QString("%1"). - arg(mpStream->ip()->hdrLen()); - break; - case 2: - info.name = QString("TOS/DSCP"); - info.textValue = QString("0x%1"). - arg(mpStream->ip()->tos(), 2, BASE_HEX, QChar('0')); - break; - case 3: - info.name = QString("Total Length"); - info.textValue = QString("%1"). - arg(mpStream->ip()->totLen()); - break; - case 4: - info.name = QString("ID"); - info.textValue = QString("0x%1"). - arg(mpStream->ip()->id(), 2, BASE_HEX, QChar('0')); - break; - case 5: - info.name = QString("Flags"); - info.textValue = QString("0x%1"). - arg(mpStream->ip()->flags(), 2, BASE_HEX, QChar('0')); // FIXME(HIGH) - break; - case 6: - info.name = QString("Fragment Offset"); - info.textValue = QString("%1"). - arg(mpStream->ip()->fragOfs()); - break; - case 7: - info.name = QString("TTL"); - info.textValue = QString("%1"). - arg(mpStream->ip()->ttl()); - break; - case 8: - info.name = QString("Protocol Type"); - info.textValue = QString("0x%1"). - arg(mpStream->ip()->proto(), 2, BASE_HEX, QChar('0')); - break; - case 9: - info.name = QString("Checksum"); - info.textValue = QString("0x%1"). - arg(mpStream->ip()->cksum(), 4, BASE_HEX, QChar('0')); - break; - case 10: - info.name = QString("Source IP"); - info.textValue = QHostAddress(mpStream->ip()->srcIp()).toString(); - break; - case 11: - info.name = QString("Destination IP"); - info.textValue = QHostAddress(mpStream->ip()->dstIp()).toString(); - break; - default: - info.name = QString(); - info.textValue = QString(); - } - - switch(role) - { - case FROL_NAME: - return info.name; - case FROL_TEXT_VALUE: - return info.textValue; - default: - ; - } - - Q_ASSERT(1 == 1); // Unreachable code - return QVariant(); -} - - -QVariant PacketModel::tcpField(int field, int role) const -{ - FieldInfo info; - - switch(field) - { - case 0: - info.name = QString("Source Port"); - info.textValue = QString("%1"). - arg(mpStream->tcp()->srcPort()); - break; - case 1: - info.name = QString("Destination Port"); - info.textValue = QString("%1"). - arg(mpStream->tcp()->dstPort()); - break; - case 2: - info.name = QString("Seq Number"); - info.textValue = QString("%1"). - arg(mpStream->tcp()->seqNum()); - break; - case 3: - info.name = QString("Ack Number"); - info.textValue = QString("%1"). - arg(mpStream->tcp()->ackNum()); - break; - case 4: - info.name = QString("Header Length"); - info.textValue = QString("%1"). - arg(mpStream->tcp()->hdrLen()); - break; - case 5: - info.name = QString("Reserved"); - info.textValue = QString("%1"). - arg(mpStream->tcp()->rsvd()); - break; - case 6: - info.name = QString("Flags"); - info.textValue = QString("0x%1"). - arg(mpStream->tcp()->flags(), 2, BASE_HEX, QChar('0')); - break; - case 7: - info.name = QString("Window"); - info.textValue = QString("%1"). - arg(mpStream->tcp()->flags()); - break; - case 8: - info.name = QString("Checksum"); - info.textValue = QString("0x%1"). - arg(mpStream->tcp()->cksum(), 4, BASE_HEX, QChar('0')); - break; - case 9: - info.name = QString("Urgent Pointer"); - info.textValue = QString("%1"). - arg(mpStream->tcp()->urgPtr()); - break; - default: - info.name = QString(); - info.textValue = QString(); - } - - switch(role) - { - case FROL_NAME: - return info.name; - case FROL_TEXT_VALUE: - return info.textValue; - default: - ; - } - - Q_ASSERT(1 == 1); // Unreachable code - return QVariant(); -} - - -QVariant PacketModel::udpField(int field, int role) const -{ - FieldInfo info; - - switch(field) - { - case 0: - info.name = QString("Source Port"); - info.textValue = QString("%1"). - arg(mpStream->udp()->srcPort()); - break; - case 1: - info.name = QString("Destination Port"); - info.textValue = QString("%1"). - arg(mpStream->udp()->dstPort()); - break; - case 2: - info.name = QString("Total Length"); - info.textValue = QString("%1"). - arg(mpStream->udp()->totLen()); - break; - case 3: - info.name = QString("Checksum"); - info.textValue = QString("0x%1"). - arg(mpStream->udp()->cksum(), 4, BASE_HEX, QChar('0')); - break; - default: - info.name = QString(); - info.textValue = QString(); - } - - switch(role) - { - case FROL_NAME: - return info.name; - case FROL_TEXT_VALUE: - return info.textValue; - default: - ; - } - - Q_ASSERT(1 == 1); // Unreachable code - return QVariant(); -} - - - -/* -** ------------- Registration Functions --------------- -*/ - -void PacketModel::registerProto(uint handle, char *name, char *abbr) -{ - ProtocolInfo proto; - - proto.handle = handle; - proto.name = QString(name); - proto.abbr = QString(abbr); - mProtocols.append(proto); -} - -void PacketModel::registerField(uint protoHandle, char *name, char *abbr) -{ - for (int i = 0; i < mProtocols.size(); i++) - { - if (mProtocols.at(i).handle == protoHandle) - { - FieldInfo field; - - field.name = QString(name); - field.abbr = QString(abbr); - mProtocols[i].fieldList.append(field); - qDebug("proto = %d, name = %s", protoHandle, name); - break; - } - } -} - -void PacketModel::registerFrameTypeProto() -{ - registerProto(PTYP_L2_NONE, "None", ""); - registerField(PTYP_L2_NONE, "Destination Mac", "dstMac"); - registerField(PTYP_L2_NONE, "Source Mac", "srcMac"); - - registerProto(PTYP_L2_ETH_2, "Ethernet II", "eth"); - registerField(PTYP_L2_ETH_2, "Destination Mac", "dstMac"); - registerField(PTYP_L2_ETH_2, "Source Mac", "srcMac"); - registerField(PTYP_L2_ETH_2, "Ethernet Type", "type"); - - registerProto(PTYP_L2_802_3_RAW, "IEEE 802.3 Raw", "dot3raw"); - registerField(PTYP_L2_802_3_RAW, "Destination Mac", "dstMac"); - registerField(PTYP_L2_802_3_RAW, "Source Mac", "srcMac"); - registerField(PTYP_L2_802_3_RAW, "Length", "len"); - - registerProto(PTYP_L2_802_3_LLC, "802.3 LLC", "dot3llc"); - registerField(PTYP_L2_802_3_LLC, "Destination Service Acces Point", "dsap"); - registerField(PTYP_L2_802_3_LLC, "Source Service Acces Point", "ssap"); - registerField(PTYP_L2_802_3_LLC, "Control", "ctl"); - - registerProto(PTYP_L2_SNAP, "SNAP", "dot3snap"); - registerField(PTYP_L2_SNAP, "Organisationally Unique Identifier", "oui"); - registerField(PTYP_L2_SNAP, "Type", "type"); - -} - -void PacketModel::registerVlanProto() -{ - registerProto(PTYP_SVLAN, "IEEE 802.1ad Service VLAN", "SVLAN"); - - registerField(PTYP_SVLAN, "Tag Protocol Identifier", "tpid"); - registerField(PTYP_SVLAN, "Priority Code Point", "pcp"); - registerField(PTYP_SVLAN, "Drop Eligible", "de"); - registerField(PTYP_SVLAN, "VLAN Identifier", "vlan"); - - registerProto(PTYP_CVLAN, "IEEE 802.1Q VLAN/CVLAN", "VLAN"); - - registerField(PTYP_CVLAN, "Tag Protocol Identifier", "tpid"); - registerField(PTYP_CVLAN, "Priority", "prio"); - registerField(PTYP_CVLAN, "Canonical Format Indicator", "cfi"); - registerField(PTYP_CVLAN, "VLAN Identifier", "vlan"); -} - -void PacketModel::registerIpProto() -{ - registerProto(PTYP_L3_IP, "Internet Protocol version 4", "IPv4"); - - registerField(PTYP_L3_IP, "Version", "ver"); - registerField(PTYP_L3_IP, "Header Length", "hdrlen"); - registerField(PTYP_L3_IP, "Type of Service/DiffServ Code Point", "tos"); - registerField(PTYP_L3_IP, "Total Length", "len"); - registerField(PTYP_L3_IP, "Identification", "id"); - registerField(PTYP_L3_IP, "Flags", "flags"); - registerField(PTYP_L3_IP, "Fragment Offset", "fragofs"); - registerField(PTYP_L3_IP, "Time to Live", "ttl"); - registerField(PTYP_L3_IP, "Protocol Id", "proto"); - registerField(PTYP_L3_IP, "Checksum", "cksum"); - registerField(PTYP_L3_IP, "Source IP", "srcip"); - registerField(PTYP_L3_IP, "Destination IP", "dstip"); -} - -void PacketModel::registerArpProto() -{ - // TODO (LOW) -} - -void PacketModel::registerTcpProto() -{ - registerProto(PTYP_L4_TCP, "Transmission Control Protocol", "TCP"); - - registerField(PTYP_L4_TCP, "Source Port", "srcport"); - registerField(PTYP_L4_TCP, "Destination Port", "dstport"); - registerField(PTYP_L4_TCP, "Sequence Number", "seqnum"); - registerField(PTYP_L4_TCP, "Acknowledgement Number", "acknum"); - registerField(PTYP_L4_TCP, "Header Length", "hdrlen"); - registerField(PTYP_L4_TCP, "Reserved", "rsvd"); - registerField(PTYP_L4_TCP, "Flags", "flags"); - registerField(PTYP_L4_TCP, "Window", "win"); - registerField(PTYP_L4_TCP, "Checksum", "cksum"); - registerField(PTYP_L4_TCP, "Urgent Pointer", "urgptr"); -} - -void PacketModel::registerUdpProto() -{ - registerProto(PTYP_L4_UDP, "User Datagram Protocol", "UDP"); - - registerField(PTYP_L4_UDP, "Source Port", "srcport"); - registerField(PTYP_L4_UDP, "Destination Port", "dstport"); - registerField(PTYP_L4_UDP, "Length", "len"); - registerField(PTYP_L4_UDP, "Checksum", "cksum"); -} - -void PacketModel::registerIcmpProto() -{ - // TODO (LOW) -} - -void PacketModel::registerIgmpProto() -{ - // TODO (LOW) -} - -void PacketModel::registerInvalidProto() -{ - registerProto(PTYP_INVALID, "Invalid Protocol (bug in code)", "invalid"); -} - -void PacketModel::registerData() -{ - registerProto(PTYP_DATA, "Data", "data"); -} - -#endif diff --git a/client/stream.cpp b/client/stream.cpp index 30568e5..653859c 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -1,3 +1,4 @@ +#include #include #include "stream.h" @@ -6,6 +7,72 @@ #define BASE_HEX 16 +QString PayloadProtocol::fieldTextValue(int index) +{ + int len; + quint32 pat; + QString textValue; + + if (parentStream) + { + len = parentStream->frameLen() - parentStream->protocolHeaderSize(); + pat = parentStream->pattern(); + } + else + { + len = 1500; // FIXME(HI): testing only + pat = 0x0a0b0c0d; + } + + // Make a larger string and then resize to the correct size to + // take care of the case where len is not a multiple of pattern size + if (len > 0) + { + // TODO(LOW): allow non-4byte patterns!!! + int w = 4; // data pattern size + + for (int i = 0; i < (len/w + 1); i++) + textValue.append(QString("%1").arg( + pat, w*2, BASE_HEX, QChar('0'))); + textValue.resize(len); + } + + return textValue; +} + +QByteArray PayloadProtocol::fieldRawValue(int index) +{ + int len; + quint32 pat; + QByteArray rawValue; + + if (parentStream) + { + len = parentStream->frameLen() - parentStream->protocolHeaderSize(); + pat = parentStream->pattern(); + } + else + { + len = 1500; // FIXME(HI): testing only + pat = 0x0a0b0c0d; + } + + // Make a larger byteArray and then resize to the correct size to + // take care of the case where len is not a multiple of pattern size + if (len > 0) + { + // TODO(LOW): allow non-4byte patterns!!! + int w = 4; // data pattern size + + rawValue.resize(len + 4); + for (int i = 0; i < (len/w + 1); i++) + qToBigEndian(pat, (uchar*) (rawValue.data() + i*sizeof(pat))); + rawValue.resize(len); + } + + return rawValue; +} + QString MacProtocol::fieldName(int index) { QString name; @@ -53,6 +120,24 @@ QByteArray MacProtocol::fieldRawValue(int index) { QByteArray rawValue; + switch(index) + { + case 0: + rawValue.resize(8); + qToBigEndian(dstMac(), (uchar *) rawValue.data()); + rawValue.remove(0, 2); + qDebug("dstMac(%d): %s", rawValue.size(), rawValue.toHex().constData()); + break; + case 1: + rawValue.resize(8); + qToBigEndian(srcMac(), (uchar *) rawValue.data()); + rawValue.remove(0, 2); + qDebug("srcMac(%d): %s", rawValue.size(), rawValue.toHex().constData()); + break; + default: + break; + } + return rawValue; } @@ -109,6 +194,24 @@ QByteArray LlcProtocol::fieldRawValue(int index) { QByteArray rawValue; + switch(index) + { + case 0: + rawValue.resize(1); + rawValue[0] = dsap(); + break; + case 1: + rawValue.resize(1); + rawValue[0] = ssap(); + break; + case 2: + rawValue.resize(1); + rawValue[0] = ctl(); + break; + default: + break; + } + return rawValue; } @@ -151,6 +254,17 @@ QByteArray SnapProtocol::fieldRawValue(int index) { QByteArray rawValue; + switch(index) + { + case 0: + rawValue.resize(4); + qToBigEndian(oui(), (uchar *) rawValue.data()); + rawValue.remove(0, 1); + break; + default: + break; + } + return rawValue; } @@ -191,9 +305,58 @@ QByteArray Eth2Protocol::fieldRawValue(int index) { QByteArray rawValue; + switch(index) + { + case 0: + rawValue.resize(2); + qToBigEndian(type(), (uchar*) rawValue.data()); + break; + default: + break; + } + return rawValue; } +QString Dot3Protocol::fieldName(int index) +{ + QString name; + + switch(index) + { + case 0: + name = QString("Length"); + break; + default: + name = QString(); + break; + } + return name; +} + +QString Dot3Protocol::fieldTextValue(int index) +{ + if (parentStream) + return QString("%1").arg(parentStream->frameLen()); + else + return QString("00"); +} + +QByteArray Dot3Protocol::fieldRawValue(int index) +{ + QByteArray ba; + + if (parentStream) + qToBigEndian((quint16) parentStream->frameLen(), (uchar*) ba.data()); + else + { + ba.resize(2); + ba[0] = ba[1] = 0; + } + + return ba; +} + int VlanProtocol::numFields() { if (isSingleTagged()) @@ -323,6 +486,56 @@ QByteArray VlanProtocol::fieldRawValue(int index) { QByteArray rawValue; + if (isDoubleTagged()) + { + switch(index) + { + case 0: + rawValue.resize(2); + qToBigEndian(stpid(), (uchar*) rawValue.data()); + break; + case 1: + rawValue.resize(2); + qToBigEndian((svlanPrio() << 13) | (svlanCfi() < 12) | svlanId(), + (uchar*) rawValue.data()); + break; + case 2: + // Combined with prio above + break; + case 3: + // Combined with prio above + break; + default: + index -= 4; + goto _single_tag; + } + + goto _exit; + } + +_single_tag: + switch(index) + { + case 0: + rawValue.resize(2); + qToBigEndian(ctpid(), (uchar*) rawValue.data()); + break; + case 1: + rawValue.resize(2); + qToBigEndian((cvlanPrio() << 13) | (cvlanCfi() < 12) | cvlanId(), + (uchar*) rawValue.data()); + break; + case 2: + // Combined with prio above + break; + case 3: + // Combined with prio above + break; + default: + break; + } + +_exit: return rawValue; } @@ -438,6 +651,60 @@ QByteArray IpProtocol::fieldRawValue(int index) { QByteArray rawValue; + switch(index) + { + case 0: + rawValue.resize(1); + //qToBigEndian((ver() << 4) | hdrLen(), (uchar*) rawValue.data()); + rawValue[0]=(ver() << 4) | hdrLen(); + break; + case 1: + // Combined with previous 4 bits of ver!! + break; + case 2: + rawValue.resize(1); + qToBigEndian(tos(), (uchar*) rawValue.data()); + break; + case 3: + rawValue.resize(2); + qToBigEndian(totLen(), (uchar*) rawValue.data()); + break; + case 4: + rawValue.resize(2); + qToBigEndian(id(), (uchar*) rawValue.data()); + break; + case 5: + rawValue.resize(2); + qToBigEndian((quint16)((flags() << 13) | fragOfs()), + (uchar*) rawValue.data()); + break; + case 6: + // Combined with previous 3 bits of flags!! + break; + case 7: + rawValue.resize(1); + qToBigEndian(ttl(), (uchar*) rawValue.data()); + break; + case 8: + rawValue.resize(1); + qToBigEndian(proto(), (uchar*) rawValue.data()); + break; + case 9: + rawValue.resize(2); + qToBigEndian(cksum(), (uchar*) rawValue.data()); + break; + case 10: + rawValue.resize(4); + qToBigEndian(srcIp(), (uchar*) rawValue.data()); + break; + case 11: + rawValue.resize(4); + qToBigEndian(dstIp(), (uchar*) rawValue.data()); + break; + default: + break; + } + return rawValue; } @@ -520,7 +787,7 @@ QString TcpProtocol::fieldTextValue(int index) break; case 7: textValue = QString("%1"). - arg(flags()); + arg(window(), 2, BASE_HEX, QChar('0')); break; case 8: textValue = QString("0x%1"). @@ -541,6 +808,51 @@ QByteArray TcpProtocol::fieldRawValue(int index) { QByteArray rawValue; + switch(index) + { + case 0: + rawValue.resize(2); + qToBigEndian(srcPort(), (uchar*) rawValue.data()); + break; + case 1: + rawValue.resize(2); + qToBigEndian(dstPort(), (uchar*) rawValue.data()); + break; + case 2: + rawValue.resize(4); + qToBigEndian(seqNum(), (uchar*) rawValue.data()); + break; + case 3: + rawValue.resize(4); + qToBigEndian(ackNum(), (uchar*) rawValue.data()); + break; + case 4: + rawValue.resize(1); + rawValue[0] = (hdrLen() << 4) | rsvd(); + break; + case 5: + // Combined with hdrLen above + break; + case 6: + rawValue.resize(1); + rawValue[0] = flags(); + break; + case 7: + rawValue.resize(2); + qToBigEndian(window(), (uchar*) rawValue.data()); + break; + case 8: + rawValue.resize(2); + qToBigEndian(cksum(), (uchar*) rawValue.data()); + break; + case 9: + rawValue.resize(2); + qToBigEndian(urgPtr(), (uchar*) rawValue.data()); + break; + default: + break; + } + return rawValue; } @@ -602,6 +914,28 @@ QByteArray UdpProtocol::fieldRawValue(int index) { QByteArray rawValue; + switch(index) + { + case 0: + rawValue.resize(2); + qToBigEndian(srcPort(), (uchar*) rawValue.data()); + break; + case 1: + rawValue.resize(2); + qToBigEndian(dstPort(), (uchar*) rawValue.data()); + break; + case 2: + rawValue.resize(2); + qToBigEndian(totLen(), (uchar*) rawValue.data()); + break; + case 3: + rawValue.resize(2); + qToBigEndian(cksum(), (uchar*) rawValue.data()); + break; + default: + break; + } + return rawValue; } @@ -622,12 +956,14 @@ Stream::Stream() // mCore->set_stream_id(mId); mUnknown = new UnknownProtocol; + mPayload = new PayloadProtocol(); //FIXME(MED): need to pass parent stream mMac = new MacProtocol; mLlc = new LlcProtocol; mSnap = new SnapProtocol; mEth2 = new Eth2Protocol; + mDot3 = new Dot3Protocol(); // FIXME(MED): need to pass parent stream mVlan = new VlanProtocol; mIp = new IpProtocol; @@ -776,9 +1112,23 @@ void Stream::updateSelectedProtocols() selectedProtocols.append(proto); _data: + + mProtocolHeaderSize = 0; +#ifndef SRIVATSP +#if 0 + for (int i = 0; i < selectedProtocols.size(); i++) + mProtocolHeaderSize += protocol(i)->protocolRawValue().size(); +#endif +#endif selectedProtocols.append(PTYP_DATA); } +int Stream::protocolHeaderSize() +{ + updateSelectedProtocols(); // FIXME(HI): shd not happen everytime + return mProtocolHeaderSize; +} + int Stream::numProtocols() { updateSelectedProtocols(); // FIXME(HI): shd not happen everytime @@ -815,7 +1165,7 @@ AbstractProtocol* Stream::protocol(int index) case PTYP_L2_ETH_2: return eth2(); case PTYP_L2_802_3_RAW: - return eth2(); // FIXME(HI): define a dot3 protocol? + return dot3(); case PTYP_L2_802_3_LLC: return llc(); @@ -843,7 +1193,7 @@ AbstractProtocol* Stream::protocol(int index) case PTYP_INVALID: return mUnknown; case PTYP_DATA: - return mUnknown; // FIXME(MED) define a "data" protocol? + return mPayload; default: return mUnknown; } diff --git a/client/stream.h b/client/stream.h index 0bb35cd..9500064 100644 --- a/client/stream.h +++ b/client/stream.h @@ -2,6 +2,7 @@ #define _STREAM_H #include + #include #include #include "../common/protocol.pb.h" @@ -17,6 +18,8 @@ class PacketModel; #define IP_PROTO_UDP 0x11 +class Stream; + class AbstractProtocol { // TODO(LOW) @@ -36,6 +39,16 @@ public: { return QString("AbsProto"); } virtual int numFields() { return 1; } + QByteArray protocolRawValue() + { + QByteArray ba; +#ifndef SRIVATSP +#else + for (int i=0; i < numFields(); i++) + ba.append(fieldRawValue(i)); +#endif + return ba; + } virtual QString fieldName(int index) { return QString("AbstractField"); } virtual QString fieldTextValue(int index) @@ -64,7 +77,31 @@ public: QString fieldTextValue(int index) { return QString("UnknownFieldValue"); } QByteArray fieldRawValue(int index) - { return QByteArray(4, '\0'); } + { return QByteArray(); } +}; + +class PayloadProtocol: public AbstractProtocol +{ + Stream *parentStream; + OstProto::Ack d; // FIXME(HI): move payload related vars from + // stream into here + +public: + PayloadProtocol (Stream *stream = NULL) { parentStream = stream; } + virtual ~PayloadProtocol() {} + + virtual ::google::protobuf::Message& data() { return d; } + + virtual QString protocolName() + { return QString("Payload Data"); } + QString protocolShortName() + { return QString("DATA"); } + int numFields() + { return 1; } + QString fieldName(int index) + { return QString("Data"); } + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); }; class MacProtocol : public AbstractProtocol @@ -238,6 +275,37 @@ public: QByteArray fieldRawValue(int index); }; + +class Dot3Protocol : public AbstractProtocol +{ +private: + Stream *parentStream; + OstProto::Ack d; // FIXME(HI): replace 'ack' with somehting else + +public: + Dot3Protocol(Stream *stream = NULL) + { parentStream = stream; qDebug("parentStream = %p", stream); } + virtual ~Dot3Protocol() {} + virtual ::google::protobuf::Message& data() {return d;} + +#if 0 // FIXME(HI): remove? + quint16 length() + { return d.length(); } + bool setLength(quint16 length) + { return true; } +#endif + + virtual QString protocolName() + { return QString("802.3 Length"); } + QString protocolShortName() + { return QString("LEN"); } + int numFields() + { return 1; } + QString fieldName(int index); + QString fieldTextValue(int index); + QByteArray fieldRawValue(int index); +}; + class VlanProtocol : public AbstractProtocol { OstProto::Vlan d; @@ -765,11 +833,14 @@ class Stream { OstProto::StreamCore *mCore; UnknownProtocol *mUnknown; + PayloadProtocol *mPayload; MacProtocol *mMac; LlcProtocol *mLlc; SnapProtocol *mSnap; Eth2Protocol *mEth2; + Dot3Protocol *mDot3; + VlanProtocol *mVlan; IpProtocol *mIp; @@ -781,11 +852,15 @@ class Stream { IgmpProtocol *mIgmp; public: + //PayloadProtocol* Payload() { return mPayload; } MacProtocol* mac() { return mMac; } + void* core() { return mCore; } // FIXME(HI): Debug ONLY + LlcProtocol* llc() { return mLlc; } SnapProtocol* snap() { return mSnap; } Eth2Protocol* eth2() { return mEth2; } + Dot3Protocol* dot3() { return mDot3; } VlanProtocol* vlan() { return mVlan; } IpProtocol* ip() { return mIp; } @@ -954,15 +1029,19 @@ public: //--------------------------------------------------------------- // Methods for use by Packet Model //--------------------------------------------------------------- - QList selectedProtocols; int numProtocols(); + + //! Includes ALL protocol headers excluding payload data + int protocolHeaderSize(); #if 0 int protocolId(int index); int protocolIndex(int id); #endif AbstractProtocol* protocol(int index); private: + QList selectedProtocols; + int mProtocolHeaderSize; void updateSelectedProtocols(); }; diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index a881dce..0202825 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -16,13 +16,13 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, //mpStreamList = streamList; mCurrentStreamIndex = streamIndex; LoadCurrentStream(); - mpPacketModel = new PacketModel(&mPort.streamByIndex(mCurrentStreamIndex), this); tvPacketTree->setModel(mpPacketModel); mpPacketModelTester = new ModelTest(mpPacketModel); tvPacketTree->header()->hide(); - + vwPacketDump->setModel(mpPacketModel); + vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); // FIXME(MED): Enable this navigation pbPrev->setDisabled(true); @@ -625,6 +625,11 @@ void StreamConfigDialog::StoreCurrentStream() { pStream->mac()->setDstMac( leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); +#if 1 + qDebug("%s: dstMac = %llx [%s] %d", __FUNCTION__, + pStream->mac()->dstMac(), + leDstMac->text().toAscii().constData(), isOk); +#endif pStream->mac()->setDstMacMode( (MacProtocol::MacAddrMode) cmbDstMacMode->currentIndex()); pStream->mac()->setDstMacCount( @@ -634,6 +639,9 @@ void StreamConfigDialog::StoreCurrentStream() pStream->mac()->setSrcMac( leSrcMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); + qDebug("%s: srcMac = %llx [%s] %d", __FUNCTION__, + pStream->mac()->srcMac(), + leSrcMac->text().toAscii().constData(), isOk); pStream->mac()->setSrcMacMode( (MacProtocol::MacAddrMode) cmbSrcMacMode->currentIndex()); pStream->mac()->setSrcMacCount( diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index b568d52..503eb27 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -33,7 +33,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 0 + 2 @@ -2036,6 +2036,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff QAbstractItemView::SelectItems + + true + diff --git a/common/protocol.proto b/common/protocol.proto index e620b2d..9cb835f 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -190,8 +190,8 @@ message StreamCore { optional uint32 data_start_ofs = 13; // Frame Length (includes CRC) - optional FrameLengthMode len_mode = 14; - optional uint32 frame_len = 15; + optional FrameLengthMode len_mode = 14 [default = e_fl_fixed]; + optional uint32 frame_len = 15 [default = 64]; optional uint32 frame_len_min = 16; optional uint32 frame_len_max = 17; From 4cf80d4ee413dceebb28c8424b17a59012b614b0 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 14 Sep 2008 12:03:53 +0000 Subject: [PATCH 09/98] Demo code for stats being checked in --- client/port.cpp | 10 +- client/port.h | 10 +- client/portgroup.cpp | 78 +++++++ client/portgroup.h | 10 + client/portgrouplist.cpp | 3 + client/portgrouplist.h | 4 + client/portstatsmodel.cpp | 117 ++++++++-- client/portstatsmodel.h | 19 +- client/portstatswindow.cpp | 53 ++++- client/portstatswindow.h | 14 +- common/protocol.proto | 18 +- server/drone.pro | 2 +- server/myservice.cpp | 435 ++++++++++++++++++++++++++++++++++--- server/myservice.h | 59 ++++- 14 files changed, 747 insertions(+), 85 deletions(-) diff --git a/client/port.cpp b/client/port.cpp index 89d94c3..06f40ae 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -16,6 +16,7 @@ Port::Port(quint32 id, quint32 portGroupId) { mPortId = id; d.mutable_port_id()->set_id(id); + stats.mutable_port_id()->set_id(id); mPortGroupId = portGroupId; } @@ -166,10 +167,6 @@ void Port::getModifiedStreamsSinceLastSync( } } - -// -// ----------- SLOTS ------------- -// void Port::when_syncComplete() { qSort(mStreams); @@ -179,3 +176,8 @@ void Port::when_syncComplete() mLastSyncStreamList.append(mStreams[i].id()); } +void Port::updateStats(OstProto::PortStats *portStats) +{ + stats.MergeFrom(*portStats); +} + diff --git a/client/port.h b/client/port.h index f96d31c..b16d680 100644 --- a/client/port.h +++ b/client/port.h @@ -13,8 +13,9 @@ class Port { //friend class StreamModel; private: - static uint mAllocStreamId; - OstProto::Port d; + static uint mAllocStreamId; + OstProto::Port d; + OstProto::PortStats stats; // FIXME(HI): consider removing mPortId as it is duplicated inside 'd' quint32 mPortId; @@ -68,6 +69,7 @@ public: Q_ASSERT(index < mStreams.size()); return mStreams[index]; } + OstProto::PortStats getStats() { return stats; } // FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal void updatePortConfig(OstProto::Port *port); @@ -89,7 +91,11 @@ public: void getModifiedStreamsSinceLastSync( OstProto::StreamConfigList &streamConfigList); + void when_syncComplete(); + + void updateStats(OstProto::PortStats *portStats); + }; #endif diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 3de90cc..70cb66e 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -413,3 +413,81 @@ void PortGroup::processModifyStreamAck(OstProto::Ack *ack) // TODO(HI): Apply Button should now be disabled???!!!!??? } + +void PortGroup::startTx(QList portList) +{ + OstProto::PortIdList portIdList; + OstProto::Ack *ack = new OstProto::Ack; + + qDebug("In %s", __FUNCTION__); + + for (int i = 0; i < portList.size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList.at(i)); + } + + serviceStub->startTx(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStartTxAck, ack)); +} + +void PortGroup::processStartTxAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + delete ack; +} + +void PortGroup::getPortStats() +{ + OstProto::PortStatsList *portStatsList = new OstProto::PortStatsList; + + qDebug("In %s", __FUNCTION__); + + serviceStub->getStats(rpcController, &portIdList, portStatsList, + NewCallback(this, &PortGroup::processPortStatsList, portStatsList)); +} + +void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList) +{ + qDebug("In %s", __FUNCTION__); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } + + for(int i = 0; i < portStatsList->port_stats_size(); i++) + { + uint id; + + id = portStatsList->port_stats(i).port_id().id(); + // FIXME: don't mix port id & index into mPorts[] + mPorts[id].updateStats(portStatsList->mutable_port_stats(i)); + } + + emit statsChanged(mPortGroupId); + +_error_exit: + delete portStatsList; +} + +void PortGroup::clearPortStats() +{ + OstProto::Ack *ack = new OstProto::Ack; + + qDebug("In %s", __FUNCTION__); + + serviceStub->clearStats(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processClearStatsAck, ack)); +} + +void PortGroup::processClearStatsAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + delete ack; +} + diff --git a/client/portgroup.h b/client/portgroup.h index 89c02af..e2b5317 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -69,10 +69,20 @@ public: OstProto::StreamConfigList *streamConfigList = NULL); void processModifyStreamAck(OstProto::Ack *ack); + + void startTx(QList portList); + void processStartTxAck(OstProto::Ack *ack); + + void getPortStats(); + void processPortStatsList(OstProto::PortStatsList *portStatsList); + void clearPortStats(); + void processClearStatsAck(OstProto::Ack *ack); + signals: void portGroupDataChanged(PortGroup* portGroup); void portListAboutToBeChanged(quint32 portGroupId); void portListChanged(quint32 portGroupId); + void statsChanged(quint32 portGroupId); private slots: void on_rpcChannel_stateChanged(); diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index 06df02d..a503449 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -74,6 +74,9 @@ void PortGroupList::addPortGroup(PortGroup &portGroup) connect(&portGroup, SIGNAL(portListChanged(quint32)), &mPortStatsModel, SLOT(when_portListChanged())); + connect(&portGroup, SIGNAL(statsChanged(quint32)), + &mPortStatsModel, SLOT(when_portGroup_stats_update(quint32))); + mPortGroups.append(&portGroup); portGroup.connectToHost(); diff --git a/client/portgrouplist.h b/client/portgrouplist.h index 84bdb9c..aadd24d 100644 --- a/client/portgrouplist.h +++ b/client/portgrouplist.h @@ -28,6 +28,7 @@ class PortGroupList : public QObject { public: PortGroupList::PortGroupList(); + PortModel* getPortModel() { return &mPortGroupListModel; } PortStatsModel* getPortStatsModel() { return &mPortStatsModel; } StreamModel* getStreamModel() { return &mStreamListModel; } @@ -37,6 +38,9 @@ public: PortGroup& portGroup(const QModelIndex& index); Port& port(const QModelIndex& index); + int numPortGroups() { return mPortGroups.size(); } + PortGroup& portGroupByIndex(int index) { return *(mPortGroups[index]); } + void addPortGroup(PortGroup &portGroup); void removePortGroup(PortGroup &portGroup); diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 5da586b..d8b40e6 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -1,10 +1,18 @@ #include "portstatsmodel.h" #include "portgrouplist.h" +#include + PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent) : QAbstractTableModel(parent) { + QTimer *timer; + pgl = p; + + timer = new QTimer(); + connect(timer, SIGNAL(timeout()), this, SLOT(updateStats())); + timer->start(5000); } int PortStatsModel::rowCount(const QModelIndex &parent) const @@ -32,9 +40,33 @@ int PortStatsModel::columnCount(const QModelIndex &parent ) const return numPorts.last(); } +void PortStatsModel::getDomainIndexes(const QModelIndex &index, + uint &portGroupIdx, uint &portIdx) const +{ + int portNum; + + // TODO(LOW): Optimize using binary search: see qLowerBound() + portNum = index.column() + 1; + for (portGroupIdx = 0; portGroupIdx < (uint) numPorts.size(); portGroupIdx++) + if (portNum <= numPorts.at(portGroupIdx)) + break; + + if (portGroupIdx) + { + if (numPorts.at(portGroupIdx -1)) + portIdx = (portNum - 1) % numPorts.at(portGroupIdx - 1); + else + portIdx = portNum - 1; + } + else + portIdx = portNum - 1; + + //qDebug("PSM: %d - %d, %d", index.column(), portGroupIdx, portIdx); +} + QVariant PortStatsModel::data(const QModelIndex &index, int role) const { - int pgidx, pidx, portNum; + uint pgidx, pidx; // Check for a valid index if (!index.isValid()) @@ -50,31 +82,44 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const if (index.column() >= (numPorts.last())) return QVariant(); - // TODO(LOW): Optimize using binary search: see qLowerBound() - portNum = index.column() + 1; - for (pgidx = 0; pgidx < numPorts.size(); pgidx++) - if (portNum <= numPorts.at(pgidx)) - break; - - if (pgidx) - { - if (numPorts.at(pgidx -1)) - pidx = (portNum - 1) % numPorts.at(pgidx - 1); - else - pidx = portNum - 1; - } - else - pidx = portNum - 1; - - //qDebug("PSM: %d - %d, %d", index.column(), pgidx, pidx); + getDomainIndexes(index, pgidx, pidx); // Check role if (role == Qt::DisplayRole) { -#if 0 // PB - return pgl->mPortGroups.at(pgidx)->mPorts.at(pidx).mPortStats[index.row()]; -#endif - return 0; //FIXME: Get actual port stats + OstProto::PortStats stats; + + stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx].getStats(); + + switch(index.row()) + { + case e_STAT_FRAMES_RCVD: + return stats.rx_pkts(); + + case e_STAT_FRAMES_SENT: + return stats.tx_pkts(); + + case e_STAT_FRAME_SEND_RATE: + return stats.tx_pps(); + + case e_STAT_FRAME_RECV_RATE: + return stats.rx_pps(); + + case e_STAT_BYTES_RCVD: + return stats.rx_bytes(); + + case e_STAT_BYTES_SENT: + return stats.tx_bytes(); + + case e_STAT_BYTE_SEND_RATE: + return stats.tx_bps(); + + case e_STAT_BYTE_RECV_RATE: + return stats.rx_bps(); + + default: + return 0; + } } else return QVariant(); @@ -92,6 +137,22 @@ QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, in return PortStatName.at(section); } +void PortStatsModel::portListFromIndex(QModelIndexList indices, + QList &portList) +{ + portList.clear(); + + for (int i = 0; i < indices.size(); i++) + { + //getDomainIndexes(indices.at(i), portGroupIdx, portIdx); + + for (int j = 0; j < portList.size(); j++) + { + // FIXME(HI): Incomplete!!!! + } + } +} + // // Slots // @@ -121,4 +182,16 @@ void PortStatsModel::on_portStatsUpdate(int port, void*stats) emit dataChanged(topLeft, bottomRight); } +void PortStatsModel::updateStats() +{ + // Request each portgroup to fetch updated stats - the port group + // raises a signal once updated stats are available + for (int i = 0; i < pgl->mPortGroups.size(); i++) + pgl->mPortGroups[i]->getPortStats(); +} +void PortStatsModel::when_portGroup_stats_update(quint32 portGroupId) +{ + // FIXME(MED): update only the changed ports, not all + reset(); +} diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h index 6bf5c5a..6dc4693 100644 --- a/client/portstatsmodel.h +++ b/client/portstatsmodel.h @@ -33,9 +33,8 @@ class PortStatsModel : public QAbstractTableModel { Q_OBJECT - PortGroupList *pgl; - public: + PortStatsModel(PortGroupList *p, QObject *parent = 0); int rowCount(const QModelIndex &parent = QModelIndex()) const; @@ -44,16 +43,32 @@ class PortStatsModel : public QAbstractTableModel QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + class PortGroupAndPortList { + uint portGroupId; + QList portList; + }; + void portListFromIndex(QModelIndexList indices, + QList &portList); + public slots: void when_portListChanged(); void on_portStatsUpdate(int port, void*stats); + void when_portGroup_stats_update(quint32 portGroupId); + + private slots: + void updateStats(); private: + PortGroupList *pgl; + // numPorts stores the num of ports per portgroup // in the same order as the portgroups are index in the pgl // Also it stores them as cumulative totals QList numPorts; + void getDomainIndexes(const QModelIndex &index, + uint &portGroupIdx, uint &portIdx) const; + }; #endif diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index 1339ebb..28b8f88 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -5,20 +5,71 @@ #include "QHeaderView" -//PortStatsWindow::PortStatsWindow(QWidget *parent) : QDialog (parent) PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent) + : QWidget(parent) { setupUi(this); + this->pgl = pgl; model = pgl->getPortStatsModel(); tvPortStats->setModel(model); tvPortStats->horizontalHeader()->setMovable(true); + tvPortStats->verticalHeader()->resizeSections(QHeaderView::ResizeToContents); } PortStatsWindow::~PortStatsWindow() { } +/* ------------- SLOTS -------------- */ + +void PortStatsWindow::on_tbStartTransmit_clicked() +{ + // TODO(MED): get selected ports + + if (pgl->numPortGroups()) + { + QList portIdList; + + // FIXME(HI): Testing only!!! + portIdList.append(1); // MS Loopback adapter + pgl->portGroupByIndex(0).startTx(portIdList); + } +} + +void PortStatsWindow::on_tbStopTransmit_clicked() +{ + // TODO(MED) +} + +void PortStatsWindow::on_tbStartCapture_clicked() +{ + // TODO(MED) +} + +void PortStatsWindow::on_tbStopCapture_clicked() +{ + // TODO(MED) +} + +void PortStatsWindow::on_tbViewCapture_clicked() +{ + // TODO(MED) +} + +void PortStatsWindow::on_tbClear_clicked() +{ + // TODO(MED) +} + +void PortStatsWindow::on_tbClearAll_clicked() +{ + for (int i = 0; i < pgl->numPortGroups(); i++) + { + pgl->portGroupByIndex(0).clearPortStats(); + } +} + void PortStatsWindow::on_tbFilter_clicked() { bool ok; diff --git a/client/portstatswindow.h b/client/portstatswindow.h index e5a1a97..98642c1 100644 --- a/client/portstatswindow.h +++ b/client/portstatswindow.h @@ -6,17 +6,29 @@ #include "ui_portstatswindow.h" #include "portgrouplist.h" -class PortStatsWindow : public QDialog, public Ui::PortStatsWindow +class PortStatsWindow : public QWidget, public Ui::PortStatsWindow { Q_OBJECT public: PortStatsWindow(PortGroupList *pgl, QWidget *parent = 0); ~PortStatsWindow(); + private: + PortGroupList *pgl; QAbstractItemModel *model; private slots: + void on_tbStartTransmit_clicked(); + void on_tbStopTransmit_clicked(); + + void on_tbStartCapture_clicked(); + void on_tbStopCapture_clicked(); + void on_tbViewCapture_clicked(); + + void on_tbClear_clicked(); + void on_tbClearAll_clicked(); + void on_tbFilter_clicked(); }; diff --git a/common/protocol.proto b/common/protocol.proto index 9cb835f..7ffd54f 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -34,7 +34,7 @@ message Llc { message Snap { optional uint32 oui = 1; - optional uint32 type = 2; + //optional uint32 type = 2; } message Eth2 { @@ -126,7 +126,7 @@ message Udp { optional uint32 src_port = 3 [default = 8902]; optional uint32 dst_port = 4 [default = 80]; - optional uint32 totLen = 5; + optional uint32 totlen = 5; optional uint32 cksum = 6; } @@ -279,11 +279,21 @@ message CaptureBufferList { } message PortStats { - // TODO + required PortId port_id = 1; + + optional uint64 rx_pkts = 11; + optional uint64 rx_bytes = 12; + optional uint64 rx_pps = 13; + optional uint64 rx_bps = 14; + + optional uint64 tx_pkts = 21; + optional uint64 tx_bytes = 22; + optional uint64 tx_pps = 23; + optional uint64 tx_bps = 24; } message PortStatsList { - repeated PortStats list = 1; + repeated PortStats port_stats = 1; } service OstService { diff --git a/server/drone.pro b/server/drone.pro index df79396..79cbd1a 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -1,7 +1,7 @@ TEMPLATE = app CONFIG += qt QT += network -DEFINES += HAVE_REMOTE +DEFINES += HAVE_REMOTE WPCAP INCLUDEPATH += "c:\msys\1.0\local\include" INCLUDEPATH += "C:\DevelLibs\WpdPack\Include" INCLUDEPATH += "..\rpc" diff --git a/server/myservice.cpp b/server/myservice.cpp index de438e1..79db27b 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -1,7 +1,311 @@ #include "myservice.h" #include "qdebug.h" -#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} +#include + +#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} +#define MB (1024*1024) + +int StreamInfo::makePacket(uchar *buf, int bufMaxSize) +{ + int pktLen, len = 0; + uchar scratch[8]; + + // TODO(HI): use FrameLengthMode - don't assume fixed + pktLen = d.core().frame_len(); + if (bufMaxSize < pktLen) + return 0; + + // We always have a Mac Header! + // TODO(HI): use MacMode - don't assume fixed + qToBigEndian((quint64) d.mac().dst_mac(), scratch); + memcpy((buf + len), scratch + 2, 6); + len += 6; + qToBigEndian((quint64) d.mac().src_mac(), scratch); + memcpy((buf + len), &scratch + 2, 6); + len += 6; + + switch(d.core().ft()) + { + case OstProto::StreamCore::e_ft_none: + break; + case OstProto::StreamCore::e_ft_eth_2: + qToBigEndian((quint16) d.eth2().type(), buf+len); + len += 2; + break; + case OstProto::StreamCore::e_ft_802_3_raw: + qToBigEndian((quint16) pktLen, buf+len); + len += 2; + break; + case OstProto::StreamCore::e_ft_802_3_llc: + buf[len+0] = (quint8) d.llc().dsap(); + buf[len+1] = (quint8) d.llc().ssap(); + buf[len+2] = (quint8) d.llc().ctl(); + len +=3; + break; + case OstProto::StreamCore::e_ft_snap: + buf[len+0] = (quint8) d.llc().dsap(); + buf[len+1] = (quint8) d.llc().ssap(); + buf[len+2] = (quint8) d.llc().ctl(); + len +=3; + qToBigEndian((quint32) d.snap().oui(), scratch); + memcpy((buf + len), scratch + 2, 3); + len += 3; + qToBigEndian((quint16) d.eth2().type(), buf+len); + len += 2; + break; + default: + qWarning("Unhandled frame type %d\n", d.core().ft()); + } + + switch (d.core().l3_proto()) + { + case OstProto::StreamCore::e_l3_none: + break; + case OstProto::StreamCore::e_l3_ip: + buf[len+0] = (quint8) (d.ip().ver_hdrlen()); + buf[len+1] = (quint8) (d.ip().tos()); + len += 2; + qToBigEndian((quint16) d.ip().tot_len(), buf+len); + len += 2; + qToBigEndian((quint16) d.ip().id(), buf+len); + len += 2; + qToBigEndian((quint16) (( (d.ip().flags() & 0x3) << 13) | + (d.ip().frag_ofs() & 0x1FFF)), buf+len); + len += 2; + buf[len+0] = (quint8) (d.ip().ttl()); + buf[len+1] = (quint8) (d.ip().proto()); + len += 2; + qToBigEndian((quint16) d.ip().cksum(), buf+len); + len += 2; + // TODO(HI): Use IpMode - don't assume fixed + qToBigEndian((quint32) d.ip().src_ip(), buf+len); + len +=4; + qToBigEndian((quint32) d.ip().dst_ip(), buf+len); + len +=4; + break; + case OstProto::StreamCore::e_l3_arp: + // TODO(LOW) + break; + default: + qWarning("Unhandled l3 proto %d\n", d.core().l3_proto()); + } + + switch (d.core().l4_proto()) + { + case OstProto::StreamCore::e_l4_none: + break; + case OstProto::StreamCore::e_l4_tcp: + qToBigEndian((quint16) d.tcp().src_port(), buf+len); + len += 2; + qToBigEndian((quint16) d.tcp().dst_port(), buf+len); + len += 2; + qToBigEndian((quint16) d.tcp().seq_num(), buf+len); + len += 2; + qToBigEndian((quint16) d.tcp().ack_num(), buf+len); + len += 2; + buf[len+0] = (quint8) d.tcp().hdrlen_rsvd(); + buf[len+1] = (quint8) d.tcp().flags(); + len += 2; + qToBigEndian((quint16) d.tcp().window(), buf+len); + len +=2; + qToBigEndian((quint16) d.tcp().cksum(), buf+len); + len +=2; + qToBigEndian((quint16) d.tcp().urg_ptr(), buf+len); + len +=2; + break; + case OstProto::StreamCore::e_l4_udp: + qToBigEndian((quint16) d.udp().src_port(), buf+len); + len += 2; + qToBigEndian((quint16) d.udp().dst_port(), buf+len); + len += 2; + qToBigEndian((quint16) d.udp().totlen(), buf+len); + len +=2; + qToBigEndian((quint16) d.udp().cksum(), buf+len); + len +=2; + break; + case OstProto::StreamCore::e_l4_icmp: + // TODO(LOW) + break; + case OstProto::StreamCore::e_l4_igmp: + // TODO(LOW) + break; + default: + qWarning("Unhandled l4 proto %d\n", d.core().l4_proto()); + } + + // Fill-in the data pattern + { + int dataLen; + + dataLen = pktLen - len; + for (int i = 0; i < (dataLen/4)+1; i++) + { + // TODO(HI): Use patternMode + qToBigEndian((quint32) d.core().pattern(), buf+len+(i*4)); + } + } + + return pktLen; +} + +// +// ------------------ PortInfo -------------------- +// +PortInfo::PortInfo(uint id, pcap_if_t *dev) + : monitor(this) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + + this->dev = dev; + devHandle = pcap_open(dev->name, 65536, PCAP_OPENFLAG_PROMISCUOUS , 1000, + NULL, errbuf); + if (devHandle == NULL) + { + qDebug("Error opening port %s: %s\n", + dev->name, pcap_geterr(devHandle)); + } + + /* By default, put the interface in statistics mode */ + if (pcap_setmode(devHandle, MODE_STAT)<0) + { + qDebug("Error setting statistics mode.\n"); + } + + d.mutable_port_id()->set_id(id); + d.set_name("eth"); // FIXME(MED): suffix portid + d.set_description(dev->description); + d.set_is_enabled(true); // FIXME(MED):check + d.set_is_oper_up(true); // FIXME(MED):check + d.set_is_exclusive_control(false); // FIXME(MED): check + + resetStats(); + + // We'll create sendqueue later when required + sendQueue = NULL; + isSendQueueDirty=true; + + // Start the monitor thread + monitor.start(); +} + +void PortInfo::update() +{ + uchar pktBuf[2000]; + pcap_pkthdr pktHdr; + + qDebug("In %s", __FUNCTION__); + + if (sendQueue) + pcap_sendqueue_destroy(sendQueue); + + // TODO(LOW): calculate sendqueue size + sendQueue = pcap_sendqueue_alloc(1*MB); + + for (int i = 0; i < streamList.size(); i++) + { + // FIXME(HI): Testing only + //if (streamList[i].d.core().is_enabled()) + { + pktHdr.len = streamList[i].makePacket(pktBuf, sizeof(pktBuf)); + pktHdr.caplen = pktHdr.len; + pktHdr.ts.tv_sec = pktHdr.ts.tv_usec = 0; // FIXME(HI) + + if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr, + (u_char*) pktBuf)) + { + qDebug("[port %d] sendqueue_queue() failed for streamidx %d\n", + id(), i); + } + } + } + + isSendQueueDirty = false; +} + +void PortInfo::startTransmit() +{ + int n; + + // TODO(HI): Stream Mode - one pass/continuous + n = pcap_sendqueue_transmit(devHandle, sendQueue, false); + if (n == 0) + qDebug("port %d: send error %s\n", id(), pcap_geterr(devHandle)); + else + qDebug("port %d: sent %d bytes\n", id(), n); +} + +void PortInfo::stopTransmit() +{ +} + +void PortInfo::resetStats() +{ + memset((void*) &stats, 0, sizeof(stats)); +} + +// +// ------------------ PortMonitor ------------------- +// + +PortInfo::PortMonitor::PortMonitor(PortInfo *port) +{ + this->port = port; +} + +void PortInfo::PortMonitor::callback(u_char *state, + const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + PortInfo *port = (PortInfo*) state; + quint64 pkts; + quint64 bytes; + + pkts = *((quint64*)(pkt_data + 0)); + bytes = *((quint64*)(pkt_data + 8)); + + port->stats.rxPkts += pkts; + port->stats.rxBytes += bytes; + +#if 0 + for (int i=0; i < 16; i++) + { + qDebug("%02x ", pkt_data[i]); + } + qDebug("{%d: %llu, %llu}\n", port->id(), + pkts, bytes); + qDebug("[%d: pkts : %llu]\n", port->id(), port->stats.rxPkts); + qDebug("[%d: bytes: %llu]\n", port->id(), port->stats.rxBytes); +#endif +} + +void PortInfo::PortMonitor::run() +{ + int ret; + + qDebug("before pcap_loop\n"); + + /* Start the main loop */ + ret = pcap_loop(port->devHandle, -1, &PortInfo::PortMonitor::callback, + (PUCHAR) port); + //ret = pcap_loop(fp, -1, &updateStats, (PUCHAR)&st_ts); + + switch(ret) + { + case 0: + qDebug("Unexpected return from pcap_loop()\n"); + break; + case -1: + qDebug("Unsolicited (error) return from pcap_loop()\n"); + break; + case -2: + qDebug("Solicited return from pcap_loop()\n"); + break; + default: + qDebug("Unknown return value from pcap_loop()\n"); + } +} + +/*--------------- MyService ---------------*/ int MyService::getStreamIndex(unsigned int portIdx, unsigned int streamId) @@ -12,9 +316,9 @@ int MyService::getStreamIndex(unsigned int portIdx, Q_ASSERT(portIdx < numPorts); - for (i = 0; i < portInfo[portIdx].streamList.size(); i++) + for (i = 0; i < portInfo[portIdx]->streamList.size(); i++) { - if (streamId == portInfo[portIdx].streamList.at(i).d.stream_id().id()) + if (streamId == portInfo[portIdx]->streamList.at(i).d.stream_id().id()) goto _found; } @@ -43,34 +347,19 @@ MyService::MyService(AbstractHost *host) goto _fail; } - /* Count number of local ports */ - for(dev = alldevs; dev != NULL; dev = dev->next) + portInfo.clear(); + /* Count, Populate and Print the list */ + for(i=0, dev=alldevs; dev!=NULL; i++, dev=dev->next) + { + portInfo.append(new PortInfo(i, dev)); numPorts++; - portInfo = new PortInfo[numPorts]; - - /* Populate and Print the list */ - for(i=0, dev=alldevs; (i < numPorts) && (dev!=NULL); i++, dev=dev->next) - { - portInfo[i].setId(i); - portInfo[i].setPcapDev(dev); #if 1 LOG("%d. %s", i, dev->name); if (dev->description) { LOG(" (%s)\n", dev->description); } -#endif -#if 0 - // FIXME(HI): Testing only!!!! - { - StreamInfo s; - - s.d.mutable_stream_id()->set_id(0); - portInfo[i].streamList.append(s); - s.d.mutable_stream_id()->set_id(1); - portInfo[i].streamList.append(s); - } #endif } @@ -86,7 +375,6 @@ _fail: MyService::~MyService() { - delete portInfo; pcap_freealldevs(alldevs); } @@ -103,7 +391,7 @@ void MyService::getPortIdList( ::OstProto::PortId *p; p = response->add_port_id(); - p->set_id(portInfo[i].d.port_id().id()); + p->set_id(portInfo[i]->d.port_id().id()); } done->Run(); @@ -126,7 +414,7 @@ const ::OstProto::PortIdList* request, OstProto::Port *p; p = response->add_port(); - p->CopyFrom(portInfo[idx].d); + p->CopyFrom(portInfo[idx]->d); } } @@ -151,11 +439,11 @@ const ::OstProto::PortId* request, } response->mutable_port_id()->set_id(portIdx); - for (int j = 0; j < portInfo[portIdx].streamList.size(); j++) + for (int j = 0; j < portInfo[portIdx]->streamList.size(); j++) { OstProto::StreamId *s, *q; - q = portInfo[portIdx].streamList[j].d.mutable_stream_id(); + q = portInfo[portIdx]->streamList[j].d.mutable_stream_id(); s = response->add_stream_id(); s->CopyFrom(*q); @@ -192,7 +480,7 @@ const ::OstProto::StreamIdList* request, continue; // TODO(LOW): Partial status of RPC s = response->add_stream(); - s->CopyFrom(portInfo[portIdx].streamList[streamIndex].d); + s->CopyFrom(portInfo[portIdx]->streamList[streamIndex].d); } _exit: @@ -229,10 +517,11 @@ const ::OstProto::StreamIdList* request, // expected in a subsequent "modifyStream" request - set the stream id // now itself however!!! s.d.mutable_stream_id()->CopyFrom(request->stream_id(i)); - portInfo[portIdx].streamList.append(s); + portInfo[portIdx]->streamList.append(s); // TODO(LOW): fill-in response "Ack"???? } + portInfo[portIdx]->setDirty(true); _exit: done->Run(); } @@ -262,10 +551,11 @@ const ::OstProto::StreamIdList* request, if (streamIndex < 0) continue; // TODO(LOW): Partial status of RPC - portInfo[portIdx].streamList.removeAt(streamIndex); + portInfo[portIdx]->streamList.removeAt(streamIndex); // TODO(LOW): fill-in response "Ack"???? } + portInfo[portIdx]->setDirty(true); _exit: done->Run(); } @@ -295,11 +585,12 @@ const ::OstProto::StreamConfigList* request, if (streamIndex < 0) continue; // TODO(LOW): Partial status of RPC - portInfo[portIdx].streamList[streamIndex].d.MergeFrom( + portInfo[portIdx]->streamList[streamIndex].d.MergeFrom( request->stream(i)); // TODO(LOW): fill-in response "Ack"???? } + portInfo[portIdx]->setDirty(true); _exit: done->Run(); } @@ -310,7 +601,33 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); - controller->SetFailed("Not Implemented"); + + // If any of the ports in the request are dirty, first update them + for (int i=0; i < request->port_id_size(); i++) + { + uint portIdx; + + portIdx = request->port_id(i).id(); + if (portIdx >= numPorts) + continue; // FIXME(MED): partial RPC? + + if (portInfo[portIdx]->isDirty()) + portInfo[portIdx]->update(); + } + + for (int i=0; i < request->port_id_size(); i++) + { + uint portIdx; + + portIdx = request->port_id(i).id(); + if (portIdx >= numPorts) + continue; // FIXME(MED): partial RPC? + + portInfo[portIdx]->startTransmit(); + } + + // TODO(LOW): fill-in response "Ack"???? + done->Run(); } @@ -320,7 +637,18 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); - controller->SetFailed("Not Implemented"); + + for (int i=0; i < request->port_id_size(); i++) + { + uint portIdx; + + portIdx = request->port_id(i).id(); + if (portIdx >= numPorts) + continue; // FIXME(MED): partial RPC? + + portInfo[portIdx]->stopTransmit(); + } + // TODO(LOW): fill-in response "Ack"???? done->Run(); } @@ -360,7 +688,30 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); - controller->SetFailed("Not Implemented"); + + for (int i=0; i < request->port_id_size(); i++) + { + uint portidx; + ::OstProto::PortStats *s; + + portidx = request->port_id(i).id(); + if (portidx >= numPorts) + continue; // FIXME(med): partial rpc? + + s = response->add_port_stats(); + s->mutable_port_id()->set_id(request->port_id(i).id()); + + s->set_rx_pkts(portInfo[portidx]->stats.rxPkts); + s->set_rx_bytes(portInfo[portidx]->stats.rxBytes); + s->set_rx_pps(portInfo[portidx]->stats.rxPps); + s->set_rx_bps(portInfo[portidx]->stats.rxBps); + + s->set_tx_pkts(portInfo[portidx]->stats.txPkts); + s->set_tx_bytes(portInfo[portidx]->stats.txBytes); + s->set_tx_pps(portInfo[portidx]->stats.txPps); + s->set_tx_bps(portInfo[portidx]->stats.txBps); + } + done->Run(); } @@ -370,7 +721,19 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); - controller->SetFailed("Not Implemented"); + + for (int i=0; i < request->port_id_size(); i++) + { + uint portIdx; + + portIdx = request->port_id(i).id(); + if (portIdx >= numPorts) + continue; // FIXME(MED): partial RPC? + + portInfo[portIdx]->resetStats(); + } + // TODO(LOW): fill-in response "Ack"???? + done->Run(); } diff --git a/server/myservice.h b/server/myservice.h index 45577be..69e2f71 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -10,7 +10,9 @@ #include "../common/protocol.pb.h" #include "abstracthost.h" #include +#include #include +#include #include "../rpc/pbhelper.h" @@ -22,10 +24,12 @@ class MyService; class StreamInfo { friend class MyService; + friend class PortInfo; OstProto::Stream d; StreamInfo() { PbHelper pbh; pbh.ForceSetSingularDefault(&d); } + int StreamInfo::makePacket(uchar *buf, int bufMaxSize); }; @@ -33,34 +37,65 @@ class PortInfo { friend class MyService; + class PortMonitor: public QThread + { + friend class PortInfo; + + PortInfo *port; + public: + PortMonitor(PortInfo *port); + static void callback(u_char *state, + const struct pcap_pkthdr *header, const u_char *pkt_data); + void run(); + }; + OstProto::Port d; + pcap_if_t *dev; + pcap_t *devHandle; + pcap_send_queue *sendQueue; + bool isSendQueueDirty; + PortMonitor monitor; + + struct PortStats + { + quint64 rxPkts; + quint64 rxBytes; + quint64 rxPps; + quint64 rxBps; + + quint64 txPkts; + quint64 txBytes; + quint64 txPps; + quint64 txBps; + }; + + struct PortStats stats; /*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */ QList streamList; public: - // TODO(LOW): Both setId and setPcapDev() should together form the ctor - void setId(unsigned int id) { d.mutable_port_id()->set_id(id); } - void setPcapDev(pcap_if_t *dev) - { - this->dev = dev; - d.set_name("eth"); // FIXME(MED): suffix portid - d.set_description(dev->description); - d.set_is_enabled(true); // FIXME(MED):check - d.set_is_oper_up(true); // FIXME(MED):check - d.set_is_exclusive_control(false); // FIXME(MED): check - } + PortInfo::PortInfo(uint id, pcap_if_t *dev); + uint id() { return d.port_id().id(); } + bool isDirty() { return isSendQueueDirty; } + void setDirty(bool dirty) { isSendQueueDirty = dirty; } + void update(); + void startTransmit(); + void stopTransmit(); + void resetStats(); }; + class MyService: public OstProto::OstService { AbstractHost *host; char logStr[1024]; uint numPorts; + /*! PortInfo::d::port_id and index into portInfo[] are same! */ - PortInfo *portInfo; + QList portInfo; pcap_if_t *alldevs; int getStreamIndex(unsigned int portIdx,unsigned int streamId); From 62a82dfb805dd6ba31b118a3e9d1fbec25dd220b Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 28 Sep 2008 18:01:52 +0000 Subject: [PATCH 10/98] Stream creation (various modes etc.) done except for Rate Control. PortStats done - need to find solution for txRates --- client/mainwindow.cpp | 4 +- client/mainwindow.ui | 318 ++++++------- client/port.cpp | 4 + client/port.h | 1 + client/portgroup.cpp | 103 ++++- client/portgroup.h | 6 +- client/portstatsfilter.ui | 51 +- client/portstatsmodel.cpp | 51 +- client/portstatsmodel.h | 9 + client/portstatswindow.cpp | 47 +- client/portstatswindow.h | 3 +- client/portswindow.cpp | 10 + client/stream.cpp | 27 ++ client/stream.h | 82 +++- client/streamconfigdialog.cpp | 222 ++++++++- client/streamconfigdialog.h | 4 + client/streamconfigdialog.ui | 848 ++++------------------------------ client/streammodel.cpp | 12 +- common/protocol.proto | 48 +- rpc/pbrpcchannel.cpp | 31 +- rpc/rpcserver.cpp | 26 +- server/drone.pro | 2 +- server/myservice.cpp | 464 ++++++++++++++++--- server/myservice.h | 53 ++- 24 files changed, 1355 insertions(+), 1071 deletions(-) diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 7eef2f3..d86b01f 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -18,10 +18,10 @@ MainWindow::MainWindow(QWidget *parent) setupUi(this); - dock->setWidget(portsWindow); - addDockWidget(Qt::TopDockWidgetArea, dock); dock2->setWidget(statsWindow); addDockWidget(Qt::BottomDockWidgetArea, dock2); + dock->setWidget(portsWindow); + addDockWidget(Qt::TopDockWidgetArea, dock); } void MainWindow::on_actionPreferences_triggered() diff --git a/client/mainwindow.ui b/client/mainwindow.ui index 5d43edb..98ab4c2 100644 --- a/client/mainwindow.ui +++ b/client/mainwindow.ui @@ -1,159 +1,159 @@ - - MainWindow - - - - 0 - 0 - 800 - 600 - - - - MainWindow - - - - - - 0 - 0 - 800 - 21 - - - - - File - - - - - - View - - - - - - Window - - - - - - - - - - - - Help - - - - - - - - - - - - Open Config - - - - - Save Config - - - - - Save Config As ... - - - - - Open Capture - - - - - Save Capture - - - - - Save Capture As ... - - - - - E&xit - - - - - Copy Port Config - - - - - Paste Port Config - - - - - Preferences - - - - - Minimize - - - - - Maximize/Restore - - - - - Minimize All - - - - - Maximize/Restoe All - - - - - Arrange All - Cascade - - - - - Arrange All - Tile - - - - - Dock - - - - - Help - - - - - About - - - - - - + + MainWindow + + + + 0 + 0 + 800 + 650 + + + + MainWindow + + + + + + 0 + 0 + 800 + 21 + + + + + File + + + + + + View + + + + + + Window + + + + + + + + + + + + Help + + + + + + + + + + + + Open Config + + + + + Save Config + + + + + Save Config As ... + + + + + Open Capture + + + + + Save Capture + + + + + Save Capture As ... + + + + + E&xit + + + + + Copy Port Config + + + + + Paste Port Config + + + + + Preferences + + + + + Minimize + + + + + Maximize/Restore + + + + + Minimize All + + + + + Maximize/Restoe All + + + + + Arrange All - Cascade + + + + + Arrange All - Tile + + + + + Dock + + + + + Help + + + + + About + + + + + + diff --git a/client/port.cpp b/client/port.cpp index 06f40ae..3ee571e 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -20,6 +20,10 @@ Port::Port(quint32 id, quint32 portGroupId) mPortGroupId = portGroupId; } +Port::~Port() +{ +} + void Port::updatePortConfig(OstProto::Port *port) { d.MergeFrom(*port); diff --git a/client/port.h b/client/port.h index b16d680..c10eeb3 100644 --- a/client/port.h +++ b/client/port.h @@ -35,6 +35,7 @@ public: // FIXME(HIGH): default args is a hack for QList operations on Port Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF); + ~Port(); quint32 portGroupId() const { return mPortGroupId; } const QString& userAlias() const { return mUserAlias; } diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 70cb66e..686b436 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -82,6 +82,13 @@ void PortGroup::when_configApply(int portIndex, uint *cookie) Q_ASSERT(portIndex < mPorts.size()); + if (state() != QAbstractSocket::ConnectedState) + { + if (cookie != NULL) + delete cookie; + return; + } + if (cookie == NULL) { // cookie[0]: op [0 - delete, 1 - add, 2 - modify, 3 - Done!] @@ -414,22 +421,62 @@ void PortGroup::processModifyStreamAck(OstProto::Ack *ack) // TODO(HI): Apply Button should now be disabled???!!!!??? } -void PortGroup::startTx(QList portList) +void PortGroup::startTx(QList *portList) { OstProto::PortIdList portIdList; - OstProto::Ack *ack = new OstProto::Ack; + OstProto::Ack *ack; qDebug("In %s", __FUNCTION__); - for (int i = 0; i < portList.size(); i++) + if (state() != QAbstractSocket::ConnectedState) + return; + + ack = new OstProto::Ack; + if (portList == NULL) + goto _exit; + else { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList.at(i)); + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } } serviceStub->startTx(rpcController, &portIdList, ack, NewCallback(this, &PortGroup::processStartTxAck, ack)); +_exit: + return; +} + +void PortGroup::stopTx(QList *portList) +{ + OstProto::PortIdList portIdList; + OstProto::Ack *ack; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + ack = new OstProto::Ack; + if (portList == NULL) + goto _exit; + else + { + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + } + + serviceStub->stopTx(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStopTxAck, ack)); +_exit: + return; } void PortGroup::processStartTxAck(OstProto::Ack *ack) @@ -439,19 +486,30 @@ void PortGroup::processStartTxAck(OstProto::Ack *ack) delete ack; } -void PortGroup::getPortStats() +void PortGroup::processStopTxAck(OstProto::Ack *ack) { - OstProto::PortStatsList *portStatsList = new OstProto::PortStatsList; - qDebug("In %s", __FUNCTION__); + delete ack; +} + +void PortGroup::getPortStats() +{ + OstProto::PortStatsList *portStatsList; + + //qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + portStatsList = new OstProto::PortStatsList; serviceStub->getStats(rpcController, &portIdList, portStatsList, NewCallback(this, &PortGroup::processPortStatsList, portStatsList)); } void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList) { - qDebug("In %s", __FUNCTION__); + //qDebug("In %s", __FUNCTION__); if (rpcController->Failed()) { @@ -474,12 +532,30 @@ _error_exit: delete portStatsList; } -void PortGroup::clearPortStats() +void PortGroup::clearPortStats(QList *portList) { - OstProto::Ack *ack = new OstProto::Ack; + OstProto::PortIdList portIdList; + OstProto::Ack *ack; qDebug("In %s", __FUNCTION__); + if (state() != QAbstractSocket::ConnectedState) + return; + + ack = new OstProto::Ack; + if (portList == NULL) + portIdList.CopyFrom(this->portIdList); + else + { + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + } + serviceStub->clearStats(rpcController, &portIdList, ack, NewCallback(this, &PortGroup::processClearStatsAck, ack)); } @@ -488,6 +564,9 @@ void PortGroup::processClearStatsAck(OstProto::Ack *ack) { qDebug("In %s", __FUNCTION__); + // Refresh stats immediately after a stats clear/reset + getPortStats(); + delete ack; } diff --git a/client/portgroup.h b/client/portgroup.h index e2b5317..2ffcbaf 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -70,12 +70,14 @@ public: void processModifyStreamAck(OstProto::Ack *ack); - void startTx(QList portList); + void startTx(QList *portList = NULL); void processStartTxAck(OstProto::Ack *ack); + void stopTx(QList *portList = NULL); + void processStopTxAck(OstProto::Ack *ack); void getPortStats(); void processPortStatsList(OstProto::PortStatsList *portStatsList); - void clearPortStats(); + void clearPortStats(QList *portList = NULL); void processClearStatsAck(OstProto::Ack *ack); signals: diff --git a/client/portstatsfilter.ui b/client/portstatsfilter.ui index 8220436..e34fde2 100644 --- a/client/portstatsfilter.ui +++ b/client/portstatsfilter.ui @@ -5,8 +5,8 @@ 0 0 - 402 - 275 + 588 + 298 @@ -71,8 +71,55 @@ QAbstractItemView::ExtendedSelection + + QListView::Free + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + U + + + + + + + D + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index d8b40e6..b3fae30 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -105,6 +105,12 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const case e_STAT_FRAME_RECV_RATE: return stats.rx_pps(); + case e_STAT_FRAMES_RCVD_NIC: + return stats.rx_pkts_nic(); + + case e_STAT_FRAMES_SENT_NIC: + return stats.tx_pkts_nic(); + case e_STAT_BYTES_RCVD: return stats.rx_bytes(); @@ -117,7 +123,15 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const case e_STAT_BYTE_RECV_RATE: return stats.rx_bps(); + case e_STAT_BYTES_RCVD_NIC: + return stats.rx_bytes_nic(); + + case e_STAT_BYTES_SENT_NIC: + return stats.tx_bytes_nic(); + default: + qWarning("%s: Unhandled stats id %d\n", __FUNCTION__, + index.row()); return 0; } } @@ -140,15 +154,38 @@ QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, in void PortStatsModel::portListFromIndex(QModelIndexList indices, QList &portList) { + int i, j; + QModelIndexList selectedCols(indices); + portList.clear(); - for (int i = 0; i < indices.size(); i++) + //selectedCols = indices.selectedColumns(); + for (i = 0; i < selectedCols.size(); i++) { - //getDomainIndexes(indices.at(i), portGroupIdx, portIdx); + uint portGroupIdx, portIdx; - for (int j = 0; j < portList.size(); j++) + getDomainIndexes(selectedCols.at(i), portGroupIdx, portIdx); + for (j = 0; j < portList.size(); j++) { - // FIXME(HI): Incomplete!!!! + if (portList[j].portGroupId == portGroupIdx) + break; + } + + if (j >= portList.size()) + { + // PortGroup Not found + PortGroupAndPortList p; + + p.portGroupId = portGroupIdx; + p.portList.append(portIdx); + + portList.append(p); + } + else + { + // PortGroup found + + portList[j].portList.append(portIdx); } } } @@ -193,5 +230,9 @@ void PortStatsModel::updateStats() void PortStatsModel::when_portGroup_stats_update(quint32 portGroupId) { // FIXME(MED): update only the changed ports, not all - reset(); + + QModelIndex topLeft = index(0, 0, QModelIndex()); + QModelIndex bottomRight = index(rowCount(), columnCount(), QModelIndex()); + + emit dataChanged(topLeft, bottomRight); } diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h index 6dc4693..1825524 100644 --- a/client/portstatsmodel.h +++ b/client/portstatsmodel.h @@ -9,10 +9,14 @@ typedef enum { e_STAT_FRAMES_SENT, e_STAT_FRAME_SEND_RATE, e_STAT_FRAME_RECV_RATE, + e_STAT_FRAMES_RCVD_NIC, + e_STAT_FRAMES_SENT_NIC, e_STAT_BYTES_RCVD, e_STAT_BYTES_SENT, e_STAT_BYTE_SEND_RATE, e_STAT_BYTE_RECV_RATE, + e_STAT_BYTES_RCVD_NIC, + e_STAT_BYTES_SENT_NIC, e_STAT_MAX } PortStat; @@ -21,10 +25,14 @@ static QStringList PortStatName = (QStringList() << "Frames Sent" << "Frame Send Rate (fps)" << "Frame Receive Rate (fps)" + << "Frames Received (NIC)" + << "Frames Sent (NIC)" << "Bytes Received" << "Bytes Sent" << "Byte Send Rate (Bps)" << "Byte Receive Rate (Bps)" + << "Bytes Received (NIC)" + << "Bytes Sent (NIC)" ); class PortGroupList; @@ -44,6 +52,7 @@ class PortStatsModel : public QAbstractTableModel int role = Qt::DisplayRole) const; class PortGroupAndPortList { + public: uint portGroupId; QList portList; }; diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index 28b8f88..5f4ff6b 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -14,7 +14,10 @@ PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent) model = pgl->getPortStatsModel(); tvPortStats->setModel(model); tvPortStats->horizontalHeader()->setMovable(true); - tvPortStats->verticalHeader()->resizeSections(QHeaderView::ResizeToContents); + + tvPortStats->verticalHeader()->setHighlightSections(false); + tvPortStats->verticalHeader()->setDefaultSectionSize( + tvPortStats->verticalHeader()->minimumSectionSize()); } PortStatsWindow::~PortStatsWindow() @@ -25,21 +28,34 @@ PortStatsWindow::~PortStatsWindow() void PortStatsWindow::on_tbStartTransmit_clicked() { - // TODO(MED): get selected ports + QList pgpl; - if (pgl->numPortGroups()) + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) { - QList portIdList; - - // FIXME(HI): Testing only!!! - portIdList.append(1); // MS Loopback adapter - pgl->portGroupByIndex(0).startTx(portIdList); + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + startTx(&pgpl[i].portList); } } void PortStatsWindow::on_tbStopTransmit_clicked() { - // TODO(MED) + QList pgpl; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + startTx(&pgpl[i].portList); + } } void PortStatsWindow::on_tbStartCapture_clicked() @@ -59,7 +75,18 @@ void PortStatsWindow::on_tbViewCapture_clicked() void PortStatsWindow::on_tbClear_clicked() { - // TODO(MED) + QList portList; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + portList); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < portList.size(); i++) + { + pgl->portGroupByIndex(portList.at(i).portGroupId). + clearPortStats(&portList[i].portList); + } } void PortStatsWindow::on_tbClearAll_clicked() diff --git a/client/portstatswindow.h b/client/portstatswindow.h index 98642c1..c1d581f 100644 --- a/client/portstatswindow.h +++ b/client/portstatswindow.h @@ -5,6 +5,7 @@ #include #include "ui_portstatswindow.h" #include "portgrouplist.h" +#include "portstatsmodel.h" class PortStatsWindow : public QWidget, public Ui::PortStatsWindow { @@ -16,7 +17,7 @@ public: private: PortGroupList *pgl; - QAbstractItemModel *model; + PortStatsModel *model; private slots: void on_tbStartTransmit_clicked(); diff --git a/client/portswindow.cpp b/client/portswindow.cpp index f711f55..645bd1b 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -11,6 +11,12 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) setupUi(this); + tvStreamList->horizontalHeader()->resizeSections( + QHeaderView::ResizeToContents); + tvStreamList->verticalHeader()->setDefaultSectionSize( + tvStreamList->verticalHeader()->minimumSectionSize()); + + // Populate Context Menu Actions tvPortList->addAction(actionNew_Port_Group); tvPortList->addAction(actionDelete_Port_Group); tvPortList->addAction(actionConnect_Port_Group); @@ -40,6 +46,10 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) connect( tvPortList->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&))); + + // Initially we don't have any ports - so trigger selection of + // portgroup detail page + when_portView_currentChanged(QModelIndex(), QModelIndex()); } PortsWindow::~PortsWindow() diff --git a/client/stream.cpp b/client/stream.cpp index 653859c..2d82040 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -951,6 +951,7 @@ Stream::Stream() mId = 0xFFFFFFFF; mCore = new OstProto::StreamCore; + mControl = new OstProto::StreamControl; // mCore->set_port_id(0xFFFFFFFF); // mCore->set_stream_id(mId); @@ -973,6 +974,8 @@ Stream::Stream() mUdp = new UdpProtocol; mIcmp = new IcmpProtocol; mIgmp = new IgmpProtocol; + + mCore->set_is_enabled(true); } void Stream::getConfig(uint portId, OstProto::Stream *s) @@ -980,6 +983,7 @@ void Stream::getConfig(uint portId, OstProto::Stream *s) s->mutable_stream_id()->set_id(mId); s->mutable_core()->CopyFrom(*mCore); + s->mutable_control()->CopyFrom(*mControl); mMac->getConfig(s->mutable_mac()); mMac->getConfig(s->mutable_mac()); @@ -997,6 +1001,29 @@ void Stream::getConfig(uint portId, OstProto::Stream *s) mIgmp->getConfig(s->mutable_igmp()); } +bool Stream::update(OstProto::Stream *stream) + { + mCore->MergeFrom(stream->core()); + mControl->MergeFrom(stream->control()); + mMac->update(stream->mac()); + + mLlc->update(stream->llc()); + mSnap->update(stream->snap()); + mEth2->update(stream->eth2()); + mVlan->update(stream->vlan()); + + mIp->update(stream->ip()); + mArp->update(stream->arp()); + + mTcp->update(stream->tcp()); + mUdp->update(stream->udp()); + mIcmp->update(stream->icmp()); + mIgmp->update(stream->igmp()); + + // FIXME(MED): Re-eval why not store complete OstProto::Stream + // instead of components + return true; + } // FIXME(HIGH): Replace this by some Protocol Registration mechanism at Init #define PTYP_L2_NONE 1 #define PTYP_L2_ETH_2 2 diff --git a/client/stream.h b/client/stream.h index 9500064..42f74ff 100644 --- a/client/stream.h +++ b/client/stream.h @@ -831,6 +831,7 @@ class Stream { quint32 mId; OstProto::StreamCore *mCore; + OstProto::StreamControl *mControl; UnknownProtocol *mUnknown; PayloadProtocol *mPayload; @@ -909,6 +910,22 @@ public: e_l4_igmp, }; + enum SendUnit { + e_su_packets, + e_su_bursts + }; + + enum SendMode { + e_sm_fixed, + e_sm_continuous + }; + + enum NextWhat { + e_nw_stop, + e_nw_goto_next, + e_nw_goto_id + }; + // ------------------------------------------------------- // Methods // ------------------------------------------------------- @@ -917,30 +934,9 @@ public: bool operator < (const Stream &s) const { return(mCore->ordinal() < s.mCore->ordinal()); } - bool update(OstProto::Stream *stream) - { - mCore->MergeFrom(stream->core()); - mMac->update(stream->mac()); - - mLlc->update(stream->llc()); - mSnap->update(stream->snap()); - mEth2->update(stream->eth2()); - mVlan->update(stream->vlan()); - - mIp->update(stream->ip()); - mArp->update(stream->arp()); - - mTcp->update(stream->tcp()); - mUdp->update(stream->udp()); - mIcmp->update(stream->icmp()); - mIgmp->update(stream->igmp()); - - // FIXME(MED): Re-eval why not store complete OstProto::Stream - // instead of components - return true; - } void getConfig(uint portId, OstProto::Stream *s); + bool update(OstProto::Stream *stream); quint32 id() { return mId;} @@ -1025,6 +1021,48 @@ public: { mCore->set_l4_proto((OstProto::StreamCore::L4Proto) l4Proto); return true; } + SendUnit sendUnit() + { return (SendUnit) mControl->unit(); } + bool setSendUnit(SendUnit sendUnit) + { mControl->set_unit( + (OstProto::StreamControl::SendUnit) sendUnit); return true; } + + SendMode sendMode() + { return (SendMode) mControl->mode(); } + bool setSendMode(SendMode sendMode) + { mControl->set_mode( + (OstProto::StreamControl::SendMode) sendMode); return true; } + + NextWhat nextWhat() + { return (NextWhat) mControl->next(); } + bool setNextWhat(NextWhat nextWhat) + { mControl->set_next( + (OstProto::StreamControl::NextWhat) nextWhat); return true; } + + quint32 numPackets() + { return (quint32) mControl->num_packets(); } + bool setNumPackets(quint32 numPackets) + { mControl->set_num_packets(numPackets); return true; } + + quint32 numBursts() + { return (quint32) mControl->num_bursts(); } + bool setNumBursts(quint32 numBursts) + { mControl->set_num_bursts(numBursts); return true; } + + quint32 burstSize() + { return (quint32) mControl->packets_per_burst(); } + bool setBurstSize(quint32 packetsPerBurst) + { mControl->set_packets_per_burst(packetsPerBurst); return true; } + + quint32 packetRate() + { return (quint32) mControl->packets_per_sec(); } + bool setPacketRate(quint32 packetsPerSec) + { mControl->set_packets_per_sec(packetsPerSec); return true; } + + quint32 burstRate() + { return (quint32) mControl->bursts_per_sec(); } + bool setBurstRate(quint32 burstsPerSec) + { mControl->set_bursts_per_sec(burstsPerSec); return true; } //--------------------------------------------------------------- // Methods for use by Packet Model diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 0202825..cef9771 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -13,6 +13,112 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, setupUi(this); setupUiExtra(); + // Time to play match the signals and slots! + connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); + + // Show/Hide FrameType related inputs for FT None + connect(rbFtNone, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), lblSsap, SLOT(setHidden(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), leSsap, SLOT(setHidden(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), lblControl, SLOT(setHidden(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), leControl, SLOT(setHidden(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool))); + + // Show/Hide FrameType related inputs for FT Ethernet2 + connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblSsap, SLOT(setHidden(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), leSsap, SLOT(setHidden(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblControl, SLOT(setHidden(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), leControl, SLOT(setHidden(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool))); + + // Show/Hide FrameType related inputs for FT 802.3 Raw + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblSsap, SLOT(setHidden(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leSsap, SLOT(setHidden(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblControl, SLOT(setHidden(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leControl, SLOT(setHidden(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool))); + + // Show/Hide FrameType related inputs for FT 802.3 LLC + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblDsap, SLOT(setVisible(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leDsap, SLOT(setVisible(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblSsap, SLOT(setVisible(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leSsap, SLOT(setVisible(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblControl, SLOT(setVisible(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leControl, SLOT(setVisible(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool))); + + // Show/Hide FrameType related inputs for FT 802.3 LLC SNAP + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblDsap, SLOT(setVisible(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leDsap, SLOT(setVisible(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblSsap, SLOT(setVisible(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leSsap, SLOT(setVisible(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblControl, SLOT(setVisible(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leControl, SLOT(setVisible(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblOui, SLOT(setVisible(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leOui, SLOT(setVisible(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool))); + + // Enable/Disable FrameType related inputs for FT 802.3 LLC SNAP + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblDsap, SLOT(setDisabled(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leDsap, SLOT(setDisabled(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblSsap, SLOT(setDisabled(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leSsap, SLOT(setDisabled(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblControl, SLOT(setDisabled(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leControl, SLOT(setDisabled(bool))); + + // Enable/Disable L4 Protocol Choices for L3 Protocol None + connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); + connect(rbL3None, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool))); + connect(rbL3None, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool))); + connect(rbL3None, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool))); + connect(rbL3None, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool))); + connect(rbL3None, SIGNAL(toggled(bool)), rbL4Other, SLOT(setDisabled(bool))); + + // Force L4 Protocol = None if L3 Protocol is set to None + connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool))); + + // Enable/Disable L4 Protocol Choices for L3 Protocol IPv4 + connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); + connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setEnabled(bool))); + connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setEnabled(bool))); + connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setEnabled(bool))); + connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setEnabled(bool))); + connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Other, SLOT(setEnabled(bool))); + + // Enable/Disable L4 Protocol Choices for L3 Protocol ARP + connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); + connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool))); + connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool))); + connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool))); + connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool))); + connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Other, SLOT(setDisabled(bool))); + + // Force L4 Protocol = None if L3 Protocol is set to ARP + connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool))); + + // Init with FT=Eth2 to trigger signals; actual value will be + // initialized by LoadCurrentStream() + rbFtEthernet2->click(); + rbFtNone->click(); + //mpStreamList = streamList; mCurrentStreamIndex = streamIndex; LoadCurrentStream(); @@ -24,9 +130,16 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, vwPacketDump->setModel(mpPacketModel); vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); - // FIXME(MED): Enable this navigation + + + // TODO(MED): + //! \todo Enable navigation of streams pbPrev->setDisabled(true); pbNext->setDisabled(true); + //! \todo Support Goto Stream Id + rbActionGotoStream->setDisabled(true); + //! \todo Support Continuous Mode + rbModeContinuous->setDisabled(true); } void StreamConfigDialog::setupUiExtra() @@ -128,6 +241,22 @@ void StreamConfigDialog::on_pbNext_clicked() #endif } +void StreamConfigDialog::on_rbFtNone_toggled(bool checked) +{ +} + +void StreamConfigDialog::on_rbFtEthernet2_toggled(bool checked) +{ +} + +void StreamConfigDialog::on_rbFt802Dot3Raw_toggled(bool checked) +{ +} + +void StreamConfigDialog::on_rbFt802Dot3Llc_toggled(bool checked) +{ +} + void StreamConfigDialog::on_rbFtLlcSnap_toggled(bool checked) { if (checked) @@ -551,6 +680,55 @@ void StreamConfigDialog::LoadCurrentStream() // TODO(LOW) } } + + // Stream Control + { + switch (pStream->sendUnit()) + { + case Stream::e_su_packets: + rbSendPackets->setChecked(true); + break; + case Stream::e_su_bursts: + rbSendBursts->setChecked(true); + break; + default: + qWarning("Unhandled sendUnit = %d\n", pStream->sendUnit()); + } + + switch (pStream->sendMode()) + { + case Stream::e_sm_fixed: + rbModeFixed->setChecked(true); + break; + case Stream::e_sm_continuous: + rbModeContinuous->setChecked(true); + break; + default: + qWarning("Unhandled sendMode = %d\n", pStream->sendMode()); + } + + switch(pStream->nextWhat()) + { + case Stream::e_nw_stop: + rbActionStop->setChecked(true); + break; + case Stream::e_nw_goto_next: + rbActionGotoNext->setChecked(true); + break; + case Stream::e_nw_goto_id: + rbActionGotoStream->setChecked(true); + break; + default: + qWarning("Unhandled nextAction = %d\n", pStream->nextWhat()); + } + + leNumPackets->setText(QString().setNum(pStream->numPackets())); + leNumBursts->setText(QString().setNum(pStream->numBursts())); + lePacketsPerBurst->setText(QString().setNum( + pStream->burstSize())); + lePacketsPerSec->setText(QString().setNum(pStream->packetRate())); + leBurstsPerSec->setText(QString().setNum(pStream->burstRate())); + } } void StreamConfigDialog::StoreCurrentStream() @@ -623,11 +801,14 @@ void StreamConfigDialog::StoreCurrentStream() { // L2 | Ethernet { + qDebug("%s: LL dstMac = %llx", __FUNCTION__, + leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); pStream->mac()->setDstMac( leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); #if 1 - qDebug("%s: dstMac = %llx [%s] %d", __FUNCTION__, - pStream->mac()->dstMac(), + qDebug("%s: dstMac = %llx", __FUNCTION__, + pStream->mac()->dstMac()); + qDebug("%s: dstMac = [%s] %d", __FUNCTION__, leDstMac->text().toAscii().constData(), isOk); #endif pStream->mac()->setDstMacMode( @@ -639,8 +820,9 @@ void StreamConfigDialog::StoreCurrentStream() pStream->mac()->setSrcMac( leSrcMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); - qDebug("%s: srcMac = %llx [%s] %d", __FUNCTION__, - pStream->mac()->srcMac(), + qDebug("%s: srcMac = %llx", __FUNCTION__, + pStream->mac()->srcMac()); + qDebug("%s: srcMac = [%s] %d", __FUNCTION__, leSrcMac->text().toAscii().constData(), isOk); pStream->mac()->setSrcMacMode( (MacProtocol::MacAddrMode) cmbSrcMacMode->currentIndex()); @@ -657,7 +839,7 @@ void StreamConfigDialog::StoreCurrentStream() vlan->setCvlanPrio(cmbCvlanPrio->currentIndex()); vlan->setCvlanCfi(cmbCvlanCfi->currentIndex()); vlan->setCvlanId(leCvlanId->text().toULong(&isOk)); - vlan->setCtpid(leCvlanTpid->text().remove(QChar(' ')).toULong(&isOk)); + vlan->setCtpid(leCvlanTpid->text().remove(QChar(' ')).toULong(&isOk, 16)); if (cbCvlanTpidOverride->isChecked()) f |= VlanProtocol::VlanCtpidOverride; if (gbCvlan->isChecked()) @@ -666,7 +848,7 @@ void StreamConfigDialog::StoreCurrentStream() vlan->setSvlanPrio(cmbSvlanPrio->currentIndex()); vlan->setSvlanCfi(cmbSvlanCfi->currentIndex()); vlan->setSvlanId(leSvlanId->text().toULong(&isOk)); - vlan->setStpid(leSvlanTpid->text().remove(QChar(' ')).toULong(&isOk)); + vlan->setStpid(leSvlanTpid->text().remove(QChar(' ')).toULong(&isOk, 16)); if (cbSvlanTpidOverride->isChecked()) f |= VlanProtocol::VlanStpidOverride; if (gbSvlan->isChecked()) @@ -798,6 +980,32 @@ void StreamConfigDialog::StoreCurrentStream() // TODO(LOW) } } + + // Stream Control + { + if (rbSendPackets->isChecked()) + pStream->setSendUnit(Stream::e_su_packets); + if (rbSendBursts->isChecked()) + pStream->setSendUnit(Stream::e_su_bursts); + + if (rbModeFixed->isChecked()) + pStream->setSendMode(Stream::e_sm_fixed); + if (rbModeContinuous->isChecked()) + pStream->setSendMode(Stream::e_sm_continuous); + + if (rbActionStop->isChecked()) + pStream->setNextWhat(Stream::e_nw_stop); + if (rbActionGotoNext->isChecked()) + pStream->setNextWhat(Stream::e_nw_goto_next); + if (rbActionGotoStream->isChecked()) + pStream->setNextWhat(Stream::e_nw_goto_id); + + pStream->setNumPackets(leNumPackets->text().toULong(&isOk)); + pStream->setNumBursts(leNumBursts->text().toULong(&isOk)); + pStream->setBurstSize(lePacketsPerBurst->text().toULong(&isOk)); + pStream->setPacketRate(lePacketsPerSec->text().toULong(&isOk)); + pStream->setBurstRate(leBurstsPerSec->text().toULong(&isOk)); + } } void StreamConfigDialog::on_pbOk_clicked() diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 2485011..f95205d 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -44,6 +44,10 @@ private slots: void on_pbPrev_clicked(); void on_pbNext_clicked(); + void on_rbFtNone_toggled(bool checked); + void on_rbFtEthernet2_toggled(bool checked); + void on_rbFt802Dot3Raw_toggled(bool checked); + void on_rbFt802Dot3Llc_toggled(bool checked); void on_rbFtLlcSnap_toggled(bool checked); void on_rbL3Ipv4_toggled(bool checked); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 503eb27..f3ed791 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -33,7 +33,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 2 + 0 @@ -214,7 +214,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff None - false + true @@ -241,7 +241,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff 802.3 LLC - true + false @@ -332,7 +332,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
- + Type @@ -420,7 +420,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - false + true ICMP @@ -430,7 +430,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - false + true IGMP @@ -440,7 +440,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - false + true TCP @@ -450,7 +450,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - false + true UDP @@ -2151,12 +2151,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 252 - 288 + 112 + 267 - 252 - 317 + 112 + 267 @@ -2167,12 +2167,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 252 - 388 + 112 + 267 - 252 - 417 + 112 + 267 @@ -2183,12 +2183,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 31 - 259 + 92 + 267 - 41 - 317 + 92 + 267 @@ -2199,12 +2199,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 31 - 259 + 92 + 267 - 81 - 317 + 92 + 267 @@ -2215,12 +2215,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 31 - 259 + 92 + 267 - 120 - 317 + 92 + 267 @@ -2231,12 +2231,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 31 - 259 + 92 + 267 - 252 - 288 + 112 + 267 @@ -2247,12 +2247,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 31 - 359 + 92 + 267 - 41 - 417 + 92 + 267 @@ -2263,12 +2263,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 31 - 359 + 92 + 267 - 120 - 417 + 92 + 267 @@ -2279,12 +2279,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 31 - 359 + 92 + 267 - 252 - 388 + 112 + 267 @@ -2295,12 +2295,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 31 - 359 + 92 + 267 - 81 - 417 + 92 + 267 @@ -2311,12 +2311,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 123 - 305 + 145 + 334 - 123 - 305 + 145 + 334 @@ -2327,12 +2327,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 123 - 305 + 145 + 334 - 123 - 305 + 145 + 334 @@ -2343,12 +2343,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 42 - 171 + 123 + 305 - 232 - 170 + 123 + 305 @@ -2359,12 +2359,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 42 - 197 + 123 + 305 - 232 - 196 + 123 + 305 @@ -2375,12 +2375,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 42 - 252 + 123 + 305 - 232 - 251 + 123 + 305 @@ -2391,12 +2391,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 383 - 274 + 192 + 305 - 506 - 274 + 192 + 305 @@ -2407,12 +2407,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 123 - 305 + 145 + 334 - 123 - 305 + 145 + 334 @@ -2423,492 +2423,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 123 - 305 + 145 + 334 - 123 - 305 - - - - - rbFtNone - toggled(bool) - lblDsap - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFtNone - toggled(bool) - leDsap - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtNone - toggled(bool) - lblSsap - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFtNone - toggled(bool) - leSsap - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtNone - toggled(bool) - lblControl - setHidden(bool) - - - 57 - 218 - - - 137 - 237 - - - - - rbFtNone - toggled(bool) - leControl - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtNone - toggled(bool) - lblOui - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFtNone - toggled(bool) - leOui - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtNone - toggled(bool) - lblTpe - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFtNone - toggled(bool) - leType - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtEthernet2 - toggled(bool) - lblDsap - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFtEthernet2 - toggled(bool) - leDsap - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtEthernet2 - toggled(bool) - lblSsap - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFtEthernet2 - toggled(bool) - leSsap - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - lblControl - setHidden(bool) - - - 57 - 218 - - - 137 - 237 - - - - - rbFt802Dot3Raw - toggled(bool) - leControl - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtEthernet2 - toggled(bool) - lblControl - setHidden(bool) - - - 57 - 218 - - - 137 - 237 - - - - - rbFtEthernet2 - toggled(bool) - leControl - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtEthernet2 - toggled(bool) - lblOui - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFtEthernet2 - toggled(bool) - leOui - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - lblDsap - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - leDsap - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - lblSsap - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - leSsap - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - lblControl - setHidden(bool) - - - 57 - 218 - - - 137 - 237 - - - - - rbFt802Dot3Raw - toggled(bool) - leControl - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - lblOui - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - leOui - setHidden(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - lblTpe - setHidden(bool) - - - 57 - 218 - - - 58 - 218 - - - - - rbFt802Dot3Raw - toggled(bool) - leType - setHidden(bool) - - - 57 - 218 - - - 99 - 218 + 145 + 334 @@ -2944,182 +2464,6 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - rbFtLlcSnap - toggled(bool) - leDsap - setDisabled(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtLlcSnap - toggled(bool) - leSsap - setDisabled(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbFtLlcSnap - toggled(bool) - leControl - setDisabled(bool) - - - 57 - 218 - - - 99 - 218 - - - - - rbL3Ipv4 - toggled(bool) - rbL4Tcp - setEnabled(bool) - - - 570 - 218 - - - 570 - 302 - - - - - rbL3Ipv4 - toggled(bool) - rbL4Udp - setEnabled(bool) - - - 570 - 218 - - - 570 - 302 - - - - - rbL3Ipv4 - toggled(bool) - rbL4Other - setEnabled(bool) - - - 570 - 218 - - - 570 - 302 - - - - - rbL3Ipv4 - toggled(bool) - rbL4Icmp - setEnabled(bool) - - - 570 - 218 - - - 570 - 302 - - - - - rbL3Ipv4 - toggled(bool) - rbL4Igmp - setEnabled(bool) - - - 570 - 218 - - - 570 - 302 - - - - - rbL3None - clicked() - rbL4None - click() - - - 570 - 218 - - - 570 - 302 - - - - - rbL3Arp - clicked() - rbL4None - click() - - - 570 - 218 - - - 570 - 302 - - - - - rbL3Other - clicked() - rbL4None - click() - - - 570 - 218 - - - 570 - 302 - - - rbActionGotoStream toggled(bool) @@ -3127,12 +2471,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 381 - 140 + 136 + 120 - 381 - 174 + 136 + 120 @@ -3143,12 +2487,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 30 - 69 + 41 + 101 - 85 - 285 + 96 + 120 @@ -3159,12 +2503,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 30 - 94 + 41 + 120 - 67 - 331 + 78 + 120 @@ -3175,12 +2519,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 30 - 94 + 41 + 120 - 222 - 189 + 136 + 120 diff --git a/client/streammodel.cpp b/client/streammodel.cpp index 3ee9136..32dce31 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -38,7 +38,10 @@ Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const flags |= Qt::ItemIsEditable; break; case StreamStatus: +#if 0 flags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable; +#endif + flags |= Qt::ItemIsEditable; break; default: break; @@ -87,11 +90,11 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const } case StreamStatus: { - #if 0 if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) - return streamList[index.row()].isEnabled; - if ((role == Qt::DisplayRole) || (role == Qt::CheckStateRole) || - #endif + return mCurrentPort->streamByIndex(index.row()).isEnabled(); + else + return QVariant(); + #if 0 if ((role == Qt::CheckStateRole) || (role == Qt::EditRole)) { if (mCurrentPort->streamByIndex(index.row()).isEnabled()) @@ -101,6 +104,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const } else return QVariant(); + #endif break; } default: diff --git a/common/protocol.proto b/common/protocol.proto index 7ffd54f..fee57b9 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -109,7 +109,7 @@ message Tcp { optional uint32 dst_port = 4 [default = 80]; optional uint32 seq_num = 5 [default = 129018]; - optional uint32 ack_num = 6 [default = 98223]; + optional uint32 ack_num = 6; optional uint32 hdrlen_rsvd = 7 [default = 0x50]; optional uint32 flags = 8; @@ -138,6 +138,9 @@ message Icmp { message Igmp { } +message StreamId { + required uint32 id = 1; +} message StreamCore { @@ -201,14 +204,41 @@ message StreamCore { optional L4Proto l4_proto = 23; } -message StreamId { - required uint32 id = 1; +message StreamControl { + enum SendUnit { + e_su_packets = 0; + e_su_bursts = 1; + } + + enum SendMode { + e_sm_fixed = 0; + e_sm_continuous = 1; + } + + enum NextWhat { + e_nw_stop = 0; + e_nw_goto_next = 1; + e_nw_goto_id = 2; + } + + optional SendUnit unit = 1 [default = e_su_packets]; + optional SendMode mode = 2 [default = e_sm_fixed]; + optional uint32 num_packets = 3 [default = 1]; + optional uint32 num_bursts = 4 [default = 1]; + optional uint32 packets_per_burst = 5 [default = 10]; + optional NextWhat next = 6 [default = e_nw_goto_next]; + optional uint32 packets_per_sec = 7; + optional uint32 bursts_per_sec = 8; + + // TODO: Gaps? + } message Stream { required StreamId stream_id = 1; optional StreamCore core = 2; + optional StreamControl control = 3; // Protocol data - L2 optional Mac mac = 51; @@ -283,13 +313,17 @@ message PortStats { optional uint64 rx_pkts = 11; optional uint64 rx_bytes = 12; - optional uint64 rx_pps = 13; - optional uint64 rx_bps = 14; + optional uint64 rx_pkts_nic = 13; + optional uint64 rx_bytes_nic = 14; + optional uint64 rx_pps = 15; + optional uint64 rx_bps = 16; optional uint64 tx_pkts = 21; optional uint64 tx_bytes = 22; - optional uint64 tx_pps = 23; - optional uint64 tx_bps = 24; + optional uint64 tx_pkts_nic = 23; + optional uint64 tx_bytes_nic = 24; + optional uint64 tx_pps = 25; + optional uint64 tx_bps = 26; } message PortStatsList { diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index 366ca6f..ed60d2f 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -69,7 +69,7 @@ void PbRpcChannel::CallMethod( char *p = (char *)&msg; int len; - qDebug("In %s", __FUNCTION__); + //qDebug("In %s", __FUNCTION__); if (!req->IsInitialized()) { @@ -88,8 +88,8 @@ void PbRpcChannel::CallMethod( isPending = true; *((quint16*)(p+0)) = HTONS(PB_MSG_TYPE_REQUEST); // type - qDebug("CLi:GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)), - PB_MSG_TYPE_REQUEST); + //qDebug("CLi:GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)), + //PB_MSG_TYPE_REQUEST); *((quint16*)(p+2)) = HTONS(method->index()); // method id // (p+4) len later after serialization *((quint16*)(p+6)) = HTONS(0); // rsvd @@ -100,9 +100,13 @@ void PbRpcChannel::CallMethod( len = req->ByteSize(); *((quint16*)(p+4)) = HTONS(len); // len - qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, len+8, - req->DebugString().c_str()); - BUFDUMP(msg, len+8); + // Avoid printing stats since it happens every couple of seconds + if (pendingMethodId != 12) + { + qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, len+8, + req->DebugString().c_str()); + BUFDUMP(msg, len+8); + } mpSocket->write(msg, len + 8); } @@ -115,12 +119,12 @@ void PbRpcChannel::on_mpSocket_readyRead() quint16 type, method, len, rsvd; PbRpcController *controller; - qDebug("In %s", __FUNCTION__); + //qDebug("In %s", __FUNCTION__); msgLen = mpSocket->read(msg, sizeof(msg)); - qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); - BUFDUMP(msg, msgLen); + //qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); + //BUFDUMP(msg, msgLen); type = NTOHS(GET16(p+0)); method = NTOHS(GET16(p+2)); @@ -153,8 +157,13 @@ void PbRpcChannel::on_mpSocket_readyRead() // Serialized data starts from offset 8 response->ParseFromArray((void*) &msg[8], len); - qDebug("client(%s): Parsed as %s", __FUNCTION__, - response->DebugString().c_str()); + + // Avoid printing stats + if (method != 12) + { + qDebug("client(%s): Parsed as %s", __FUNCTION__, + response->DebugString().c_str()); + } if (!response->IsInitialized()) { diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index 7b6335b..a3978cb 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -41,7 +41,7 @@ void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcCo char *p = (char *)&msg; int len; - qDebug("In RpcServer::done"); + //qDebug("In RpcServer::done"); // TODO: check PbRpcController to see if method failed if (PbRpcController->Failed()) @@ -67,9 +67,13 @@ void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcCo len = resp->ByteSize(); (*(quint16*)(p+4)) = HTONS(len); // len - qDebug("Server(%s): sending %d bytes to client encoding <%s>", - __FUNCTION__, len + 8, resp->DebugString().c_str()); - //BUFDUMP(msg, len + 8); + // Avoid printing stats since it happens once every couple of seconds + if (pendingMethodId != 12) + { + qDebug("Server(%s): sending %d bytes to client encoding <%s>", + __FUNCTION__, len + 8, resp->DebugString().c_str()); + //BUFDUMP(msg, len + 8); + } clientSock->write(msg, len + 8); @@ -132,17 +136,17 @@ void RpcServer::when_dataAvail() PbRpcController *controller; msgLen = clientSock->read(msg, sizeof(msg)); - LogInt(QString(QByteArray(msg, msgLen).toHex())); + //LogInt(QString(QByteArray(msg, msgLen).toHex())); - qDebug("Server %s: rcvd %d bytes", __FUNCTION__, msgLen); + //qDebug("Server %s: rcvd %d bytes", __FUNCTION__, msgLen); //BUFDUMP(msg, msgLen); type = NTOHS(GET16(p+0)); method = NTOHS(GET16(p+2)); len = NTOHS(GET16(p+4)); rsvd = NTOHS(GET16(p+6)); - qDebug("type = %d, method = %d, len = %d, rsvd = %d", - type, method, len, rsvd); + //qDebug("type = %d, method = %d, len = %d, rsvd = %d", + //type, method, len, rsvd); if (type != PB_MSG_TYPE_REQUEST) { @@ -182,12 +186,12 @@ void RpcServer::when_dataAvail() goto _error_exit; } - qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, - resp->DebugString().c_str()); + //qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, + //resp->DebugString().c_str()); controller = new PbRpcController; - qDebug("before service->callmethod()"); + //qDebug("before service->callmethod()"); service->CallMethod(methodDesc, controller, req, resp, NewCallback(this, &RpcServer::done, resp, controller)); diff --git a/server/drone.pro b/server/drone.pro index 79cbd1a..3642823 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -5,7 +5,7 @@ DEFINES += HAVE_REMOTE WPCAP INCLUDEPATH += "c:\msys\1.0\local\include" INCLUDEPATH += "C:\DevelLibs\WpdPack\Include" INCLUDEPATH += "..\rpc" -LIBS += -L"C:\DevelLibs\WpdPack\Lib" -lwpcap +LIBS += -L"C:\DevelLibs\WpdPack\Lib" -lwpcap -lpacket LIBS += -L"..\rpc\debug" -lpbrpc HEADERS += drone.h FORMS += drone.ui diff --git a/server/myservice.cpp b/server/myservice.cpp index 79db27b..b21310d 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -1,30 +1,177 @@ #include "myservice.h" #include "qdebug.h" +#include #include +#ifdef Q_OS_WIN32 +#include +#include +#endif + #define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} #define MB (1024*1024) -int StreamInfo::makePacket(uchar *buf, int bufMaxSize) +#if 0 +quint16 StreamInfo::ipv4Cksum(quint16 ipHdrLen, quint16 buff[]) { - int pktLen, len = 0; + quint16 word16; + quint32 sum=0; + quint16 i; + + // make 16 bit words out of every two adjacent 8 bit words in the packet + // and add them up + for (i = 0; i < ipHdrLen ;i += 2) + { + word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF); + sum = sum + (quint32) word16; + } + + // take only 16 bits out of the 32 bit sum and add up the carries + while (sum>>16) + sum = (sum & 0xFFFF)+(sum >> 16); + + // one's complement the result + sum = ~sum; + + return (quint16) sum; +} +#endif + +quint16 StreamInfo::ipv4Cksum(uchar *buf, int len) +{ + quint32 sum = 0; /* assume 32 bit long, 16 bit short */ + quint16 *ip = (quint16*) buf; + + while(len > 1) + { + sum += *ip; + if(sum & 0x80000000) /* if high order bit set, fold */ + sum = (sum & 0xFFFF) + (sum >> 16); + ip++; + len -= 2; + } + + if(len) /* take care of left over byte */ + sum += (unsigned short) *(unsigned char *)ip; + + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); + + qDebug("cksum = %x", ~sum); + return (quint16) ~sum; +} + +int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) +{ + int u, pktLen, len = 0; uchar scratch[8]; // TODO(HI): use FrameLengthMode - don't assume fixed - pktLen = d.core().frame_len(); + // pktLen is adjusted for CRC/FCS which will be added by the NIC + pktLen = d.core().frame_len() - 4; if (bufMaxSize < pktLen) return 0; // We always have a Mac Header! - // TODO(HI): use MacMode - don't assume fixed - qToBigEndian((quint64) d.mac().dst_mac(), scratch); + switch (d.mac().dst_mac_mode()) + { + case OstProto::Mac::e_mm_fixed: + qToBigEndian((quint64) d.mac().dst_mac(), scratch); + break; + case OstProto::Mac::e_mm_inc: + u = (n % d.mac().dst_mac_count()) * d.mac().dst_mac_step(); + qToBigEndian((quint64) d.mac().dst_mac() + u, scratch); + break; + case OstProto::Mac::e_mm_dec: + u = (n % d.mac().dst_mac_count()) * d.mac().dst_mac_step(); + qToBigEndian((quint64) d.mac().dst_mac() - u, scratch); + break; + default: + qWarning("Unhandled dstMac_mode %d", d.mac().dst_mac_mode()); + } memcpy((buf + len), scratch + 2, 6); len += 6; - qToBigEndian((quint64) d.mac().src_mac(), scratch); - memcpy((buf + len), &scratch + 2, 6); + + switch (d.mac().src_mac_mode()) + { + case OstProto::Mac::e_mm_fixed: + qToBigEndian((quint64) d.mac().src_mac(), scratch); + break; + case OstProto::Mac::e_mm_inc: + u = (n % d.mac().src_mac_count()) * d.mac().src_mac_step(); + qToBigEndian((quint64) d.mac().src_mac() + u, scratch); + break; + case OstProto::Mac::e_mm_dec: + u = (n % d.mac().src_mac_count()) * d.mac().src_mac_step(); + qToBigEndian((quint64) d.mac().src_mac() - u, scratch); + break; + default: + qWarning("Unhandled srcMac_mode %d", d.mac().src_mac_mode()); + } + memcpy((buf + len), scratch + 2, 6); len += 6; + + // Frame Type - Part 1 (pre VLAN info) + switch(d.core().ft()) + { + case OstProto::StreamCore::e_ft_none: + case OstProto::StreamCore::e_ft_eth_2: + break; + case OstProto::StreamCore::e_ft_802_3_raw: + qToBigEndian((quint16) pktLen, buf+len); + len += 2; + break; + case OstProto::StreamCore::e_ft_802_3_llc: + qToBigEndian((quint16) pktLen, buf+len); + len += 2; + buf[len+0] = (quint8) d.llc().dsap(); + buf[len+1] = (quint8) d.llc().ssap(); + buf[len+2] = (quint8) d.llc().ctl(); + len +=3; + break; + case OstProto::StreamCore::e_ft_snap: + qToBigEndian((quint16) pktLen, buf+len); + len += 2; + buf[len+0] = (quint8) d.llc().dsap(); + buf[len+1] = (quint8) d.llc().ssap(); + buf[len+2] = (quint8) d.llc().ctl(); + len +=3; + qToBigEndian((quint32) d.snap().oui(), scratch); + memcpy((buf + len), scratch + 2, 3); + len += 3; + break; + default: + qWarning("Unhandled frame type %d\n", d.core().ft()); + } + + // VLAN + if (d.vlan().is_svlan_tagged()) + { + if (d.vlan().is_stpid_override()) + qToBigEndian((quint16) d.vlan().stpid(), buf+len); + else + qToBigEndian((quint16) 0x88a8, buf+len); + len += 2 ; + + qToBigEndian((quint16) d.vlan().svlan_tag(), buf+len); + len += 2 ; + } + + if (d.vlan().is_cvlan_tagged()) + { + if (d.vlan().is_ctpid_override()) + qToBigEndian((quint16) d.vlan().ctpid(), buf+len); + else + qToBigEndian((quint16) 0x8100, buf+len); + len += 2 ; + + qToBigEndian((quint16) d.vlan().cvlan_tag(), buf+len); + len += 2 ; + } + + // Frame Type - Part 2 (post VLAN info) switch(d.core().ft()) { case OstProto::StreamCore::e_ft_none: @@ -34,23 +181,9 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize) len += 2; break; case OstProto::StreamCore::e_ft_802_3_raw: - qToBigEndian((quint16) pktLen, buf+len); - len += 2; - break; case OstProto::StreamCore::e_ft_802_3_llc: - buf[len+0] = (quint8) d.llc().dsap(); - buf[len+1] = (quint8) d.llc().ssap(); - buf[len+2] = (quint8) d.llc().ctl(); - len +=3; break; case OstProto::StreamCore::e_ft_snap: - buf[len+0] = (quint8) d.llc().dsap(); - buf[len+1] = (quint8) d.llc().ssap(); - buf[len+2] = (quint8) d.llc().ctl(); - len +=3; - qToBigEndian((quint32) d.snap().oui(), scratch); - memcpy((buf + len), scratch + 2, 3); - len += 3; qToBigEndian((quint16) d.eth2().type(), buf+len); len += 2; break; @@ -58,32 +191,107 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize) qWarning("Unhandled frame type %d\n", d.core().ft()); } + // L3 switch (d.core().l3_proto()) { case OstProto::StreamCore::e_l3_none: break; case OstProto::StreamCore::e_l3_ip: + { + quint32 subnet, host; + int ipOfs = len; + buf[len+0] = (quint8) (d.ip().ver_hdrlen()); buf[len+1] = (quint8) (d.ip().tos()); len += 2; - qToBigEndian((quint16) d.ip().tot_len(), buf+len); + + if (d.ip().is_override_totlen()) + qToBigEndian((quint16) d.ip().tot_len(), buf+len); + else + qToBigEndian((quint16) (pktLen - ipOfs), buf+len); len += 2; + qToBigEndian((quint16) d.ip().id(), buf+len); len += 2; + qToBigEndian((quint16) (( (d.ip().flags() & 0x3) << 13) | (d.ip().frag_ofs() & 0x1FFF)), buf+len); len += 2; + buf[len+0] = (quint8) (d.ip().ttl()); buf[len+1] = (quint8) (d.ip().proto()); len += 2; - qToBigEndian((quint16) d.ip().cksum(), buf+len); + + // cksum calculated after filling in the rest + qToBigEndian((quint16) 0, buf+len); len += 2; + // TODO(HI): Use IpMode - don't assume fixed - qToBigEndian((quint32) d.ip().src_ip(), buf+len); + switch(d.ip().src_ip_mode()) + { + case OstProto::Ip::e_im_fixed: + qToBigEndian((quint32) d.ip().src_ip(), buf+len); + break; + case OstProto::Ip::e_im_inc_host: + u = n % d.ip().src_ip_count(); + subnet = d.ip().src_ip() & d.ip().src_ip_mask(); + host = (((d.ip().src_ip() & ~d.ip().src_ip_mask()) + u) & + ~d.ip().src_ip_mask()); + qToBigEndian((quint32) (subnet | host), buf+len); + break; + case OstProto::Ip::e_im_dec_host: + u = n % d.ip().src_ip_count(); + subnet = d.ip().src_ip() & d.ip().src_ip_mask(); + host = (((d.ip().src_ip() & ~d.ip().src_ip_mask()) - u) & + ~d.ip().src_ip_mask()); + qToBigEndian((quint32) (subnet | host), buf+len); + break; + case OstProto::Ip::e_im_random_host: + subnet = d.ip().src_ip() & d.ip().src_ip_mask(); + host = (qrand() & ~d.ip().src_ip_mask()); + qToBigEndian((quint32) (subnet | host), buf+len); + break; + default: + qWarning("Unhandled src_ip_mode = %d", d.ip().src_ip_mode()); + } len +=4; - qToBigEndian((quint32) d.ip().dst_ip(), buf+len); + + switch(d.ip().dst_ip_mode()) + { + case OstProto::Ip::e_im_fixed: + qToBigEndian((quint32) d.ip().dst_ip(), buf+len); + break; + case OstProto::Ip::e_im_inc_host: + u = n % d.ip().dst_ip_count(); + subnet = d.ip().dst_ip() & d.ip().dst_ip_mask(); + host = (((d.ip().dst_ip() & ~d.ip().dst_ip_mask()) + u) & + ~d.ip().dst_ip_mask()); + qToBigEndian((quint32) (subnet | host), buf+len); + break; + case OstProto::Ip::e_im_dec_host: + u = n % d.ip().dst_ip_count(); + subnet = d.ip().dst_ip() & d.ip().dst_ip_mask(); + host = (((d.ip().dst_ip() & ~d.ip().dst_ip_mask()) - u) & + ~d.ip().dst_ip_mask()); + qToBigEndian((quint32) (subnet | host), buf+len); + break; + case OstProto::Ip::e_im_random_host: + subnet = d.ip().dst_ip() & d.ip().dst_ip_mask(); + host = (qrand() & ~d.ip().dst_ip_mask()); + qToBigEndian((quint32) (subnet | host), buf+len); + break; + default: + qWarning("Unhandled dst_ip_mode = %d", d.ip().dst_ip_mode()); + } len +=4; + + // Calculate and fill in cksum (unless overridden) + if (d.ip().is_override_cksum()) + qToBigEndian((quint16) d.ip().cksum(), buf+ipOfs+10); + else + *((quint16*)(buf + ipOfs + 10)) = ipv4Cksum(buf + ipOfs, len-ipOfs); break; + } case OstProto::StreamCore::e_l3_arp: // TODO(LOW) break; @@ -96,34 +304,59 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize) case OstProto::StreamCore::e_l4_none: break; case OstProto::StreamCore::e_l4_tcp: + { qToBigEndian((quint16) d.tcp().src_port(), buf+len); len += 2; qToBigEndian((quint16) d.tcp().dst_port(), buf+len); len += 2; - qToBigEndian((quint16) d.tcp().seq_num(), buf+len); - len += 2; - qToBigEndian((quint16) d.tcp().ack_num(), buf+len); - len += 2; - buf[len+0] = (quint8) d.tcp().hdrlen_rsvd(); + + qToBigEndian((quint32) d.tcp().seq_num(), buf+len); + len += 4; + qToBigEndian((quint32) d.tcp().ack_num(), buf+len); + len += 4; + + if (d.tcp().is_override_hdrlen()) + buf[len+0] = (quint8) d.tcp().hdrlen_rsvd(); + else + buf[len+0] = (quint8) 0x50; // FIXME(LOW) buf[len+1] = (quint8) d.tcp().flags(); len += 2; + qToBigEndian((quint16) d.tcp().window(), buf+len); len +=2; - qToBigEndian((quint16) d.tcp().cksum(), buf+len); + + if (d.tcp().is_override_cksum()) + qToBigEndian((quint16) d.tcp().cksum(), buf+len); + else + qToBigEndian((quint16) 0, buf+len); // FIXME(HI) len +=2; + qToBigEndian((quint16) d.tcp().urg_ptr(), buf+len); len +=2; break; + } case OstProto::StreamCore::e_l4_udp: + { + int udpLen = pktLen - len; + qToBigEndian((quint16) d.udp().src_port(), buf+len); len += 2; qToBigEndian((quint16) d.udp().dst_port(), buf+len); len += 2; - qToBigEndian((quint16) d.udp().totlen(), buf+len); + + if (d.udp().is_override_totlen()) + qToBigEndian((quint16) d.udp().totlen(), buf+len); + else + qToBigEndian((quint16) udpLen, buf+len); len +=2; - qToBigEndian((quint16) d.udp().cksum(), buf+len); + + if (d.udp().is_override_cksum()) + qToBigEndian((quint16) d.udp().cksum(), buf+len); + else + qToBigEndian((quint16) 0, buf+len); // FIXME(HI) len +=2; break; + } case OstProto::StreamCore::e_l4_icmp: // TODO(LOW) break; @@ -149,6 +382,7 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize) return pktLen; } + // // ------------------ PortInfo -------------------- // @@ -166,6 +400,13 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) dev->name, pcap_geterr(devHandle)); } +#if 0 + if (pcap_setdirection(devHandle, PCAP_D_IN)<0) + { + qDebug("[%s] Error setting direction inbound only\n", dev->name); + } +#endif + /* By default, put the interface in statistics mode */ if (pcap_setmode(devHandle, MODE_STAT)<0) { @@ -179,10 +420,14 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) d.set_is_oper_up(true); // FIXME(MED):check d.set_is_exclusive_control(false); // FIXME(MED): check + memset((void*) &stats, 0, sizeof(stats)); resetStats(); // We'll create sendqueue later when required sendQueue = NULL; + pcapExtra.sendQueueNumPkts = 0; + pcapExtra.txPkts = 0; + pcapExtra.txBytes = 0; isSendQueueDirty=true; // Start the monitor thread @@ -201,21 +446,47 @@ void PortInfo::update() // TODO(LOW): calculate sendqueue size sendQueue = pcap_sendqueue_alloc(1*MB); + pcapExtra.sendQueueNumPkts = 0; + + // First sort the streams by ordinalValue + qSort(streamList); for (int i = 0; i < streamList.size(); i++) { - // FIXME(HI): Testing only - //if (streamList[i].d.core().is_enabled()) + if (streamList[i].d.core().is_enabled()) { - pktHdr.len = streamList[i].makePacket(pktBuf, sizeof(pktBuf)); - pktHdr.caplen = pktHdr.len; - pktHdr.ts.tv_sec = pktHdr.ts.tv_usec = 0; // FIXME(HI) + int numPackets, numBursts; - if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr, - (u_char*) pktBuf)) + if (streamList[i].d.control().unit() == + OstProto::StreamControl::e_su_bursts) { - qDebug("[port %d] sendqueue_queue() failed for streamidx %d\n", - id(), i); + numBursts = streamList[i].d.control().num_bursts(); + numPackets = streamList[i].d.control().packets_per_burst(); + } + else + { + numBursts = 1; + numPackets = streamList[i].d.control().num_packets(); + } + + for (int j = 0; j < numBursts; j++) + { + for (int k = 0; k < numPackets; k++) + { + pktHdr.len = streamList[i].makePacket( + pktBuf, sizeof(pktBuf), j * numPackets + k); + pktHdr.caplen = pktHdr.len; + pktHdr.ts.tv_sec = pktHdr.ts.tv_usec = 0; // FIXME(HI) + + if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr, + (u_char*) pktBuf)) + { + qDebug("[port %d] sendqueue_queue() failed for " + "streamidx %d\n", id(), i); + } + else + pcapExtra.sendQueueNumPkts++; + } } } } @@ -225,14 +496,29 @@ void PortInfo::update() void PortInfo::startTransmit() { - int n; + uint bytes; // TODO(HI): Stream Mode - one pass/continuous - n = pcap_sendqueue_transmit(devHandle, sendQueue, false); - if (n == 0) - qDebug("port %d: send error %s\n", id(), pcap_geterr(devHandle)); + bytes = pcap_sendqueue_transmit(devHandle, sendQueue, false); + if (bytes < sendQueue->len) + { + qDebug("port %d: sent (%d/%d) error %s. TxStats may be inconsistent", + id(), bytes, sendQueue->len, pcap_geterr(devHandle)); + //! \TODO parse sendqueue using 'bytes' to get actual pkts sent + pcapExtra.txPkts += pcapExtra.sendQueueNumPkts; + pcapExtra.txBytes += bytes; + } else - qDebug("port %d: sent %d bytes\n", id(), n); + { + qDebug("port %d: sent (%d/%d) bytes\n", id(), bytes, sendQueue->len); + pcapExtra.txPkts += pcapExtra.sendQueueNumPkts; + pcapExtra.txBytes += bytes; + } + + // pcap_sendqueue_transmit() returned 'bytes' includes size of pcap_pkthdr + // - adjust for it + pcapExtra.txBytes -= pcapExtra.sendQueueNumPkts * sizeof(pcap_pkthdr); + } void PortInfo::stopTransmit() @@ -241,7 +527,7 @@ void PortInfo::stopTransmit() void PortInfo::resetStats() { - memset((void*) &stats, 0, sizeof(stats)); + memcpy((void*) &epochStats, (void*) &stats, sizeof(stats)); } // @@ -251,21 +537,57 @@ void PortInfo::resetStats() PortInfo::PortMonitor::PortMonitor(PortInfo *port) { this->port = port; +#ifdef Q_OS_WIN32 + { + int sz = sizeof(PACKET_OID_DATA) + sizeof(quint64) + 4; + //oidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, + //sizeof(PACKET_OID_DATA) + sizeof(quint64) - 1); + oidData = (PPACKET_OID_DATA) malloc(sz); + if (oidData) + { + memset(oidData, 0, sz); + oidData->Length=sizeof(quint64); + } + else + qFatal("failed to alloc oidData"); + } +#endif } void PortInfo::PortMonitor::callback(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data) { + uint usec; PortInfo *port = (PortInfo*) state; + quint64 pkts; quint64 bytes; - pkts = *((quint64*)(pkt_data + 0)); - bytes = *((quint64*)(pkt_data + 8)); + // Update RxStats and RxRates using PCAP data + pkts = *((quint64*)(pkt_data + 0)); + bytes = *((quint64*)(pkt_data + 8)); + + // Note: PCAP reported bytes includes ETH_FRAME_HDR_SIZE - adjust for it + bytes -= pkts * ETH_FRAME_HDR_SIZE; + + usec = (header->ts.tv_sec - port->lastTs.tv_sec) * 1000000 + + (header->ts.tv_usec - port->lastTs.tv_usec); + port->stats.rxPps = (pkts * 1000000) / usec; + port->stats.rxBps = (bytes * 1000000) / usec; port->stats.rxPkts += pkts; port->stats.rxBytes += bytes; + // Update TxStats from PcapExtra + port->stats.txPkts = port->pcapExtra.txPkts; + port->stats.txBytes = port->pcapExtra.txBytes; + + //! \TODO TxRates + + // Store curr timestamp as last timestamp + port->lastTs.tv_sec = header->ts.tv_sec; + port->lastTs.tv_usec = header->ts.tv_usec; + #if 0 for (int i=0; i < 16; i++) { @@ -276,6 +598,26 @@ void PortInfo::PortMonitor::callback(u_char *state, qDebug("[%d: pkts : %llu]\n", port->id(), port->stats.rxPkts); qDebug("[%d: bytes: %llu]\n", port->id(), port->stats.rxBytes); #endif + + // Retreive NIC stats +#ifdef Q_OS_WIN32 + port->monitor.oidData->Oid = OID_GEN_RCV_OK; + if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData)) + { + if (port->monitor.oidData->Length <= sizeof(port->stats.txPkts)) + memcpy((void*)&port->stats.rxPktsNic, + (void*)port->monitor.oidData->Data, + port->monitor.oidData->Length); + } + port->monitor.oidData->Oid = OID_GEN_XMIT_OK; + if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData)) + { + if (port->monitor.oidData->Length <= sizeof(port->stats.txPkts)) + memcpy((void*)&port->stats.txPktsNic, + (void*)port->monitor.oidData->Data, + port->monitor.oidData->Length); + } +#endif } void PortInfo::PortMonitor::run() @@ -687,7 +1029,7 @@ const ::OstProto::PortIdList* request, ::OstProto::PortStatsList* response, ::google::protobuf::Closure* done) { - qDebug("In %s", __PRETTY_FUNCTION__); + //qDebug("In %s", __PRETTY_FUNCTION__); for (int i=0; i < request->port_id_size(); i++) { @@ -701,13 +1043,25 @@ const ::OstProto::PortIdList* request, s = response->add_port_stats(); s->mutable_port_id()->set_id(request->port_id(i).id()); - s->set_rx_pkts(portInfo[portidx]->stats.rxPkts); - s->set_rx_bytes(portInfo[portidx]->stats.rxBytes); + s->set_rx_pkts(portInfo[portidx]->stats.rxPkts - + portInfo[portidx]->epochStats.rxPkts); + s->set_rx_bytes(portInfo[portidx]->stats.rxBytes - + portInfo[portidx]->epochStats.rxBytes); + s->set_rx_pkts_nic(portInfo[portidx]->stats.rxPktsNic - + portInfo[portidx]->epochStats.rxPktsNic); + s->set_rx_bytes_nic(portInfo[portidx]->stats.rxBytesNic - + portInfo[portidx]->epochStats.rxBytesNic); s->set_rx_pps(portInfo[portidx]->stats.rxPps); s->set_rx_bps(portInfo[portidx]->stats.rxBps); - s->set_tx_pkts(portInfo[portidx]->stats.txPkts); - s->set_tx_bytes(portInfo[portidx]->stats.txBytes); + s->set_tx_pkts(portInfo[portidx]->stats.txPkts - + portInfo[portidx]->epochStats.txPkts); + s->set_tx_bytes(portInfo[portidx]->stats.txBytes - + portInfo[portidx]->epochStats.txBytes); + s->set_tx_pkts_nic(portInfo[portidx]->stats.txPktsNic - + portInfo[portidx]->epochStats.txPktsNic); + s->set_tx_bytes_nic(portInfo[portidx]->stats.txBytesNic - + portInfo[portidx]->epochStats.txBytesNic); s->set_tx_pps(portInfo[portidx]->stats.txPps); s->set_tx_bps(portInfo[portidx]->stats.txBps); } diff --git a/server/myservice.h b/server/myservice.h index 69e2f71..ecb474e 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -16,9 +16,16 @@ #include "../rpc/pbhelper.h" +#ifdef Q_OS_WIN32 +#include +#endif + #define MAX_PKT_HDR_SIZE 1536 #define MAX_STREAM_NAME_SIZE 64 +//! 7 byte Preamble + 1 byte SFD + 4 byte FCS +#define ETH_FRAME_HDR_SIZE 12 + class MyService; class StreamInfo @@ -29,7 +36,13 @@ class StreamInfo OstProto::Stream d; StreamInfo() { PbHelper pbh; pbh.ForceSetSingularDefault(&d); } - int StreamInfo::makePacket(uchar *buf, int bufMaxSize); + + //quint16 ipv4Cksum(quint16 ipHdrLen, quint16 buff[]); + quint16 ipv4Cksum(uchar *buf, int len); + int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n); +public: + bool operator < (const StreamInfo &s) const + { return(d.core().ordinal() < s.d.core().ordinal()); } }; @@ -41,7 +54,10 @@ class PortInfo { friend class PortInfo; - PortInfo *port; + PortInfo *port; +#ifdef Q_OS_WIN32 + PPACKET_OID_DATA oidData; +#endif public: PortMonitor(PortInfo *port); static void callback(u_char *state, @@ -51,26 +67,47 @@ class PortInfo OstProto::Port d; - pcap_if_t *dev; - pcap_t *devHandle; - pcap_send_queue *sendQueue; - bool isSendQueueDirty; - PortMonitor monitor; - struct PortStats { quint64 rxPkts; quint64 rxBytes; + quint64 rxPktsNic; + quint64 rxBytesNic; quint64 rxPps; quint64 rxBps; quint64 txPkts; quint64 txBytes; + quint64 txPktsNic; + quint64 txBytesNic; quint64 txPps; quint64 txBps; }; + //! \todo Need lock for stats access/update + + //! Stuff we need to maintain since PCAP doesn't as of now. As and when + // PCAP supports it, we'll remove from here + struct PcapExtra + { + //! pcap_sendqueue_transmit() only returns 'bytes' sent + uint sendQueueNumPkts; + + //! PCAP doesn't do any tx stats + quint64 txPkts; + quint64 txBytes; + }; + + pcap_if_t *dev; + pcap_t *devHandle; + pcap_send_queue *sendQueue; + bool isSendQueueDirty; + PcapExtra pcapExtra; + PortMonitor monitor; + + struct PortStats epochStats; struct PortStats stats; + struct timeval lastTs; //! used for Rate Stats calculations /*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */ QList streamList; From bfc0e8d4c89a80317d93451bdeda1cf1e79f5279 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 5 Oct 2008 17:07:33 +0000 Subject: [PATCH 11/98] Tcp/Udp checksums done. Frame Length Modes done. Data Pattern Modes done. Some minor fixes/enhancements in streamconfigdialog. Added a "Edit Stream" action in StreamList context menu --- client/portgroup.cpp | 1 + client/portstatsmodel.cpp | 2 +- client/portswindow.cpp | 51 ++++-- client/portswindow.h | 1 + client/portswindow.ui | 8 + client/stream.h | 6 +- client/streamconfigdialog.cpp | 196 ++++++++++++++++------ client/streamconfigdialog.h | 5 +- client/streamconfigdialog.ui | 81 ++++++---- common/protocol.proto | 10 +- server/myservice.cpp | 297 ++++++++++++++++++++++++---------- server/myservice.h | 12 +- 12 files changed, 478 insertions(+), 192 deletions(-) diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 686b436..4630c72 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -159,6 +159,7 @@ void PortGroup::when_configApply(int portIndex, uint *cookie) case 3: qDebug("apply completed"); + mPorts[portIndex].when_syncComplete(); delete cookie; break; diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index b3fae30..d554687 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -12,7 +12,7 @@ PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent) timer = new QTimer(); connect(timer, SIGNAL(timeout()), this, SLOT(updateStats())); - timer->start(5000); + timer->start(2000); } int PortStatsModel::rowCount(const QModelIndex &parent) const diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 645bd1b..27dec05 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -23,6 +23,7 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) tvPortList->addAction(actionDisconnect_Port_Group); tvStreamList->addAction(actionNew_Stream); + tvStreamList->addAction(actionEdit_Stream); tvStreamList->addAction(actionDelete_Stream); tvStreamList->setModel(plm->getStreamModel()); @@ -32,10 +33,12 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(when_portModel_dataChanged(const QModelIndex&, const QModelIndex&))); + connect( tvPortList->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(when_portView_currentChanged(const QModelIndex&, const QModelIndex&))); + connect( tvStreamList->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(when_streamView_currentChanged(const QModelIndex&, @@ -43,13 +46,16 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) connect( tvStreamList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(when_streamView_selectionChanged())); + +#if 0 connect( tvPortList->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&))); +#endif - // Initially we don't have any ports - so trigger selection of - // portgroup detail page + // Initially we don't have any ports/streams - so send signal triggers when_portView_currentChanged(QModelIndex(), QModelIndex()); + when_streamView_currentChanged(QModelIndex(), QModelIndex()); } PortsWindow::~PortsWindow() @@ -66,11 +72,6 @@ void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) qDebug("%s: invalid index", __FUNCTION__); return; } -#if 0 // CleanedUp! - // FIXME(MED): This way of passing params must be changed - scd = new StreamConfigDialog(plm->getStreamModel()->currentPortStreamList(), - (uint) index.row(), this); -#endif scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()), index.row(), this); qDebug("stream list activated\n"); @@ -81,7 +82,9 @@ void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) void PortsWindow::when_portView_currentChanged(const QModelIndex& current, const QModelIndex& previous) { + plm->getStreamModel()->setCurrentPortIndex(current); updatePortViewActions(current); + updateStreamViewActions(); if (!current.isValid()) { @@ -143,16 +146,32 @@ void PortsWindow::updateStreamViewActions(const QModelIndex& current) void PortsWindow::updateStreamViewActions() { - if (tvStreamList->selectionModel()->hasSelection()) + // For some reason hasSelection() returns true even if selection size is 0 + // so additional check for size introduced + if (tvStreamList->selectionModel()->hasSelection() && + (tvStreamList->selectionModel()->selection().size() > 0)) { qDebug("Has selection %d", tvStreamList->selectionModel()->selection().size()); - // If more than one non-contiguous ranges selected, disable "New" + + // If more than one non-contiguous ranges selected, + // disable "New" and "Edit" if (tvStreamList->selectionModel()->selection().size() > 1) + { actionNew_Stream->setDisabled(true); + actionEdit_Stream->setDisabled(true); + } else + { actionNew_Stream->setEnabled(true); + // Enable "Edit" only if the single range has a single row + if (tvStreamList->selectionModel()->selection().at(0).height() > 1) + actionEdit_Stream->setDisabled(true); + else + actionEdit_Stream->setEnabled(true); + } + // Delete is always enabled as long as we have a selection actionDelete_Stream->setEnabled(true); } @@ -160,6 +179,7 @@ void PortsWindow::updateStreamViewActions() { qDebug("No selection"); actionNew_Stream->setEnabled(true); + actionEdit_Stream->setDisabled(true); actionDelete_Stream->setDisabled(true); } } @@ -346,6 +366,19 @@ void PortsWindow::on_actionNew_Stream_triggered() plm->getStreamModel()->insertRows(row, count); } +void PortsWindow::on_actionEdit_Stream_triggered() +{ + qDebug("Edit Stream Action"); + + // Ensure we have only one range selected which contains only one row + if ((tvStreamList->selectionModel()->selection().size() == 1) && + (tvStreamList->selectionModel()->selection().at(0).height() == 1)) + { + on_tvStreamList_activated(tvStreamList->selectionModel()-> + selection().at(0).topLeft()); + } +} + void PortsWindow::on_actionDelete_Stream_triggered() { qDebug("Delete Stream Action"); diff --git a/client/portswindow.h b/client/portswindow.h index 2a26c2b..a5bc562 100644 --- a/client/portswindow.h +++ b/client/portswindow.h @@ -49,6 +49,7 @@ private slots: void on_actionDisconnect_Port_Group_triggered(); void on_actionNew_Stream_triggered(); + void on_actionEdit_Stream_triggered(); void on_actionDelete_Stream_triggered(); }; diff --git a/client/portswindow.ui b/client/portswindow.ui index 04349d2..99a32af 100644 --- a/client/portswindow.ui +++ b/client/portswindow.ui @@ -206,6 +206,14 @@ Delete Stream + + + :/icons/stream_edit.png + + + Edit Stream + + diff --git a/client/stream.h b/client/stream.h index 42f74ff..6e41702 100644 --- a/client/stream.h +++ b/client/stream.h @@ -883,9 +883,9 @@ public: }; enum DataPatternMode { - e_dp_fixed, - e_dp_inc, - e_dp_dec, + e_dp_fixed_word, + e_dp_inc_byte, + e_dp_dec_byte, e_dp_random }; diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index cef9771..7ee59f7 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -12,6 +12,8 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, { setupUi(this); setupUiExtra(); + + // setupUi // Time to play match the signals and slots! connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); @@ -28,6 +30,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFtNone, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool))); connect(rbFtNone, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool))); + // Enable/Disable L3 Protocol Choices for FT None + connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); + // Show/Hide FrameType related inputs for FT Ethernet2 connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool))); connect(rbFtEthernet2, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool))); @@ -40,6 +47,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool))); connect(rbFtEthernet2, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool))); + // Enable/Disable L3 Protocol Choices for FT Ethernet2 + connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); + connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); + // Show/Hide FrameType related inputs for FT 802.3 Raw connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool))); connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool))); @@ -52,6 +64,14 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool))); connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool))); + // Force L3 = None if FT = 802.3 Raw + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); + + // Enable/Disable L3 Protocol Choices for FT 802Dot3Raw + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool))); + connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); + // Show/Hide FrameType related inputs for FT 802.3 LLC connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblDsap, SLOT(setVisible(bool))); connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leDsap, SLOT(setVisible(bool))); @@ -64,6 +84,14 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool))); connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool))); + // Force L3 = None if FT = 802.3 LLC (to ensure a valid L3 is selected) + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); + + // Enable/Disable L3 Protocol Choices for FT 802Dot3Llc + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); + connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); + // Show/Hide FrameType related inputs for FT 802.3 LLC SNAP connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblDsap, SLOT(setVisible(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leDsap, SLOT(setVisible(bool))); @@ -76,6 +104,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool))); + // Enable/Disable L3 Protocol Choices for FT 802.3 LLC SNAP + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); + connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); + // Enable/Disable FrameType related inputs for FT 802.3 LLC SNAP connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblDsap, SLOT(setDisabled(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leDsap, SLOT(setDisabled(bool))); @@ -90,7 +123,6 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbL3None, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool))); connect(rbL3None, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool))); connect(rbL3None, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool))); - connect(rbL3None, SIGNAL(toggled(bool)), rbL4Other, SLOT(setDisabled(bool))); // Force L4 Protocol = None if L3 Protocol is set to None connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool))); @@ -101,7 +133,6 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setEnabled(bool))); - connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Other, SLOT(setEnabled(bool))); // Enable/Disable L4 Protocol Choices for L3 Protocol ARP connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); @@ -109,15 +140,20 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool))); connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool))); connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool))); - connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Other, SLOT(setDisabled(bool))); // Force L4 Protocol = None if L3 Protocol is set to ARP connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool))); - // Init with FT=Eth2 to trigger signals; actual value will be - // initialized by LoadCurrentStream() + //TODO: remove if not needed +#if 0 + // This set of 'clicks' is a hack to trigger signals at dialog creation + // time so that a coherent 'set' is initialized + // Actual stream values will be initialized by LoadCurrentStream() + rbL3Ipv4->click(); + rbL3None->click(); rbFtEthernet2->click(); rbFtNone->click(); +#endif //mpStreamList = streamList; mCurrentStreamIndex = streamIndex; @@ -148,7 +184,21 @@ void StreamConfigDialog::setupUiExtra() QRegExp reHex4B("[0-9,a-f,A-F]{1,8}"); QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); - // Setup default stuff that cannot be done in designer + // ---- Setup default stuff that cannot be done in designer ---- + + // Since the dialog defaults are FT = None, L3 = None, L4 = None; + // hide associated input fields since it can't be done in Designer + lblDsap->setHidden(true); + leDsap->setHidden(true); + lblSsap->setHidden(true); + leSsap->setHidden(true); + lblControl->setHidden(true); + leControl->setHidden(true); + lblOui->setHidden(true); + leOui->setHidden(true); + lblType->setHidden(true); + leType->setHidden(true); + twProto->setTabEnabled(2, FALSE); twProto->setTabEnabled(3, FALSE); @@ -189,17 +239,73 @@ StreamConfigDialog::~StreamConfigDialog() delete mpPacketModel; } +void StreamConfigDialog::on_cmbPatternMode_currentIndexChanged(QString mode) +{ + if (mode == "Fixed Word") + { + lePattern->setEnabled(true); + } + else if (mode == "Increment Byte") + { + lePattern->setDisabled(true); + } + else if (mode == "Decrement Byte") + { + lePattern->setDisabled(true); + } + if (mode == "Random") + { + lePattern->setDisabled(true); + } + else + { + qWarning("Unhandled/Unknown PatternMode = %s", mode.toAscii().data()); + } +} +void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode) +{ + if (mode == "Fixed") + { + lePktLen->setEnabled(true); + lePktLenMin->setDisabled(true); + lePktLenMax->setDisabled(true); + } + else if (mode == "Increment") + { + lePktLen->setDisabled(true); + lePktLenMin->setEnabled(true); + lePktLenMax->setEnabled(true); + } + else if (mode == "Decrement") + { + lePktLen->setDisabled(true); + lePktLenMin->setEnabled(true); + lePktLenMax->setEnabled(true); + } + else if (mode == "Random") + { + lePktLen->setDisabled(true); + lePktLenMin->setEnabled(true); + lePktLenMax->setEnabled(true); + } + else + { + qWarning("Unhandled/Unknown PktLenMode = %s", mode.toAscii().data()); + } +} + + void StreamConfigDialog::on_cmbDstMacMode_currentIndexChanged(QString mode) { if (mode == "Fixed") { - leDstMacCount->setEnabled(FALSE); - leDstMacStep->setEnabled(FALSE); + leDstMacCount->setEnabled(false); + leDstMacStep->setEnabled(false); } else { - leDstMacCount->setEnabled(TRUE); - leDstMacStep->setEnabled(TRUE); + leDstMacCount->setEnabled(true); + leDstMacStep->setEnabled(true); } } @@ -207,13 +313,41 @@ void StreamConfigDialog::on_cmbSrcMacMode_currentIndexChanged(QString mode) { if (mode == "Fixed") { - leSrcMacCount->setEnabled(FALSE); - leSrcMacStep->setEnabled(FALSE); + leSrcMacCount->setEnabled(false); + leSrcMacStep->setEnabled(false); } else { - leSrcMacCount->setEnabled(TRUE); - leSrcMacStep->setEnabled(TRUE); + leSrcMacCount->setEnabled(true); + leSrcMacStep->setEnabled(true); + } +} + +void StreamConfigDialog::on_cmbIpSrcAddrMode_currentIndexChanged(QString mode) +{ + if (mode == "Fixed") + { + leIpSrcAddrCount->setDisabled(true); + leIpSrcAddrMask->setDisabled(true); + } + else + { + leIpSrcAddrCount->setEnabled(true); + leIpSrcAddrMask->setEnabled(true); + } +} + +void StreamConfigDialog::on_cmbIpDstAddrMode_currentIndexChanged(QString mode) +{ + if (mode == "Fixed") + { + leIpDstAddrCount->setDisabled(true); + leIpDstAddrMask->setDisabled(true); + } + else + { + leIpDstAddrCount->setEnabled(true); + leIpDstAddrMask->setEnabled(true); } } @@ -371,14 +505,6 @@ void StreamConfigDialog::on_rbL4Udp_toggled(bool checked) } } -void StreamConfigDialog::on_rbL4Other_toggled(bool checked) -{ - if (checked) - leIpProto->setEnabled(true); - else - leIpProto->setEnabled(false); -} - void StreamConfigDialog::update_NumPacketsAndNumBursts() { if (rbSendPackets->isChecked() && rbModeFixed->isChecked()) @@ -512,32 +638,6 @@ void StreamConfigDialog::LoadCurrentStream() qDebug("%s: unknown l4 Protocol %d", __FUNCTION__, pStream->l4Proto()); } -// PB (not needed anymore?) -#if 0 - // Check for specific supported protocols first ... - if (pStream->eth2()->type() == ETH_TYP_IP) - rbL3Ipv4->setChecked(TRUE); - else if (pStream->eth2()->type() == ETH_TYP_ARP) - rbL3Arp->setChecked(TRUE); - - // ... then for None/Other - rbL3None->setChecked((pStream->proto.protoMask & PM_L3_PROTO_NONE) > 0); - rbL3Other->setChecked((pStream->proto.protoMask & PM_L3_PROTO_OTHER) > 0); - - // Check for specific supported protocols first ... - if (pStream->proto.ipProto == IP_PROTO_ICMP) - rbL4Icmp->setChecked(TRUE); - else if (pStream->proto.ipProto == IP_PROTO_IGMP) - rbL4Igmp->setChecked(TRUE); - else if (pStream->proto.ipProto == IP_PROTO_TCP) - rbL4Tcp->setChecked(TRUE); - else if (pStream->proto.ipProto == IP_PROTO_UDP) - rbL4Udp->setChecked(TRUE); - - // ... then for None/Other - rbL4None->setChecked((pStream->proto.protoMask & PM_L4_PROTO_NONE) > 0); - rbL4Other->setChecked((pStream->proto.protoMask & PM_L4_PROTO_OTHER) > 0); -#endif } // L2 diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index f95205d..a8fe510 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -39,8 +39,12 @@ private: void StoreCurrentStream(); private slots: + void on_cmbPatternMode_currentIndexChanged(QString mode); + void on_cmbPktLenMode_currentIndexChanged(QString mode); void on_cmbDstMacMode_currentIndexChanged(QString mode); void on_cmbSrcMacMode_currentIndexChanged(QString mode); + void on_cmbIpSrcAddrMode_currentIndexChanged(QString mode); + void on_cmbIpDstAddrMode_currentIndexChanged(QString mode); void on_pbPrev_clicked(); void on_pbNext_clicked(); @@ -57,7 +61,6 @@ private slots: void on_rbL4Igmp_toggled(bool checked); void on_rbL4Tcp_toggled(bool checked); void on_rbL4Udp_toggled(bool checked); - void on_rbL4Other_toggled(bool checked); void update_NumPacketsAndNumBursts(); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index f3ed791..b94e107 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,7 +8,7 @@ 0 0 - 554 + 534 521 @@ -63,17 +63,17 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - Fixed + Fixed Word - Increment + Increment Byte - Decrement + Decrement Byte @@ -141,6 +141,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + false + 64 @@ -174,6 +177,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + false + 64 @@ -373,6 +379,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + false + IPv4 @@ -383,18 +392,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - ARP - - - - - false - Other + ARP @@ -420,7 +422,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - true + false ICMP @@ -430,7 +432,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - true + false IGMP @@ -440,7 +442,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - true + false TCP @@ -449,21 +451,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - true - - - UDP - - - - - false - Other + UDP @@ -483,6 +475,19 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -1054,7 +1059,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + @@ -1130,7 +1135,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + @@ -1206,6 +1211,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + false + @@ -1213,6 +1221,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + false + 255.255.255.255 @@ -1264,6 +1275,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + false + @@ -1271,6 +1285,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + false + 255.255.255.255 @@ -1279,7 +1296,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + @@ -1310,14 +1327,14 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + Qt::Vertical - 470 + 469 16 @@ -1355,7 +1372,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 1 + 0 diff --git a/common/protocol.proto b/common/protocol.proto index fee57b9..04c7a70 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -169,9 +169,9 @@ message StreamCore { } enum DataPatternMode { - e_dp_fixed = 0; - e_dp_inc = 1; - e_dp_dec = 2; + e_dp_fixed_word = 0; + e_dp_inc_byte = 1; + e_dp_dec_byte = 2; e_dp_random = 3; } @@ -195,8 +195,8 @@ message StreamCore { // Frame Length (includes CRC) optional FrameLengthMode len_mode = 14 [default = e_fl_fixed]; optional uint32 frame_len = 15 [default = 64]; - optional uint32 frame_len_min = 16; - optional uint32 frame_len_max = 17; + optional uint32 frame_len_min = 16 [default = 64]; + optional uint32 frame_len_max = 17 [default = 1518]; // Currently Selected Protocols optional FrameType ft = 21 [default = e_ft_none]; diff --git a/server/myservice.cpp b/server/myservice.cpp index b21310d..3296a86 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -12,65 +12,105 @@ #define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} #define MB (1024*1024) -#if 0 -quint16 StreamInfo::ipv4Cksum(quint16 ipHdrLen, quint16 buff[]) +quint32 StreamInfo::pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp, + quint8 protocol, quint16 len) { - quint16 word16; - quint32 sum=0; - quint16 i; - - // make 16 bit words out of every two adjacent 8 bit words in the packet - // and add them up - for (i = 0; i < ipHdrLen ;i += 2) - { - word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF); - sum = sum + (quint32) word16; - } - - // take only 16 bits out of the 32 bit sum and add up the carries - while (sum>>16) - sum = (sum & 0xFFFF)+(sum >> 16); + quint32 sum; - // one's complement the result - sum = ~sum; - - return (quint16) sum; + sum = srcIp >> 16; + sum += srcIp & 0xFFFF; + sum += dstIp >> 16; + sum += dstIp & 0xFFFF; + sum += (quint16) (protocol); + sum += len; + + // Above calculation done assuming 'big endian' - so convert to host order + return qFromBigEndian(sum); } -#endif -quint16 StreamInfo::ipv4Cksum(uchar *buf, int len) +quint32 StreamInfo::ipv4CksumPartial(uchar *buf, int len) { - quint32 sum = 0; /* assume 32 bit long, 16 bit short */ + quint32 sum = 0; quint16 *ip = (quint16*) buf; - while(len > 1) + if (len & 0x0001) + { + qFatal("Cannot calculate partial checksum on non multiple of 2 length"); + return 0; + } + + while(len) { sum += *ip; - if(sum & 0x80000000) /* if high order bit set, fold */ + if(sum & 0x80000000) sum = (sum & 0xFFFF) + (sum >> 16); ip++; len -= 2; } - if(len) /* take care of left over byte */ + return sum; +} + +quint16 StreamInfo::ipv4Cksum(uchar *buf, int len, quint32 partialSum) +{ + quint32 sum = partialSum; + quint16 *ip = (quint16*) buf; + + while(len > 1) + { + sum += *ip; + if(sum & 0x80000000) + sum = (sum & 0xFFFF) + (sum >> 16); + ip++; + len -= 2; + } + + if (len) sum += (unsigned short) *(unsigned char *)ip; while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); - qDebug("cksum = %x", ~sum); return (quint16) ~sum; } int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) { - int u, pktLen, len = 0; + int u, pktLen, dataLen, len = 0; + quint32 srcIp, dstIp; // need it later for TCP/UDP cksum calculation + quint32 cumCksum = 0; // cumulative cksum used to combine partial cksums + int tcpOfs, udpOfs; // needed to fill in cksum later uchar scratch[8]; - // TODO(HI): use FrameLengthMode - don't assume fixed + // Decide a frame length based on length mode + switch(d.core().len_mode()) + { + case OstProto::StreamCore::e_fl_fixed: + pktLen = d.core().frame_len(); + break; + case OstProto::StreamCore::e_fl_inc: + pktLen = d.core().frame_len_min() + (n % + (d.core().frame_len_max() - d.core().frame_len_min() + 1)); + break; + case OstProto::StreamCore::e_fl_dec: + pktLen = d.core().frame_len_max() - (n % + (d.core().frame_len_max() - d.core().frame_len_min() + 1)); + break; + case OstProto::StreamCore::e_fl_random: + pktLen = d.core().frame_len_min() + (qrand() % + (d.core().frame_len_max() - d.core().frame_len_min() + 1)); + break; + default: + qWarning("Unhandled len mode %d. Using default 64", + d.core().len_mode()); + pktLen = 64; + break; + } + // pktLen is adjusted for CRC/FCS which will be added by the NIC - pktLen = d.core().frame_len() - 4; - if (bufMaxSize < pktLen) + pktLen -= 4; + + if ((pktLen < 0) || (pktLen > bufMaxSize)) return 0; // We always have a Mac Header! @@ -226,30 +266,34 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) qToBigEndian((quint16) 0, buf+len); len += 2; - // TODO(HI): Use IpMode - don't assume fixed + // Get Src/Dst IP for this packet using respective IpMode switch(d.ip().src_ip_mode()) { case OstProto::Ip::e_im_fixed: - qToBigEndian((quint32) d.ip().src_ip(), buf+len); + srcIp = (quint32) d.ip().src_ip(); + qToBigEndian(srcIp, buf+len); break; case OstProto::Ip::e_im_inc_host: u = n % d.ip().src_ip_count(); subnet = d.ip().src_ip() & d.ip().src_ip_mask(); host = (((d.ip().src_ip() & ~d.ip().src_ip_mask()) + u) & ~d.ip().src_ip_mask()); - qToBigEndian((quint32) (subnet | host), buf+len); + srcIp = (quint32) (subnet | host); + qToBigEndian(srcIp, buf+len); break; case OstProto::Ip::e_im_dec_host: u = n % d.ip().src_ip_count(); subnet = d.ip().src_ip() & d.ip().src_ip_mask(); host = (((d.ip().src_ip() & ~d.ip().src_ip_mask()) - u) & ~d.ip().src_ip_mask()); - qToBigEndian((quint32) (subnet | host), buf+len); + srcIp = (quint32) (subnet | host); + qToBigEndian(srcIp, buf+len); break; case OstProto::Ip::e_im_random_host: subnet = d.ip().src_ip() & d.ip().src_ip_mask(); host = (qrand() & ~d.ip().src_ip_mask()); - qToBigEndian((quint32) (subnet | host), buf+len); + srcIp = (quint32) (subnet | host); + qToBigEndian(srcIp, buf+len); break; default: qWarning("Unhandled src_ip_mode = %d", d.ip().src_ip_mode()); @@ -259,26 +303,30 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) switch(d.ip().dst_ip_mode()) { case OstProto::Ip::e_im_fixed: - qToBigEndian((quint32) d.ip().dst_ip(), buf+len); + dstIp = (quint32) d.ip().dst_ip(); + qToBigEndian(dstIp, buf+len); break; case OstProto::Ip::e_im_inc_host: u = n % d.ip().dst_ip_count(); subnet = d.ip().dst_ip() & d.ip().dst_ip_mask(); host = (((d.ip().dst_ip() & ~d.ip().dst_ip_mask()) + u) & ~d.ip().dst_ip_mask()); - qToBigEndian((quint32) (subnet | host), buf+len); + dstIp = (quint32) (subnet | host); + qToBigEndian(dstIp, buf+len); break; case OstProto::Ip::e_im_dec_host: u = n % d.ip().dst_ip_count(); subnet = d.ip().dst_ip() & d.ip().dst_ip_mask(); host = (((d.ip().dst_ip() & ~d.ip().dst_ip_mask()) - u) & ~d.ip().dst_ip_mask()); - qToBigEndian((quint32) (subnet | host), buf+len); + dstIp = (quint32) (subnet | host); + qToBigEndian(dstIp, buf+len); break; case OstProto::Ip::e_im_random_host: subnet = d.ip().dst_ip() & d.ip().dst_ip_mask(); host = (qrand() & ~d.ip().dst_ip_mask()); - qToBigEndian((quint32) (subnet | host), buf+len); + dstIp = (quint32) (subnet | host); + qToBigEndian(dstIp, buf+len); break; default: qWarning("Unhandled dst_ip_mode = %d", d.ip().dst_ip_mode()); @@ -291,6 +339,7 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) else *((quint16*)(buf + ipOfs + 10)) = ipv4Cksum(buf + ipOfs, len-ipOfs); break; + } case OstProto::StreamCore::e_l3_arp: // TODO(LOW) @@ -305,6 +354,10 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) break; case OstProto::StreamCore::e_l4_tcp: { + tcpOfs = len; + + cumCksum = pseudoHdrCksumPartial(srcIp, dstIp, 6, pktLen - len); + qToBigEndian((quint16) d.tcp().src_port(), buf+len); len += 2; qToBigEndian((quint16) d.tcp().dst_port(), buf+len); @@ -318,26 +371,30 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) if (d.tcp().is_override_hdrlen()) buf[len+0] = (quint8) d.tcp().hdrlen_rsvd(); else - buf[len+0] = (quint8) 0x50; // FIXME(LOW) + buf[len+0] = (quint8) 0x50; // FIXME(LOW): Hardcoding buf[len+1] = (quint8) d.tcp().flags(); len += 2; qToBigEndian((quint16) d.tcp().window(), buf+len); len +=2; - if (d.tcp().is_override_cksum()) - qToBigEndian((quint16) d.tcp().cksum(), buf+len); - else - qToBigEndian((quint16) 0, buf+len); // FIXME(HI) + // Fill in cksum as 0 for cksum calculation, actual cksum filled later + qToBigEndian((quint16) 0, buf+len); len +=2; qToBigEndian((quint16) d.tcp().urg_ptr(), buf+len); len +=2; + + // Accumulate cumulative cksum + cumCksum += ipv4CksumPartial(buf + tcpOfs, len - tcpOfs); + break; } case OstProto::StreamCore::e_l4_udp: { - int udpLen = pktLen - len; + udpOfs = len; + + cumCksum = pseudoHdrCksumPartial(srcIp, dstIp, 17, pktLen - len); qToBigEndian((quint16) d.udp().src_port(), buf+len); len += 2; @@ -347,14 +404,16 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) if (d.udp().is_override_totlen()) qToBigEndian((quint16) d.udp().totlen(), buf+len); else - qToBigEndian((quint16) udpLen, buf+len); + qToBigEndian((quint16) (pktLen - udpOfs), buf+len); len +=2; - if (d.udp().is_override_cksum()) - qToBigEndian((quint16) d.udp().cksum(), buf+len); - else - qToBigEndian((quint16) 0, buf+len); // FIXME(HI) + // Fill in cksum as 0 for cksum calculation, actual cksum filled later + qToBigEndian((quint16) 0, buf+len); len +=2; + + // Accumulate cumulative cksum + cumCksum += ipv4CksumPartial(buf + udpOfs, len - udpOfs); + break; } case OstProto::StreamCore::e_l4_icmp: @@ -368,15 +427,51 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) } // Fill-in the data pattern + dataLen = pktLen - len; + switch(d.core().pattern_mode()) { - int dataLen; + case OstProto::StreamCore::e_dp_fixed_word: + for (int i = 0; i < (dataLen/4)+1; i++) + qToBigEndian((quint32) d.core().pattern(), buf+len+(i*4)); + break; + case OstProto::StreamCore::e_dp_inc_byte: + for (int i = 0; i < dataLen; i++) + buf[len + i] = i % (0xFF + 1); + break; + case OstProto::StreamCore::e_dp_dec_byte: + for (int i = 0; i < dataLen; i++) + buf[len + i] = 0xFF - (i % (0xFF + 1)); + break; + case OstProto::StreamCore::e_dp_random: + for (int i = 0; i < dataLen; i++) + buf[len + i] = qrand() % (0xFF + 1); + break; + default: + qWarning("Unhandled data pattern %d", d.core().pattern_mode()); + } - dataLen = pktLen - len; - for (int i = 0; i < (dataLen/4)+1; i++) - { - // TODO(HI): Use patternMode - qToBigEndian((quint32) d.core().pattern(), buf+len+(i*4)); - } + // Calculate TCP/UDP checksum over the data pattern/payload and fill in + switch (d.core().l4_proto()) + { + case OstProto::StreamCore::e_l4_tcp: + if (d.tcp().is_override_cksum()) + qToBigEndian((quint16) d.tcp().cksum(), buf + tcpOfs + 16); + else + *((quint16*)(buf + tcpOfs + 16)) = + ipv4Cksum(buf + len, dataLen, cumCksum); + break; + case OstProto::StreamCore::e_l4_udp: + if (d.udp().is_override_cksum()) + qToBigEndian((quint16) d.udp().cksum(), buf + udpOfs + 6); + else + *((quint16*)(buf + udpOfs + 6)) = + ipv4Cksum(buf + len, dataLen, cumCksum); + break; + case OstProto::StreamCore::e_l4_none: + case OstProto::StreamCore::e_l4_icmp: + case OstProto::StreamCore::e_l4_igmp: + // No cksum processing required + break; } return pktLen; @@ -414,7 +509,7 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) } d.mutable_port_id()->set_id(id); - d.set_name("eth"); // FIXME(MED): suffix portid + d.set_name(QString("eth%1").arg(id).toAscii().constData()); d.set_description(dev->description); d.set_is_enabled(true); // FIXME(MED):check d.set_is_oper_up(true); // FIXME(MED):check @@ -425,7 +520,7 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) // We'll create sendqueue later when required sendQueue = NULL; - pcapExtra.sendQueueNumPkts = 0; + pcapExtra.sendQueueCumLen.clear(); pcapExtra.txPkts = 0; pcapExtra.txBytes = 0; isSendQueueDirty=true; @@ -446,7 +541,7 @@ void PortInfo::update() // TODO(LOW): calculate sendqueue size sendQueue = pcap_sendqueue_alloc(1*MB); - pcapExtra.sendQueueNumPkts = 0; + pcapExtra.sendQueueCumLen.clear(); // First sort the streams by ordinalValue qSort(streamList); @@ -457,35 +552,45 @@ void PortInfo::update() { int numPackets, numBursts; - if (streamList[i].d.control().unit() == - OstProto::StreamControl::e_su_bursts) + switch (streamList[i].d.control().unit()) { + case OstProto::StreamControl::e_su_bursts: numBursts = streamList[i].d.control().num_bursts(); numPackets = streamList[i].d.control().packets_per_burst(); - } - else - { + break; + case OstProto::StreamControl::e_su_packets: numBursts = 1; numPackets = streamList[i].d.control().num_packets(); + break; + default: + qWarning("Unhandled stream control unit %d", + streamList[i].d.control().unit()); + continue; } + for (int j = 0; j < numBursts; j++) { for (int k = 0; k < numPackets; k++) { - pktHdr.len = streamList[i].makePacket( - pktBuf, sizeof(pktBuf), j * numPackets + k); - pktHdr.caplen = pktHdr.len; - pktHdr.ts.tv_sec = pktHdr.ts.tv_usec = 0; // FIXME(HI) + int len; - if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr, - (u_char*) pktBuf)) + len = streamList[i].makePacket(pktBuf, sizeof(pktBuf), + j * numPackets + k); + if (len > 0) { - qDebug("[port %d] sendqueue_queue() failed for " - "streamidx %d\n", id(), i); + pktHdr.caplen = pktHdr.len = len; + pktHdr.ts.tv_sec = pktHdr.ts.tv_usec = 0; // FIXME(HI) + + if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr, + (u_char*) pktBuf)) + { + qDebug("[port %d] sendqueue_queue() failed for " + "streamidx %d\n", id(), i); + } + else + pcapExtra.sendQueueCumLen.append(sendQueue->len); } - else - pcapExtra.sendQueueNumPkts++; } } } @@ -496,7 +601,7 @@ void PortInfo::update() void PortInfo::startTransmit() { - uint bytes; + uint bytes, pkts; // TODO(HI): Stream Mode - one pass/continuous bytes = pcap_sendqueue_transmit(devHandle, sendQueue, false); @@ -504,21 +609,35 @@ void PortInfo::startTransmit() { qDebug("port %d: sent (%d/%d) error %s. TxStats may be inconsistent", id(), bytes, sendQueue->len, pcap_geterr(devHandle)); - //! \TODO parse sendqueue using 'bytes' to get actual pkts sent - pcapExtra.txPkts += pcapExtra.sendQueueNumPkts; - pcapExtra.txBytes += bytes; + + // parse sendqueue using 'bytes' to get actual pkts sent +#if 0 + // FIXME(LOW): Get this working + pkts = qUpperBound(pcapExtra.sendQueueCumLen, bytes); +#else + for (int i = 0; i < pcapExtra.sendQueueCumLen.size(); i++) + { + if (pcapExtra.sendQueueCumLen.at(i) > bytes) + { + pkts = i; + break; + } + } +#endif } else { qDebug("port %d: sent (%d/%d) bytes\n", id(), bytes, sendQueue->len); - pcapExtra.txPkts += pcapExtra.sendQueueNumPkts; - pcapExtra.txBytes += bytes; + pkts = pcapExtra.sendQueueCumLen.size(); } // pcap_sendqueue_transmit() returned 'bytes' includes size of pcap_pkthdr // - adjust for it - pcapExtra.txBytes -= pcapExtra.sendQueueNumPkts * sizeof(pcap_pkthdr); + if (bytes) + bytes -= pkts * sizeof(pcap_pkthdr); + pcapExtra.txPkts += pkts; + pcapExtra.txBytes += bytes; } void PortInfo::stopTransmit() @@ -951,7 +1070,7 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // FIXME(MED): partial RPC? + continue; // TODO(LOW): partial RPC? if (portInfo[portIdx]->isDirty()) portInfo[portIdx]->update(); @@ -963,7 +1082,7 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // FIXME(MED): partial RPC? + continue; // TODO(LOW): partial RPC? portInfo[portIdx]->startTransmit(); } @@ -986,7 +1105,7 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // FIXME(MED): partial RPC? + continue; // TODO(LOW): partial RPC? portInfo[portIdx]->stopTransmit(); } @@ -1038,7 +1157,7 @@ const ::OstProto::PortIdList* request, portidx = request->port_id(i).id(); if (portidx >= numPorts) - continue; // FIXME(med): partial rpc? + continue; // TODO(LOW): partial rpc? s = response->add_port_stats(); s->mutable_port_id()->set_id(request->port_id(i).id()); @@ -1082,7 +1201,7 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // FIXME(MED): partial RPC? + continue; // TODO(LOW): partial RPC? portInfo[portIdx]->resetStats(); } diff --git a/server/myservice.h b/server/myservice.h index ecb474e..a14524d 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -37,8 +37,10 @@ class StreamInfo StreamInfo() { PbHelper pbh; pbh.ForceSetSingularDefault(&d); } - //quint16 ipv4Cksum(quint16 ipHdrLen, quint16 buff[]); - quint16 ipv4Cksum(uchar *buf, int len); + quint32 pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp, + quint8 protocol, quint16 len); + quint32 ipv4CksumPartial(uchar *buf, int len); + quint16 ipv4Cksum(uchar *buf, int len, quint32 partialSum = 0); int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n); public: bool operator < (const StreamInfo &s) const @@ -90,8 +92,10 @@ class PortInfo // PCAP supports it, we'll remove from here struct PcapExtra { - //! pcap_sendqueue_transmit() only returns 'bytes' sent - uint sendQueueNumPkts; + //! Used to track num of packets (and their sizes) in the + // send queue. Also used to find out actual num of pkts sent + // in case of partial send in pcap_sendqueue_transmit() + QList sendQueueCumLen; //! PCAP doesn't do any tx stats quint64 txPkts; From d9aa2e43a017d8c65d152dd05076df1e57aa78c9 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 17 Jan 2009 10:13:46 +0000 Subject: [PATCH 12/98] Changes for successful compilation in Linux. PCAP/Winpcap functions changed to use those which are common on both PCAP and WinPCAP. Some additional WinPCAP only functions (such as the pcap_sendqueue_xxx) which we intend to use have been added into pcapextra.c which will be used in case of Linux --- client/dumpview.h | 2 +- client/ostinato.pro | 4 +-- client/portgrouplist.h | 2 +- rpc/pbhelper.h | 2 +- server/drone.pro | 14 ++++---- server/myservice.cpp | 75 ++++++++++++++++++++++++++++++++++++------ server/myservice.h | 7 ++-- 7 files changed, 82 insertions(+), 24 deletions(-) diff --git a/client/dumpview.h b/client/dumpview.h index cdbcde7..e362103 100644 --- a/client/dumpview.h +++ b/client/dumpview.h @@ -26,7 +26,7 @@ protected slots: void paintEvent(QPaintEvent *event); private: - void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize, + void populateDump(QByteArray &dump, int &selOfs, int &selSize, QModelIndex parent = QModelIndex()); bool inline isPrintable(char c) {if ((c > 48) && (c < 126)) return true; else return false; } diff --git a/client/ostinato.pro b/client/ostinato.pro index 4b1cb69..7e6c89e 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -1,8 +1,8 @@ TEMPLATE = app CONFIG += qt debug QT += network -INCLUDEPATH += "c:\msys\1.0\local\include" "..\rpc\" -LIBS += -L"c:\msys\1.0\local\lib" -lprotobuf -L"..\rpc\debug" -lpbrpc +INCLUDEPATH += "../rpc/" +LIBS += -lprotobuf -L"../rpc/" -lpbrpc RESOURCES += ostinato.qrc HEADERS += \ dumpview.h \ diff --git a/client/portgrouplist.h b/client/portgrouplist.h index aadd24d..89256eb 100644 --- a/client/portgrouplist.h +++ b/client/portgrouplist.h @@ -26,7 +26,7 @@ class PortGroupList : public QObject { // Methods public: - PortGroupList::PortGroupList(); + PortGroupList(); PortModel* getPortModel() { return &mPortGroupListModel; } diff --git a/rpc/pbhelper.h b/rpc/pbhelper.h index 21afefa..e3d85b0 100644 --- a/rpc/pbhelper.h +++ b/rpc/pbhelper.h @@ -4,7 +4,7 @@ #include #include -#include +#include class PbHelper { diff --git a/server/drone.pro b/server/drone.pro index 3642823..315a0e2 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -1,15 +1,17 @@ TEMPLATE = app -CONFIG += qt +CONFIG += qt debug QT += network DEFINES += HAVE_REMOTE WPCAP -INCLUDEPATH += "c:\msys\1.0\local\include" -INCLUDEPATH += "C:\DevelLibs\WpdPack\Include" -INCLUDEPATH += "..\rpc" -LIBS += -L"C:\DevelLibs\WpdPack\Lib" -lwpcap -lpacket -LIBS += -L"..\rpc\debug" -lpbrpc +INCLUDEPATH += "../rpc" +win32:LIBS += -lwpcap -lpacket +unix:LIBS += -lpcap +win32:LIBS += -L"../rpc/debug" -lpbrpc +unix:LIBS += -L"../rpc" -lpbrpc HEADERS += drone.h FORMS += drone.ui SOURCES += drone_main.cpp drone.cpp SOURCES += myservice.cpp +unix:SOURCES += pcapextra.cpp + SOURCES += "..\common\protocol.pb.cc" diff --git a/server/myservice.cpp b/server/myservice.cpp index 3296a86..5f69adc 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -487,8 +487,8 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) char errbuf[PCAP_ERRBUF_SIZE]; this->dev = dev; - devHandle = pcap_open(dev->name, 65536, PCAP_OPENFLAG_PROMISCUOUS , 1000, - NULL, errbuf); + devHandle = pcap_open_live(dev->name, 0, PCAP_OPENFLAG_PROMISCUOUS , + 1000 /*ms*/, errbuf); if (devHandle == NULL) { qDebug("Error opening port %s: %s\n", @@ -509,8 +509,16 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) } d.mutable_port_id()->set_id(id); - d.set_name(QString("eth%1").arg(id).toAscii().constData()); - d.set_description(dev->description); +#ifdef Q_OS_WIN32 + d.set_name(QString("if%1").arg(id).toAscii().constData()); +#else + if (dev->name) + d.set_name(dev->name); + else + d.set_name(QString("if%1").arg(id).toAscii().constData()); +#endif + if (dev->description) + d.set_description(dev->description); d.set_is_enabled(true); // FIXME(MED):check d.set_is_oper_up(true); // FIXME(MED):check d.set_is_exclusive_control(false); // FIXME(MED): check @@ -635,9 +643,18 @@ void PortInfo::startTransmit() // - adjust for it if (bytes) bytes -= pkts * sizeof(pcap_pkthdr); - +#ifdef Q_OS_WIN32 + // Update pcapExtra counters - port TxStats will be updated in the + // 'stats callback' function so that both Rx and Tx stats are updated + // together pcapExtra.txPkts += pkts; pcapExtra.txBytes += bytes; +#else + // We don't have a regular stats callback function here, so update + // Port TxStats directly here + stats.txPkts += pkts; + stats.txBytes += bytes; +#endif } void PortInfo::stopTransmit() @@ -673,9 +690,12 @@ PortInfo::PortMonitor::PortMonitor(PortInfo *port) #endif } +#ifdef Q_OS_WIN32 void PortInfo::PortMonitor::callback(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data) { + // This is the WinPcap Callback - which is a 'stats mode' callback + uint usec; PortInfo *port = (PortInfo*) state; @@ -723,7 +743,7 @@ void PortInfo::PortMonitor::callback(u_char *state, port->monitor.oidData->Oid = OID_GEN_RCV_OK; if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData)) { - if (port->monitor.oidData->Length <= sizeof(port->stats.txPkts)) + if (port->monitor.oidData->Length <= sizeof(port->stats.rxPktsNic)) memcpy((void*)&port->stats.rxPktsNic, (void*)port->monitor.oidData->Data, port->monitor.oidData->Length); @@ -731,14 +751,50 @@ void PortInfo::PortMonitor::callback(u_char *state, port->monitor.oidData->Oid = OID_GEN_XMIT_OK; if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData)) { - if (port->monitor.oidData->Length <= sizeof(port->stats.txPkts)) + if (port->monitor.oidData->Length <= sizeof(port->stats.txPktsNic)) memcpy((void*)&port->stats.txPktsNic, (void*)port->monitor.oidData->Data, port->monitor.oidData->Length); } #endif } +#else +void PortInfo::PortMonitor::callback(u_char *state, + const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // This is the LibPcap Callback - which is a 'capture mode' callback + // This callback is called once for EVERY packet + uint usec; + PortInfo *port = (PortInfo*) state; + + quint64 pkts; + quint64 bytes; + + // Update RxStats and RxRates using PCAP data + usec = (header->ts.tv_sec - port->lastTs.tv_sec) * 1000000 + + (header->ts.tv_usec - port->lastTs.tv_usec); + // TODO(rate) +#if 0 + port->stats.rxPps = (pkts * 1000000) / usec; + port->stats.rxBps = (bytes * 1000000) / usec; +#endif + + // Note: For a 'capture callback' PCAP reported bytes DOES NOT include + // ETH_FRAME_HDR_SIZE - so don't adjust for it + port->stats.rxPkts++; + port->stats.rxBytes += header->len; + + // NOTE: Port TxStats are updated by Port Transmit Function itself + // since this callback is called only when a packet is received + + //! \TODO TxRates + + // Store curr timestamp as last timestamp + port->lastTs.tv_sec = header->ts.tv_sec; + port->lastTs.tv_usec = header->ts.tv_usec; +} +#endif void PortInfo::PortMonitor::run() { int ret; @@ -747,8 +803,7 @@ void PortInfo::PortMonitor::run() /* Start the main loop */ ret = pcap_loop(port->devHandle, -1, &PortInfo::PortMonitor::callback, - (PUCHAR) port); - //ret = pcap_loop(fp, -1, &updateStats, (PUCHAR)&st_ts); + (u_char*) port); switch(ret) { @@ -802,7 +857,7 @@ MyService::MyService(AbstractHost *host) alldevs = NULL; LOG("Retrieving the device list from the local machine\n"); - if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + if (pcap_findalldevs(&alldevs, errbuf) == -1) { LOG("Error in pcap_findalldevs_ex: %s\n", errbuf); goto _fail; diff --git a/server/myservice.h b/server/myservice.h index a14524d..c0679fb 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -15,7 +15,8 @@ #include #include "../rpc/pbhelper.h" - +#include "pcapextra.h" + #ifdef Q_OS_WIN32 #include #endif @@ -41,7 +42,7 @@ class StreamInfo quint8 protocol, quint16 len); quint32 ipv4CksumPartial(uchar *buf, int len); quint16 ipv4Cksum(uchar *buf, int len, quint32 partialSum = 0); - int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n); + int makePacket(uchar *buf, int bufMaxSize, int n); public: bool operator < (const StreamInfo &s) const { return(d.core().ordinal() < s.d.core().ordinal()); } @@ -117,7 +118,7 @@ class PortInfo QList streamList; public: - PortInfo::PortInfo(uint id, pcap_if_t *dev); + PortInfo(uint id, pcap_if_t *dev); uint id() { return d.port_id().id(); } bool isDirty() { return isSendQueueDirty; } void setDirty(bool dirty) { isSendQueueDirty = dirty; } From ab007ce0a5a3025fe704ce7ba8e77aa054c178ad Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 17 Jan 2009 10:52:00 +0000 Subject: [PATCH 13/98] Checking in pcapextra.h and pcapextra.cpp that got left out in the last commit --- server/pcapextra.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++ server/pcapextra.h | 30 ++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 server/pcapextra.cpp create mode 100644 server/pcapextra.h diff --git a/server/pcapextra.cpp b/server/pcapextra.cpp new file mode 100644 index 0000000..f3dd255 --- /dev/null +++ b/server/pcapextra.cpp @@ -0,0 +1,111 @@ +#include // memcpy() +#include // malloc(), free() +#include "pcapextra.h" + +/* NOTE: All code borrowed from WinPcap */ + +int pcap_setmode(pcap_t *p, int mode) +{ + // no STAT mode in libpcap, so just return 0 to indicate success + return 0; +} + +pcap_send_queue* pcap_sendqueue_alloc (u_int memsize) +{ + pcap_send_queue *tqueue; + + /* Allocate the queue */ + tqueue = (pcap_send_queue*)malloc(sizeof(pcap_send_queue)); + if(tqueue == NULL){ + return NULL; + } + + /* Allocate the buffer */ + tqueue->buffer = (char*)malloc(memsize); + if(tqueue->buffer == NULL){ + free(tqueue); + return NULL; + } + + tqueue->maxlen = memsize; + tqueue->len = 0; + + return tqueue; +} + +void pcap_sendqueue_destroy (pcap_send_queue *queue) +{ + free(queue->buffer); + free(queue); +} + +int pcap_sendqueue_queue (pcap_send_queue *queue, + const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) +{ + if(queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > + queue->maxlen) + { + return -1; + } + + /* Copy the pcap_pkthdr header*/ + memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr)); + queue->len += sizeof(struct pcap_pkthdr); + + /* copy the packet */ + memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen); + queue->len += pkt_header->caplen; + + return 0; +} + +u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync) +{ + char* PacketBuff = queue->buffer; + int Size = queue->len; + + struct pcap_pkthdr *winpcap_hdr; + char* EndOfUserBuff = (char *)PacketBuff + Size; + int ret; + + // Start from the first packet + winpcap_hdr = (struct pcap_pkthdr*)PacketBuff; + + if((char*)winpcap_hdr + winpcap_hdr->caplen + sizeof(struct pcap_pkthdr) > + EndOfUserBuff ) + { + // Malformed buffer + return 0; + } + + while( true ){ + + if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > 65536) + { + // Malformed header + return 0; + } + + // Send the packet + ret = pcap_sendpacket(p, + (unsigned char*)winpcap_hdr + sizeof(struct pcap_pkthdr), + winpcap_hdr->caplen); + + if(ret < 0){ + // Error sending the packet + return (char*)winpcap_hdr - (char*)PacketBuff; + } + + // Step to the next packet in the buffer + //(char*)winpcap_hdr += winpcap_hdr->caplen + sizeof(struct pcap_pkthdr); + winpcap_hdr = (struct pcap_pkthdr*) ((char*)winpcap_hdr + + winpcap_hdr->caplen + sizeof(struct pcap_pkthdr)); + + // Check if the end of the user buffer has been reached + if( (char*)winpcap_hdr >= EndOfUserBuff ) + { + return (char*)winpcap_hdr - (char*)PacketBuff; + } + } +} + diff --git a/server/pcapextra.h b/server/pcapextra.h new file mode 100644 index 0000000..25ae4bf --- /dev/null +++ b/server/pcapextra.h @@ -0,0 +1,30 @@ +#ifndef _PCAP_EXTRA_H +#define _PCAP_EXTRA_H + +#ifndef Q_OS_WIN32 + +#include "pcap.h" + +#define PCAP_OPENFLAG_PROMISCUOUS 1 + +struct pcap_send_queue +{ + u_int maxlen; + u_int len; + char *buffer; +}; + +int pcap_setmode(pcap_t *p, int mode); +#define MODE_STAT 1 + +pcap_send_queue* pcap_sendqueue_alloc (u_int memsize); +void pcap_sendqueue_destroy (pcap_send_queue *queue); +int pcap_sendqueue_queue (pcap_send_queue *queue, + const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); +u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync); + + +#endif + +#endif + From 9ac311f80fe8b52d1e3882ad7e5012115fc1944b Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 17 Jan 2009 11:37:35 +0000 Subject: [PATCH 14/98] Fixing the path that was unix specific to work for both unix and win32 --- client/ostinato.pro | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/ostinato.pro b/client/ostinato.pro index 7e6c89e..572abb2 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -2,7 +2,9 @@ TEMPLATE = app CONFIG += qt debug QT += network INCLUDEPATH += "../rpc/" -LIBS += -lprotobuf -L"../rpc/" -lpbrpc +LIBS += -lprotobuf +win32:LIBS += -L"../rpc/debug" -lpbrpc +unix:LIBS += -L"../rpc" -lpbrpc RESOURCES += ostinato.qrc HEADERS += \ dumpview.h \ From 0c70668e564e285701ca60869b0458a781355d11 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 2 Feb 2009 10:08:57 +0000 Subject: [PATCH 15/98] Split the PCAP callback into 2 - one for Rx and one for Tx using pcap_setdirection() --- server/myservice.cpp | 248 ++++++++++++++++++++++++++++++++++--------- server/myservice.h | 30 ++++-- 2 files changed, 224 insertions(+), 54 deletions(-) diff --git a/server/myservice.cpp b/server/myservice.cpp index 5f69adc..97f54cd 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -482,33 +482,57 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) // ------------------ PortInfo -------------------- // PortInfo::PortInfo(uint id, pcap_if_t *dev) - : monitor(this) + : monitorRx(this), monitorTx(this) { char errbuf[PCAP_ERRBUF_SIZE]; this->dev = dev; - devHandle = pcap_open_live(dev->name, 0, PCAP_OPENFLAG_PROMISCUOUS , + + /* + * Get 2 device handles - one for rx and one for tx. If we use only + * one handle for both rx and tx anythin that we tx using the single + * handle is not received back to us + */ + devHandleRx = pcap_open_live(dev->name, 0, PCAP_OPENFLAG_PROMISCUOUS , 1000 /*ms*/, errbuf); - if (devHandle == NULL) + if (devHandleRx == NULL) { qDebug("Error opening port %s: %s\n", - dev->name, pcap_geterr(devHandle)); + dev->name, pcap_geterr(devHandleRx)); } -#if 0 - if (pcap_setdirection(devHandle, PCAP_D_IN)<0) + if (pcap_setdirection(devHandleRx, PCAP_D_IN)<0) { qDebug("[%s] Error setting direction inbound only\n", dev->name); } -#endif /* By default, put the interface in statistics mode */ - if (pcap_setmode(devHandle, MODE_STAT)<0) + if (pcap_setmode(devHandleRx, MODE_STAT)<0) + { + qDebug("Error setting statistics mode.\n"); + } + + devHandleTx = pcap_open_live(dev->name, 0, PCAP_OPENFLAG_PROMISCUOUS , + 1000 /*ms*/, errbuf); + if (devHandleTx == NULL) + { + qDebug("Error opening port %s: %s\n", + dev->name, pcap_geterr(devHandleTx)); + } + + if (pcap_setdirection(devHandleTx, PCAP_D_OUT)<0) + { + qDebug("[%s] Error setting direction outbound only\n", dev->name); + } + + /* By default, put the interface in statistics mode */ + if (pcap_setmode(devHandleTx, MODE_STAT)<0) { qDebug("Error setting statistics mode.\n"); } d.mutable_port_id()->set_id(id); + #ifdef Q_OS_WIN32 d.set_name(QString("if%1").arg(id).toAscii().constData()); #else @@ -517,6 +541,8 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) else d.set_name(QString("if%1").arg(id).toAscii().constData()); #endif + d.set_name(d.name()+pcap_datalink_val_to_name(pcap_datalink(devHandleRx))); + if (dev->description) d.set_description(dev->description); d.set_is_enabled(true); // FIXME(MED):check @@ -534,7 +560,8 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) isSendQueueDirty=true; // Start the monitor thread - monitor.start(); + monitorRx.start(); + monitorTx.start(); } void PortInfo::update() @@ -612,11 +639,13 @@ void PortInfo::startTransmit() uint bytes, pkts; // TODO(HI): Stream Mode - one pass/continuous - bytes = pcap_sendqueue_transmit(devHandle, sendQueue, false); + // NOTE: Transmit on the Rx Handle so that we can receive it back + // on the Tx Handle to do stats + bytes = pcap_sendqueue_transmit(devHandleRx, sendQueue, false); if (bytes < sendQueue->len) { qDebug("port %d: sent (%d/%d) error %s. TxStats may be inconsistent", - id(), bytes, sendQueue->len, pcap_geterr(devHandle)); + id(), bytes, sendQueue->len, pcap_geterr(devHandleTx)); // parse sendqueue using 'bytes' to get actual pkts sent #if 0 @@ -649,11 +678,6 @@ void PortInfo::startTransmit() // together pcapExtra.txPkts += pkts; pcapExtra.txBytes += bytes; -#else - // We don't have a regular stats callback function here, so update - // Port TxStats directly here - stats.txPkts += pkts; - stats.txBytes += bytes; #endif } @@ -670,7 +694,27 @@ void PortInfo::resetStats() // ------------------ PortMonitor ------------------- // -PortInfo::PortMonitor::PortMonitor(PortInfo *port) +PortInfo::PortMonitorRx::PortMonitorRx(PortInfo *port) +{ + this->port = port; +#ifdef Q_OS_WIN32 + { + int sz = sizeof(PACKET_OID_DATA) + sizeof(quint64) + 4; + //oidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, + //sizeof(PACKET_OID_DATA) + sizeof(quint64) - 1); + oidData = (PPACKET_OID_DATA) malloc(sz); + if (oidData) + { + memset(oidData, 0, sz); + oidData->Length=sizeof(quint64); + } + else + qFatal("failed to alloc oidData"); + } +#endif +} + +PortInfo::PortMonitorTx::PortMonitorTx(PortInfo *port) { this->port = port; #ifdef Q_OS_WIN32 @@ -691,7 +735,60 @@ PortInfo::PortMonitor::PortMonitor(PortInfo *port) } #ifdef Q_OS_WIN32 -void PortInfo::PortMonitor::callback(u_char *state, +void PortInfo::PortMonitorRx::callbackRx(u_char *state, + const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // This is the WinPcap Callback - which is a 'stats mode' callback + + uint usec; + PortInfo *port = (PortInfo*) state; + + quint64 pkts; + quint64 bytes; + + // Update RxStats and RxRates using PCAP data + pkts = *((quint64*)(pkt_data + 0)); + bytes = *((quint64*)(pkt_data + 8)); + + // Note: PCAP reported bytes includes ETH_FRAME_HDR_SIZE - adjust for it + bytes -= pkts * ETH_FRAME_HDR_SIZE; + + usec = (header->ts.tv_sec - port->lastTsRx.tv_sec) * 1000000 + + (header->ts.tv_usec - port->lastTsRx.tv_usec); + port->stats.rxPps = (pkts * 1000000) / usec; + port->stats.rxBps = (bytes * 1000000) / usec; + + port->stats.rxPkts += pkts; + port->stats.rxBytes += bytes; + + // Store curr timestamp as last timestamp + port->lastTsRx.tv_sec = header->ts.tv_sec; + port->lastTsRx.tv_usec = header->ts.tv_usec; + +#if 0 + for (int i=0; i < 16; i++) + { + qDebug("%02x ", pkt_data[i]); + } + qDebug("{%d: %llu, %llu}\n", port->id(), + pkts, bytes); + qDebug("[%d: pkts : %llu]\n", port->id(), port->stats.rxPkts); + qDebug("[%d: bytes: %llu]\n", port->id(), port->stats.rxBytes); +#endif + + // Retreive NIC stats +#ifdef Q_OS_WIN32 + port->monitorRx.oidData->Oid = OID_GEN_RCV_OK; + if (PacketRequest(port->devHandleRx->adapter, 0, port->monitorRx.oidData)) + { + if (port->monitorRx.oidData->Length <= sizeof(port->stats.rxPktsNic)) + memcpy((void*)&port->stats.rxPktsNic, + (void*)port->monitorRx.oidData->Data, + port->monitorRx.oidData->Length); + } +#endif +} +void PortInfo::PortMonitorTx::callbackTx(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data) { // This is the WinPcap Callback - which is a 'stats mode' callback @@ -717,15 +814,25 @@ void PortInfo::PortMonitor::callback(u_char *state, port->stats.rxPkts += pkts; port->stats.rxBytes += bytes; - // Update TxStats from PcapExtra + // Since WinPCAP (due to NDIS limitation) cannot distinguish between + // rx/tx packets, pcap stats are not of much use - for the tx stats + // update from PcapExtra + + pkts = port->pcapExtra.txPkts - port->stats.txPkts; + bytes = port->pcapExtra.txBytes - port->stats.txBytes; + + // Use the pcap timestamp for rate calculation though + usec = (header->ts.tv_sec - port->lastTs.tv_sec) * 1000000 + + (header->ts.tv_usec - port->lastTs.tv_usec); + port->stats.txPps = (pkts * 1000000) / usec; + port->stats.txBps = (bytes * 1000000) / usec; + port->stats.txPkts = port->pcapExtra.txPkts; port->stats.txBytes = port->pcapExtra.txBytes; - //! \TODO TxRates - // Store curr timestamp as last timestamp - port->lastTs.tv_sec = header->ts.tv_sec; - port->lastTs.tv_usec = header->ts.tv_usec; + port->lastTsTx.tv_sec = header->ts.tv_sec; + port->lastTsTx.tv_usec = header->ts.tv_usec; #if 0 for (int i=0; i < 16; i++) @@ -740,26 +847,18 @@ void PortInfo::PortMonitor::callback(u_char *state, // Retreive NIC stats #ifdef Q_OS_WIN32 - port->monitor.oidData->Oid = OID_GEN_RCV_OK; - if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData)) + port->monitorTx.oidData->Oid = OID_GEN_XMIT_OK; + if (PacketRequest(port->devHandleTx->adapter, 0, port->monitorTx.oidData)) { - if (port->monitor.oidData->Length <= sizeof(port->stats.rxPktsNic)) - memcpy((void*)&port->stats.rxPktsNic, - (void*)port->monitor.oidData->Data, - port->monitor.oidData->Length); - } - port->monitor.oidData->Oid = OID_GEN_XMIT_OK; - if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData)) - { - if (port->monitor.oidData->Length <= sizeof(port->stats.txPktsNic)) + if (port->monitorTx.oidData->Length <= sizeof(port->stats.txPktsNic)) memcpy((void*)&port->stats.txPktsNic, - (void*)port->monitor.oidData->Data, - port->monitor.oidData->Length); + (void*)port->monitorTx.oidData->Data, + port->monitorTx.oidData->Length); } #endif } #else -void PortInfo::PortMonitor::callback(u_char *state, +void PortInfo::PortMonitorRx::callbackRx(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data) { // This is the LibPcap Callback - which is a 'capture mode' callback @@ -772,8 +871,8 @@ void PortInfo::PortMonitor::callback(u_char *state, quint64 bytes; // Update RxStats and RxRates using PCAP data - usec = (header->ts.tv_sec - port->lastTs.tv_sec) * 1000000 + - (header->ts.tv_usec - port->lastTs.tv_usec); + usec = (header->ts.tv_sec - port->lastTsRx.tv_sec) * 1000000 + + (header->ts.tv_usec - port->lastTsRx.tv_usec); // TODO(rate) #if 0 port->stats.rxPps = (pkts * 1000000) / usec; @@ -785,25 +884,78 @@ void PortInfo::PortMonitor::callback(u_char *state, port->stats.rxPkts++; port->stats.rxBytes += header->len; - // NOTE: Port TxStats are updated by Port Transmit Function itself - // since this callback is called only when a packet is received + // Store curr timestamp as last timestamp + port->lastTsRx.tv_sec = header->ts.tv_sec; + port->lastTsRx.tv_usec = header->ts.tv_usec; +} - //! \TODO TxRates +void PortInfo::PortMonitorTx::callbackTx(u_char *state, + const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // This is the LibPcap Callback - which is a 'capture mode' callback + // This callback is called once for EVERY packet + + uint usec; + PortInfo *port = (PortInfo*) state; + + quint64 pkts; + quint64 bytes; + + // Update TxStats and TxRates using PCAP data + usec = (header->ts.tv_sec - port->lastTsTx.tv_sec) * 1000000 + + (header->ts.tv_usec - port->lastTsTx.tv_usec); + // TODO(rate) +#if 0 + port->stats.txPps = (pkts * 1000000) / usec; + port->stats.txBps = (bytes * 1000000) / usec; +#endif + + // Note: For a 'capture callback' PCAP reported bytes DOES NOT include + // ETH_FRAME_HDR_SIZE - so don't adjust for it + + port->stats.txPkts++; + port->stats.txBytes += header->len; // Store curr timestamp as last timestamp - port->lastTs.tv_sec = header->ts.tv_sec; - port->lastTs.tv_usec = header->ts.tv_usec; + port->lastTsTx.tv_sec = header->ts.tv_sec; + port->lastTsTx.tv_usec = header->ts.tv_usec; } #endif -void PortInfo::PortMonitor::run() +void PortInfo::PortMonitorRx::run() { int ret; - qDebug("before pcap_loop\n"); + qDebug("before pcap_loop rx \n"); /* Start the main loop */ - ret = pcap_loop(port->devHandle, -1, &PortInfo::PortMonitor::callback, - (u_char*) port); + ret = pcap_loop(port->devHandleRx, -1, + &PortInfo::PortMonitorRx::callbackRx, (u_char*) port); + + switch(ret) + { + case 0: + qDebug("Unexpected return from pcap_loop()\n"); + break; + case -1: + qDebug("Unsolicited (error) return from pcap_loop()\n"); + break; + case -2: + qDebug("Solicited return from pcap_loop()\n"); + break; + default: + qDebug("Unknown return value from pcap_loop()\n"); + } +} + +void PortInfo::PortMonitorTx::run() +{ + int ret; + + qDebug("before pcap_loopTx\n"); + + /* Start the main loop */ + ret = pcap_loop(port->devHandleTx, -1, + &PortInfo::PortMonitorTx::callbackTx, (u_char*) port); switch(ret) { diff --git a/server/myservice.h b/server/myservice.h index c0679fb..182c65f 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -53,7 +53,7 @@ class PortInfo { friend class MyService; - class PortMonitor: public QThread + class PortMonitorRx: public QThread { friend class PortInfo; @@ -62,8 +62,23 @@ class PortInfo PPACKET_OID_DATA oidData; #endif public: - PortMonitor(PortInfo *port); - static void callback(u_char *state, + PortMonitorRx(PortInfo *port); + static void callbackRx(u_char *state, + const struct pcap_pkthdr *header, const u_char *pkt_data); + void run(); + }; + + class PortMonitorTx: public QThread + { + friend class PortInfo; + + PortInfo *port; +#ifdef Q_OS_WIN32 + PPACKET_OID_DATA oidData; +#endif + public: + PortMonitorTx(PortInfo *port); + static void callbackTx(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data); void run(); }; @@ -104,15 +119,18 @@ class PortInfo }; pcap_if_t *dev; - pcap_t *devHandle; + pcap_t *devHandleRx; + pcap_t *devHandleTx; pcap_send_queue *sendQueue; bool isSendQueueDirty; PcapExtra pcapExtra; - PortMonitor monitor; + PortMonitorRx monitorRx; + PortMonitorTx monitorTx; struct PortStats epochStats; struct PortStats stats; - struct timeval lastTs; //! used for Rate Stats calculations + struct timeval lastTsRx; //! used for Rate Stats calculations + struct timeval lastTsTx; //! used for Rate Stats calculations /*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */ QList streamList; From 017cb75ae5d5711f55225c1219ac8bdb8249bce0 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Thu, 12 Feb 2009 17:07:19 +0000 Subject: [PATCH 16/98] - Packet Transmission is now a separate thread to allow for event processing - Packet Transmission rate (IPG) is done - need to test. IBG is still pending - Per port there are two pcap_t handles - one for Rx and one for Tx: since PCAP does not capture loopback packets, transmission by OST happens on Rx Hdl so that they are recieved on the Tx Hdl - pcap_loop() changed to pcap_dispatch() to be able to work in PCAP/Linux - forgot exactly why :-) - Removed NIC stats - Implemented PortStatsFilterDialog ordering of ports - PortStatsWindow - Tooltip on Port column dispays stats limitations --- client/portstatsfilter.ui | 70 ++++------ client/portstatsfilterdialog.cpp | 43 +++++-- client/portstatsfilterdialog.h | 2 + client/portstatsmodel.cpp | 46 +++++-- client/portstatsmodel.h | 12 +- client/portstatswindow.cpp | 14 +- client/portstatswindow.ui | 32 ++--- server/myservice.cpp | 215 ++++++++++++++++++++++--------- server/myservice.h | 16 ++- 9 files changed, 294 insertions(+), 156 deletions(-) diff --git a/client/portstatsfilter.ui b/client/portstatsfilter.ui index e34fde2..a681c65 100644 --- a/client/portstatsfilter.ui +++ b/client/portstatsfilter.ui @@ -6,7 +6,7 @@ 0 0 588 - 298 + 320 @@ -17,9 +17,21 @@ + + false + + + false + + + QAbstractItemView::NoDragDrop + QAbstractItemView::ExtendedSelection + + QListView::Static + @@ -68,6 +80,18 @@ + + true + + + true + + + false + + + QAbstractItemView::InternalMove + QAbstractItemView::ExtendedSelection @@ -76,50 +100,6 @@ - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - U - - - - - - - D - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - diff --git a/client/portstatsfilterdialog.cpp b/client/portstatsfilterdialog.cpp index af95303..6c97d85 100644 --- a/client/portstatsfilterdialog.cpp +++ b/client/portstatsfilterdialog.cpp @@ -4,13 +4,6 @@ PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent) { setupUi(this); - // TODO(MED): Use ExtendedSelection and use "selected" instead of - // "current" for selecting in/out - // TODO(MED): Ensure items are READ-ONLY not editable - // TODO(MED): Enable "double-click" on items - lvUnselected->setSelectionMode(QAbstractItemView::SingleSelection); - lvSelected->setSelectionMode(QAbstractItemView::SingleSelection); - mUnselected.setSortRole(PositionRole); lvUnselected->setModel(&mUnselected); @@ -37,6 +30,10 @@ QList PortStatsFilterDialog::getItemList(bool* ok, item = new QStandardItem(model->headerData(i, orientation).toString()); item->setData(i, PositionRole); + item->setFlags(Qt::ItemIsSelectable + | Qt::ItemIsDragEnabled + //| Qt::ItemIsDropEnabled + | Qt::ItemIsEnabled); if (initial.contains(i)) mSelected.appendRow(item); @@ -62,6 +59,36 @@ QList PortStatsFilterDialog::getItemList(bool* ok, } void PortStatsFilterDialog::on_tbSelectIn_clicked() +{ + QStandardItem *item; + while (lvUnselected->selectionModel()->selectedIndexes().size()) + { + item = mUnselected.takeItem(lvUnselected->selectionModel()-> + selectedIndexes().at(0).row()); + if (mUnselected.removeRow(lvUnselected->selectionModel()-> + selectedIndexes().at(0).row())) + mSelected.appendRow(item); + } +} + +void PortStatsFilterDialog::on_tbSelectOut_clicked() +{ + QStandardItem *item; + + while (lvSelected->selectionModel()->selectedIndexes().size()) + { + item = mSelected.takeItem(lvSelected->selectionModel()-> + selectedIndexes().at(0).row()); + if (mSelected.removeRow(lvSelected->selectionModel()-> + selectedIndexes().at(0).row())) + { + mUnselected.appendRow(item); + mUnselected.sort(0); + } + } +} + +void PortStatsFilterDialog::on_lvUnselected_doubleClicked(const QModelIndex &index) { QStandardItem *item; @@ -70,7 +97,7 @@ void PortStatsFilterDialog::on_tbSelectIn_clicked() mSelected.appendRow(item); } -void PortStatsFilterDialog::on_tbSelectOut_clicked() +void PortStatsFilterDialog::on_lvSelected_doubleClicked(const QModelIndex &index) { QStandardItem *item; diff --git a/client/portstatsfilterdialog.h b/client/portstatsfilterdialog.h index e845e0d..cabbf0c 100644 --- a/client/portstatsfilterdialog.h +++ b/client/portstatsfilterdialog.h @@ -27,6 +27,8 @@ private: private slots: void on_tbSelectIn_clicked(); void on_tbSelectOut_clicked(); + void on_lvUnselected_doubleClicked(const QModelIndex &index); + void on_lvSelected_doubleClicked(const QModelIndex &index); }; #endif diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index d554687..7676e42 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -105,12 +105,6 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const case e_STAT_FRAME_RECV_RATE: return stats.rx_pps(); - case e_STAT_FRAMES_RCVD_NIC: - return stats.rx_pkts_nic(); - - case e_STAT_FRAMES_SENT_NIC: - return stats.tx_pkts_nic(); - case e_STAT_BYTES_RCVD: return stats.rx_bytes(); @@ -123,12 +117,19 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const case e_STAT_BYTE_RECV_RATE: return stats.rx_bps(); +#if 0 + case e_STAT_FRAMES_RCVD_NIC: + return stats.rx_pkts_nic(); + + case e_STAT_FRAMES_SENT_NIC: + return stats.tx_pkts_nic(); + case e_STAT_BYTES_RCVD_NIC: return stats.rx_bytes_nic(); case e_STAT_BYTES_SENT_NIC: return stats.tx_bytes_nic(); - +#endif default: qWarning("%s: Unhandled stats id %d\n", __FUNCTION__, index.row()); @@ -142,11 +143,39 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, int role) const { +#ifdef Q_OS_WIN32 + // TODO(MED): The limitations should be the server's not the client's! + // Ideally we shd enhance the protocol to convey limitation(s), if any, + // from server to client + if (role == Qt::ToolTipRole) + { + if (orientation == Qt::Horizontal) + { + return QString("Limitation(s)" + "

Frames/Bytes Receieved: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
" + "Frames/Bytes Sent: Only Ostinato Tx pkts (Tx by others NOT included)

" + "

Rx/Tx Rates are derived from the above and hence subject to same limitations

" + ); + } + else + return QVariant(); + } +#endif + if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) - return QString("Port %1").arg(section); + { + uint portGroupIdx, portIdx; + + getDomainIndexes(index(0, section), portGroupIdx, portIdx); +#ifdef Q_OS_WIN32 + return QString("Port %1/%2 (*)").arg(portGroupIdx).arg(portIdx); +#else + return QString("Port %1/%2").arg(portGroupIdx).arg(portIdx); +#endif + } else return PortStatName.at(section); } @@ -212,7 +241,6 @@ void PortStatsModel::when_portListChanged() void PortStatsModel::on_portStatsUpdate(int port, void*stats) { - // FIXME(MED): update only the changed port not all QModelIndex topLeft = index(port, 0, QModelIndex()); QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex()); diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h index 1825524..de1c585 100644 --- a/client/portstatsmodel.h +++ b/client/portstatsmodel.h @@ -9,14 +9,16 @@ typedef enum { e_STAT_FRAMES_SENT, e_STAT_FRAME_SEND_RATE, e_STAT_FRAME_RECV_RATE, - e_STAT_FRAMES_RCVD_NIC, - e_STAT_FRAMES_SENT_NIC, e_STAT_BYTES_RCVD, e_STAT_BYTES_SENT, e_STAT_BYTE_SEND_RATE, e_STAT_BYTE_RECV_RATE, +#if 0 + e_STAT_FRAMES_RCVD_NIC, + e_STAT_FRAMES_SENT_NIC, e_STAT_BYTES_RCVD_NIC, e_STAT_BYTES_SENT_NIC, +#endif e_STAT_MAX } PortStat; @@ -25,14 +27,16 @@ static QStringList PortStatName = (QStringList() << "Frames Sent" << "Frame Send Rate (fps)" << "Frame Receive Rate (fps)" - << "Frames Received (NIC)" - << "Frames Sent (NIC)" << "Bytes Received" << "Bytes Sent" << "Byte Send Rate (Bps)" << "Byte Receive Rate (Bps)" +#if 0 + << "Frames Received (NIC)" + << "Frames Sent (NIC)" << "Bytes Received (NIC)" << "Bytes Sent (NIC)" +#endif ); class PortGroupList; diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index 5f4ff6b..53be8b7 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -13,11 +13,11 @@ PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent) this->pgl = pgl; model = pgl->getPortStatsModel(); tvPortStats->setModel(model); - tvPortStats->horizontalHeader()->setMovable(true); tvPortStats->verticalHeader()->setHighlightSections(false); tvPortStats->verticalHeader()->setDefaultSectionSize( tvPortStats->verticalHeader()->minimumSectionSize()); + } PortStatsWindow::~PortStatsWindow() @@ -109,7 +109,17 @@ void PortStatsWindow::on_tbFilter_clicked() newColumns = dialog.getItemList(&ok, model, Qt::Horizontal, currentColumns); - if(ok) + if (ok) + { + // hide/show sections first ... for(int i = 0; i < model->columnCount(); i++) tvPortStats->setColumnHidden(i, !newColumns.contains(i)); + + // ... then for the 'shown' columns, set the visual index + for(int i = 0; i < newColumns.size(); i++) + { + tvPortStats->horizontalHeader()->moveSection(tvPortStats-> + horizontalHeader()->visualIndex(newColumns.at(i)), i); + } + } } diff --git a/client/portstatswindow.ui b/client/portstatswindow.ui index 4396ff6..a7fc8d5 100644 --- a/client/portstatswindow.ui +++ b/client/portstatswindow.ui @@ -15,9 +15,6 @@ - - Clear All - QFrame::StyledPanel @@ -28,7 +25,7 @@ - Clear All + Start Tx Starts transmit on selected port(s) @@ -44,7 +41,7 @@ - Clear All + Stop Tx Stops transmit on selected port(s) @@ -60,7 +57,7 @@ - Clear All + Clear Selected Port Stats Clears statistics of the selected port(s) @@ -73,7 +70,7 @@ - Clear All + Clear All Ports Stats Clears statistics of all ports @@ -86,7 +83,7 @@ - Clear All + Start Capture Captures packets on the selected port(s) @@ -102,7 +99,7 @@ - Clear All + Stop Capture End capture on selecteed port(s) @@ -118,7 +115,7 @@ - Clear All + View Capture Buffer View captured packets on selected port(s) @@ -133,9 +130,6 @@ - - Clear All - Qt::Vertical @@ -143,9 +137,6 @@ - - Clear All - Qt::Horizontal @@ -159,9 +150,6 @@ - - Clear All - Select which ports to view @@ -177,11 +165,7 @@ - - - Clear All - - + diff --git a/server/myservice.cpp b/server/myservice.cpp index 97f54cd..eef1610 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -4,7 +4,7 @@ #include #include -#ifdef Q_OS_WIN32 +#if 0 #include #include #endif @@ -482,7 +482,7 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) // ------------------ PortInfo -------------------- // PortInfo::PortInfo(uint id, pcap_if_t *dev) - : monitorRx(this), monitorTx(this) + : monitorRx(this), monitorTx(this), transmitter(this) { char errbuf[PCAP_ERRBUF_SIZE]; @@ -501,10 +501,12 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) dev->name, pcap_geterr(devHandleRx)); } +#if 0 if (pcap_setdirection(devHandleRx, PCAP_D_IN)<0) { qDebug("[%s] Error setting direction inbound only\n", dev->name); } +#endif /* By default, put the interface in statistics mode */ if (pcap_setmode(devHandleRx, MODE_STAT)<0) @@ -520,10 +522,12 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) dev->name, pcap_geterr(devHandleTx)); } +#if 0 if (pcap_setdirection(devHandleTx, PCAP_D_OUT)<0) { qDebug("[%s] Error setting direction outbound only\n", dev->name); } +#endif /* By default, put the interface in statistics mode */ if (pcap_setmode(devHandleTx, MODE_STAT)<0) @@ -534,14 +538,15 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) d.mutable_port_id()->set_id(id); #ifdef Q_OS_WIN32 - d.set_name(QString("if%1").arg(id).toAscii().constData()); + d.set_name(QString("if%1 ").arg(id).toAscii().constData()); #else if (dev->name) d.set_name(dev->name); else - d.set_name(QString("if%1").arg(id).toAscii().constData()); + d.set_name(QString("if%1 ").arg(id).toAscii().constData()); #endif - d.set_name(d.name()+pcap_datalink_val_to_name(pcap_datalink(devHandleRx))); + d.set_name(d.name()+"{"+ + pcap_datalink_val_to_name(pcap_datalink(devHandleRx))+"}"); if (dev->description) d.set_description(dev->description); @@ -586,6 +591,7 @@ void PortInfo::update() if (streamList[i].d.core().is_enabled()) { int numPackets, numBursts; + long ipg; switch (streamList[i].d.control().unit()) { @@ -596,6 +602,8 @@ void PortInfo::update() case OstProto::StreamControl::e_su_packets: numBursts = 1; numPackets = streamList[i].d.control().num_packets(); + ipg = 1000000/streamList[i].d.control().packets_per_sec(); + qDebug("ipg = %ld\n", ipg); break; default: qWarning("Unhandled stream control unit %d", @@ -603,9 +611,11 @@ void PortInfo::update() continue; } - + pktHdr.ts.tv_sec = 0; + pktHdr.ts.tv_usec = 0; for (int j = 0; j < numBursts; j++) { + // FIXME(HI): IBG rate (bursts_per_sec) for (int k = 0; k < numPackets; k++) { int len; @@ -615,7 +625,12 @@ void PortInfo::update() if (len > 0) { pktHdr.caplen = pktHdr.len = len; - pktHdr.ts.tv_sec = pktHdr.ts.tv_usec = 0; // FIXME(HI) + pktHdr.ts.tv_usec += ipg; + if (pktHdr.ts.tv_usec > 1000000) + { + pktHdr.ts.tv_sec++; + pktHdr.ts.tv_usec -= 1000000; + } if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr, (u_char*) pktBuf)) @@ -636,49 +651,7 @@ void PortInfo::update() void PortInfo::startTransmit() { - uint bytes, pkts; - - // TODO(HI): Stream Mode - one pass/continuous - // NOTE: Transmit on the Rx Handle so that we can receive it back - // on the Tx Handle to do stats - bytes = pcap_sendqueue_transmit(devHandleRx, sendQueue, false); - if (bytes < sendQueue->len) - { - qDebug("port %d: sent (%d/%d) error %s. TxStats may be inconsistent", - id(), bytes, sendQueue->len, pcap_geterr(devHandleTx)); - - // parse sendqueue using 'bytes' to get actual pkts sent -#if 0 - // FIXME(LOW): Get this working - pkts = qUpperBound(pcapExtra.sendQueueCumLen, bytes); -#else - for (int i = 0; i < pcapExtra.sendQueueCumLen.size(); i++) - { - if (pcapExtra.sendQueueCumLen.at(i) > bytes) - { - pkts = i; - break; - } - } -#endif - } - else - { - qDebug("port %d: sent (%d/%d) bytes\n", id(), bytes, sendQueue->len); - pkts = pcapExtra.sendQueueCumLen.size(); - } - - // pcap_sendqueue_transmit() returned 'bytes' includes size of pcap_pkthdr - // - adjust for it - if (bytes) - bytes -= pkts * sizeof(pcap_pkthdr); -#ifdef Q_OS_WIN32 - // Update pcapExtra counters - port TxStats will be updated in the - // 'stats callback' function so that both Rx and Tx stats are updated - // together - pcapExtra.txPkts += pkts; - pcapExtra.txBytes += bytes; -#endif + transmitter.start(); } void PortInfo::stopTransmit() @@ -750,6 +723,11 @@ void PortInfo::PortMonitorRx::callbackRx(u_char *state, pkts = *((quint64*)(pkt_data + 0)); bytes = *((quint64*)(pkt_data + 8)); +#if 0 + if (port->id() == 2) + qDebug("# %llu", pkts); +#endif + // Note: PCAP reported bytes includes ETH_FRAME_HDR_SIZE - adjust for it bytes -= pkts * ETH_FRAME_HDR_SIZE; @@ -777,7 +755,7 @@ void PortInfo::PortMonitorRx::callbackRx(u_char *state, #endif // Retreive NIC stats -#ifdef Q_OS_WIN32 +#if 0 port->monitorRx.oidData->Oid = OID_GEN_RCV_OK; if (PacketRequest(port->devHandleRx->adapter, 0, port->monitorRx.oidData)) { @@ -799,20 +777,28 @@ void PortInfo::PortMonitorTx::callbackTx(u_char *state, quint64 pkts; quint64 bytes; + +#if 0 // Update RxStats and RxRates using PCAP data pkts = *((quint64*)(pkt_data + 0)); bytes = *((quint64*)(pkt_data + 8)); +#if 0 + if (port->id() == 2) + qDebug("@ %llu", pkts); +#endif + // Note: PCAP reported bytes includes ETH_FRAME_HDR_SIZE - adjust for it bytes -= pkts * ETH_FRAME_HDR_SIZE; - usec = (header->ts.tv_sec - port->lastTs.tv_sec) * 1000000 + - (header->ts.tv_usec - port->lastTs.tv_usec); - port->stats.rxPps = (pkts * 1000000) / usec; - port->stats.rxBps = (bytes * 1000000) / usec; + usec = (header->ts.tv_sec - port->lastTsTx.tv_sec) * 1000000 + + (header->ts.tv_usec - port->lastTsTx.tv_usec); + port->stats.txPps = (pkts * 1000000) / usec; + port->stats.txBps = (bytes * 1000000) / usec; - port->stats.rxPkts += pkts; - port->stats.rxBytes += bytes; + port->stats.txPkts += pkts; + port->stats.txBytes += bytes; +#endif // Since WinPCAP (due to NDIS limitation) cannot distinguish between // rx/tx packets, pcap stats are not of much use - for the tx stats @@ -822,8 +808,8 @@ void PortInfo::PortMonitorTx::callbackTx(u_char *state, bytes = port->pcapExtra.txBytes - port->stats.txBytes; // Use the pcap timestamp for rate calculation though - usec = (header->ts.tv_sec - port->lastTs.tv_sec) * 1000000 + - (header->ts.tv_usec - port->lastTs.tv_usec); + usec = (header->ts.tv_sec - port->lastTsTx.tv_sec) * 1000000 + + (header->ts.tv_usec - port->lastTsTx.tv_usec); port->stats.txPps = (pkts * 1000000) / usec; port->stats.txBps = (bytes * 1000000) / usec; @@ -846,7 +832,7 @@ void PortInfo::PortMonitorTx::callbackTx(u_char *state, #endif // Retreive NIC stats -#ifdef Q_OS_WIN32 +#if 0 port->monitorTx.oidData->Oid = OID_GEN_XMIT_OK; if (PacketRequest(port->devHandleTx->adapter, 0, port->monitorTx.oidData)) { @@ -926,7 +912,7 @@ void PortInfo::PortMonitorRx::run() int ret; qDebug("before pcap_loop rx \n"); - +#if 1 /* Start the main loop */ ret = pcap_loop(port->devHandleRx, -1, &PortInfo::PortMonitorRx::callbackRx, (u_char*) port); @@ -945,6 +931,28 @@ void PortInfo::PortMonitorRx::run() default: qDebug("Unknown return value from pcap_loop()\n"); } +#else + while (1) + { + /* Start the main loop */ + ret = pcap_dispatch(port->devHandleRx, -1, + &PortInfo::PortMonitorRx::callbackRx, (u_char*) port); + + switch(ret) + { + case -1: + qDebug("Unsolicited (error) return from pcap_loop() %s\n", + pcap_geterr(port->devHandleRx)); + break; + case -2: + qDebug("Solicited return from pcap_loop()\n"); + break; + default: + //qDebug("%d pkts rcvd\n", ret); + break; + } + } +#endif } void PortInfo::PortMonitorTx::run() @@ -952,7 +960,7 @@ void PortInfo::PortMonitorTx::run() int ret; qDebug("before pcap_loopTx\n"); - +#if 1 /* Start the main loop */ ret = pcap_loop(port->devHandleTx, -1, &PortInfo::PortMonitorTx::callbackTx, (u_char*) port); @@ -971,6 +979,84 @@ void PortInfo::PortMonitorTx::run() default: qDebug("Unknown return value from pcap_loop()\n"); } +#else + while (1) + { + /* Start the main loop */ + ret = pcap_dispatch(port->devHandleTx, -1, + &PortInfo::PortMonitorTx::callbackTx, (u_char*) port); + + switch(ret) + { + case -1: + qDebug("Unsolicited (error) return from pcap_loop() %s\n", + pcap_geterr(port->devHandleTx)); + break; + case -2: + qDebug("Solicited return from pcap_loop()\n"); + break; + default: + //qDebug("%d pkts rcvd\n", ret); + break; + } + } +#endif +} + +/*--------------- PortTransmitter ---------------*/ + +PortInfo::PortTransmitter::PortTransmitter(PortInfo *port) +{ + this->port = port; +} + +void PortInfo::PortTransmitter::run() +{ + uint bytes, pkts; + + // TODO(HI): Stream Mode - one pass/continuous + // NOTE: Transmit on the Rx Handle so that we can receive it back + // on the Tx Handle to do stats + bytes = pcap_sendqueue_transmit(port->devHandleRx, port->sendQueue, true); + if (bytes < port->sendQueue->len) + { + qDebug("port %d: sent (%d/%d) error %s. TxStats may be inconsistent", + port->id(), bytes, port->sendQueue->len, + pcap_geterr(port->devHandleTx)); + + // parse sendqueue using 'bytes' to get actual pkts sent +#if 0 + // FIXME(LOW): Get this working + pkts = qUpperBound(pcapExtra.sendQueueCumLen, bytes); +#else + for (int i = 0; i < port->pcapExtra.sendQueueCumLen.size(); i++) + { + if (port->pcapExtra.sendQueueCumLen.at(i) > bytes) + { + pkts = i; + break; + } + } +#endif + } + else + { + qDebug("port %d: sent (%d/%d) bytes\n", port->id(), bytes, + port->sendQueue->len); + pkts = port->pcapExtra.sendQueueCumLen.size(); + } + + // pcap_sendqueue_transmit() returned 'bytes' includes size of pcap_pkthdr + // - adjust for it + if (bytes) + bytes -= pkts * sizeof(pcap_pkthdr); +#ifdef Q_OS_WIN32 + // Update pcapExtra counters - port TxStats will be updated in the + // 'stats callback' function so that both Rx and Tx stats are updated + // together + port->pcapExtra.txPkts += pkts; + port->pcapExtra.txBytes += bytes; +#endif } /*--------------- MyService ---------------*/ @@ -1369,6 +1455,11 @@ const ::OstProto::PortIdList* request, s = response->add_port_stats(); s->mutable_port_id()->set_id(request->port_id(i).id()); + if (portidx == 2) + { + qDebug("<%llu", portInfo[portidx]->epochStats.rxPkts); + qDebug(">%llu", portInfo[portidx]->stats.rxPkts); + } s->set_rx_pkts(portInfo[portidx]->stats.rxPkts - portInfo[portidx]->epochStats.rxPkts); s->set_rx_bytes(portInfo[portidx]->stats.rxBytes - diff --git a/server/myservice.h b/server/myservice.h index 182c65f..6155cac 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -82,6 +82,17 @@ class PortInfo const struct pcap_pkthdr *header, const u_char *pkt_data); void run(); }; + + class PortTransmitter: public QThread + { + friend class PortInfo; + + PortInfo *port; + + public: + PortTransmitter(PortInfo *port); + void run(); + }; OstProto::Port d; @@ -111,7 +122,7 @@ class PortInfo //! Used to track num of packets (and their sizes) in the // send queue. Also used to find out actual num of pkts sent // in case of partial send in pcap_sendqueue_transmit() - QList sendQueueCumLen; + QList sendQueueCumLen; //! PCAP doesn't do any tx stats quint64 txPkts; @@ -121,11 +132,12 @@ class PortInfo pcap_if_t *dev; pcap_t *devHandleRx; pcap_t *devHandleTx; - pcap_send_queue *sendQueue; + pcap_send_queue* sendQueue; bool isSendQueueDirty; PcapExtra pcapExtra; PortMonitorRx monitorRx; PortMonitorTx monitorTx; + PortTransmitter transmitter; struct PortStats epochStats; struct PortStats stats; From f13b0915d57f5347aadb5fc4f12f3b053374ace8 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 22 Feb 2009 07:53:14 +0000 Subject: [PATCH 17/98] Packet Transmit Changes - not using pcap_sendqueue_transmit() any longer --- client/portstatsmodel.cpp | 2 +- client/portstatswindow.cpp | 2 +- common/protocol.proto | 4 +- server/drone.pro | 2 +- server/myservice.cpp | 126 +++++++++++++++++++++---------------- server/myservice.h | 12 ++-- server/pcapextra.cpp | 47 +++++++++++++- server/pcapextra.h | 28 ++++++++- 8 files changed, 154 insertions(+), 69 deletions(-) diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 7676e42..bcc0f54 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -12,7 +12,7 @@ PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent) timer = new QTimer(); connect(timer, SIGNAL(timeout()), this, SLOT(updateStats())); - timer->start(2000); + timer->start(1000); } int PortStatsModel::rowCount(const QModelIndex &parent) const diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index 53be8b7..d1340a6 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -54,7 +54,7 @@ void PortStatsWindow::on_tbStopTransmit_clicked() for (int i = 0; i < pgpl.size(); i++) { pgl->portGroupByIndex(pgpl.at(i).portGroupId). - startTx(&pgpl[i].portList); + stopTx(&pgpl[i].portList); } } diff --git a/common/protocol.proto b/common/protocol.proto index 04c7a70..7038517 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -227,8 +227,8 @@ message StreamControl { optional uint32 num_bursts = 4 [default = 1]; optional uint32 packets_per_burst = 5 [default = 10]; optional NextWhat next = 6 [default = e_nw_goto_next]; - optional uint32 packets_per_sec = 7; - optional uint32 bursts_per_sec = 8; + optional uint32 packets_per_sec = 7 [default = 1]; + optional uint32 bursts_per_sec = 8 [default = 1]; // TODO: Gaps? diff --git a/server/drone.pro b/server/drone.pro index 315a0e2..15d69b1 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -12,6 +12,6 @@ FORMS += drone.ui SOURCES += drone_main.cpp drone.cpp SOURCES += myservice.cpp -unix:SOURCES += pcapextra.cpp +SOURCES += pcapextra.cpp SOURCES += "..\common\protocol.pb.cc" diff --git a/server/myservice.cpp b/server/myservice.cpp index eef1610..dd19090 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -558,8 +558,7 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) resetStats(); // We'll create sendqueue later when required - sendQueue = NULL; - pcapExtra.sendQueueCumLen.clear(); + sendQueueList.clear(); pcapExtra.txPkts = 0; pcapExtra.txBytes = 0; isSendQueueDirty=true; @@ -571,17 +570,21 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) void PortInfo::update() { - uchar pktBuf[2000]; - pcap_pkthdr pktHdr; + uchar pktBuf[2000]; + pcap_pkthdr pktHdr; + ost_pcap_send_queue sendQ; qDebug("In %s", __FUNCTION__); - if (sendQueue) - pcap_sendqueue_destroy(sendQueue); + if (sendQueueList.size()) + { + foreach(sendQ, sendQueueList) + pcap_sendqueue_destroy(sendQ.sendQueue); + } // TODO(LOW): calculate sendqueue size - sendQueue = pcap_sendqueue_alloc(1*MB); - pcapExtra.sendQueueCumLen.clear(); + sendQ.sendQueue = pcap_sendqueue_alloc(1*MB); + sendQ.sendQueueCumLen.clear(); // First sort the streams by ordinalValue qSort(streamList); @@ -590,32 +593,36 @@ void PortInfo::update() { if (streamList[i].d.core().is_enabled()) { - int numPackets, numBursts; - long ipg; + long numPackets, numBursts; + long ibg, ipg; switch (streamList[i].d.control().unit()) { case OstProto::StreamControl::e_su_bursts: numBursts = streamList[i].d.control().num_bursts(); numPackets = streamList[i].d.control().packets_per_burst(); + ibg = 1000000/streamList[i].d.control().bursts_per_sec(); + ipg = 0; break; case OstProto::StreamControl::e_su_packets: numBursts = 1; numPackets = streamList[i].d.control().num_packets(); + ibg = 0; ipg = 1000000/streamList[i].d.control().packets_per_sec(); - qDebug("ipg = %ld\n", ipg); break; default: qWarning("Unhandled stream control unit %d", streamList[i].d.control().unit()); continue; } + qDebug("numBursts = %ld, numPackets = %ld\n", + numBursts, numPackets); + qDebug("ibg = %ld, ipg = %ld\n", ibg, ipg); pktHdr.ts.tv_sec = 0; pktHdr.ts.tv_usec = 0; for (int j = 0; j < numBursts; j++) { - // FIXME(HI): IBG rate (bursts_per_sec) for (int k = 0; k < numPackets; k++) { int len; @@ -632,20 +639,45 @@ void PortInfo::update() pktHdr.ts.tv_usec -= 1000000; } - if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr, + // Not enough space? Alloc another one! + if ((sendQ.sendQueue->len + len + sizeof(pcap_pkthdr)) + > sendQ.sendQueue->maxlen) + { + sendQueueList.append(sendQ); + + // TODO(LOW): calculate sendqueue size + sendQ.sendQueue = pcap_sendqueue_alloc(1*MB); + sendQ.sendQueueCumLen.clear(); + +#if 0 + pktHdr.ts.tv_sec = 0; + pktHdr.ts.tv_usec = 0; +#endif + } + + if (-1 == pcap_sendqueue_queue(sendQ.sendQueue, &pktHdr, (u_char*) pktBuf)) { qDebug("[port %d] sendqueue_queue() failed for " "streamidx %d\n", id(), i); } else - pcapExtra.sendQueueCumLen.append(sendQueue->len); + sendQ.sendQueueCumLen.append(sendQ.sendQueue->len); } } + pktHdr.ts.tv_usec += ibg; + if (pktHdr.ts.tv_usec > 1000000) + { + pktHdr.ts.tv_sec++; + pktHdr.ts.tv_usec -= 1000000; + } } } } + // The last alloc'ed sendQ appended here + sendQueueList.append(sendQ); + isSendQueueDirty = false; } @@ -656,6 +688,7 @@ void PortInfo::startTransmit() void PortInfo::stopTransmit() { + transmitter.stop(); } void PortInfo::resetStats() @@ -1012,53 +1045,33 @@ PortInfo::PortTransmitter::PortTransmitter(PortInfo *port) void PortInfo::PortTransmitter::run() { - uint bytes, pkts; - // TODO(HI): Stream Mode - one pass/continuous - // NOTE: Transmit on the Rx Handle so that we can receive it back + + // NOTE1: We can't use pcap_sendqueue_transmit() directly even on Win32 + // 'coz of 2 reasons - there's no way of stopping it before all packets + // in the sendQueue are sent out and secondly, stats are available only + // when all packets have been sent - no periodic updates + // + // NOTE2: Transmit on the Rx Handle so that we can receive it back // on the Tx Handle to do stats - bytes = pcap_sendqueue_transmit(port->devHandleRx, port->sendQueue, true); - if (bytes < port->sendQueue->len) - { - qDebug("port %d: sent (%d/%d) error %s. TxStats may be inconsistent", - port->id(), bytes, port->sendQueue->len, - pcap_geterr(port->devHandleTx)); - - // parse sendqueue using 'bytes' to get actual pkts sent -#if 0 - // FIXME(LOW): Get this working - pkts = qUpperBound(pcapExtra.sendQueueCumLen, bytes); -#else - for (int i = 0; i < port->pcapExtra.sendQueueCumLen.size(); i++) - { - if (port->pcapExtra.sendQueueCumLen.at(i) > bytes) - { - pkts = i; - break; - } - } -#endif - } - else - { - qDebug("port %d: sent (%d/%d) bytes\n", port->id(), bytes, - port->sendQueue->len); - pkts = port->pcapExtra.sendQueueCumLen.size(); - } - - // pcap_sendqueue_transmit() returned 'bytes' includes size of pcap_pkthdr - // - adjust for it - if (bytes) - bytes -= pkts * sizeof(pcap_pkthdr); -#ifdef Q_OS_WIN32 - // Update pcapExtra counters - port TxStats will be updated in the + // + // NOTE3: Update pcapExtra counters - port TxStats will be updated in the // 'stats callback' function so that both Rx and Tx stats are updated // together - port->pcapExtra.txPkts += pkts; - port->pcapExtra.txBytes += bytes; -#endif + + m_stop = 0; + ost_pcap_sendqueue_list_transmit(port->devHandleRx, port->sendQueueList, + true, &m_stop, &port->pcapExtra.txPkts, &port->pcapExtra.txBytes, + QThread::usleep); + m_stop = 0; } +void PortInfo::PortTransmitter::stop() +{ + m_stop = 1; +} + + /*--------------- MyService ---------------*/ int MyService::getStreamIndex(unsigned int portIdx, @@ -1455,11 +1468,14 @@ const ::OstProto::PortIdList* request, s = response->add_port_stats(); s->mutable_port_id()->set_id(request->port_id(i).id()); +#if 0 if (portidx == 2) { qDebug("<%llu", portInfo[portidx]->epochStats.rxPkts); qDebug(">%llu", portInfo[portidx]->stats.rxPkts); } +#endif + s->set_rx_pkts(portInfo[portidx]->stats.rxPkts - portInfo[portidx]->epochStats.rxPkts); s->set_rx_bytes(portInfo[portidx]->stats.rxBytes - diff --git a/server/myservice.h b/server/myservice.h index 6155cac..7f1cb88 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -87,11 +87,13 @@ class PortInfo { friend class PortInfo; - PortInfo *port; + PortInfo *port; + int m_stop; public: PortTransmitter(PortInfo *port); void run(); + void stop(); }; OstProto::Port d; @@ -114,25 +116,23 @@ class PortInfo }; //! \todo Need lock for stats access/update + //! Stuff we need to maintain since PCAP doesn't as of now. As and when // PCAP supports it, we'll remove from here struct PcapExtra { - //! Used to track num of packets (and their sizes) in the - // send queue. Also used to find out actual num of pkts sent - // in case of partial send in pcap_sendqueue_transmit() - QList sendQueueCumLen; //! PCAP doesn't do any tx stats quint64 txPkts; quint64 txBytes; + }; pcap_if_t *dev; pcap_t *devHandleRx; pcap_t *devHandleTx; - pcap_send_queue* sendQueue; + QList sendQueueList; bool isSendQueueDirty; PcapExtra pcapExtra; PortMonitorRx monitorRx; diff --git a/server/pcapextra.cpp b/server/pcapextra.cpp index f3dd255..78d57e0 100644 --- a/server/pcapextra.cpp +++ b/server/pcapextra.cpp @@ -4,6 +4,7 @@ /* NOTE: All code borrowed from WinPcap */ +#ifndef Q_OS_WIN32 int pcap_setmode(pcap_t *p, int mode) { // no STAT mode in libpcap, so just return 0 to indicate success @@ -58,13 +59,36 @@ int pcap_sendqueue_queue (pcap_send_queue *queue, return 0; } +#endif -u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync) +u_int ost_pcap_sendqueue_list_transmit(pcap_t *p, + QList sendQueueList, int sync, + int *p_stop, quint64* p_pkts, quint64* p_bytes, + void (*pf_usleep)(ulong)) +{ + uint ret = 0; + + foreach(ost_pcap_send_queue sq, sendQueueList) + { + ret += ost_pcap_sendqueue_transmit(p, sq.sendQueue, sync, + p_stop, p_pkts, p_bytes, pf_usleep); + + // TODO(HI): Timing between subsequent sendQueues + } + + return ret; +} + +u_int ost_pcap_sendqueue_transmit(pcap_t *p, + pcap_send_queue *queue, int sync, + int *p_stop, quint64* p_pkts, quint64* p_bytes, + void (*pf_usleep)(ulong)) { char* PacketBuff = queue->buffer; int Size = queue->len; struct pcap_pkthdr *winpcap_hdr; + struct timeval ts; char* EndOfUserBuff = (char *)PacketBuff + Size; int ret; @@ -78,8 +102,14 @@ u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync) return 0; } + if (sync) + ts = winpcap_hdr->ts; + while( true ){ + if (*p_stop) + return (char*)winpcap_hdr - (char*)PacketBuff; + if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > 65536) { // Malformed header @@ -96,6 +126,9 @@ u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync) return (char*)winpcap_hdr - (char*)PacketBuff; } + if (p_pkts) (*p_pkts)++; + if (p_bytes) (*p_bytes) += winpcap_hdr->caplen; + // Step to the next packet in the buffer //(char*)winpcap_hdr += winpcap_hdr->caplen + sizeof(struct pcap_pkthdr); winpcap_hdr = (struct pcap_pkthdr*) ((char*)winpcap_hdr + @@ -106,6 +139,18 @@ u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync) { return (char*)winpcap_hdr - (char*)PacketBuff; } + + if (sync) + { + long usec = (winpcap_hdr->ts.tv_sec-ts.tv_sec)*1000000 + + (winpcap_hdr->ts.tv_usec - ts.tv_usec); + + if (usec) + { + (*pf_usleep)(usec); + ts = winpcap_hdr->ts; + } + } } } diff --git a/server/pcapextra.h b/server/pcapextra.h index 25ae4bf..3d2f8f4 100644 --- a/server/pcapextra.h +++ b/server/pcapextra.h @@ -1,10 +1,35 @@ #ifndef _PCAP_EXTRA_H #define _PCAP_EXTRA_H -#ifndef Q_OS_WIN32 +#include +#include #include "pcap.h" +struct ost_pcap_send_queue +{ + pcap_send_queue *sendQueue; + //! Used to track num of packets (and their sizes) in the + // send queue. Also used to find out actual num of pkts sent + // in case of partial send in pcap_sendqueue_transmit() + QList sendQueueCumLen; +}; + +// Common for all OS - *nix or Win32 +u_int ost_pcap_sendqueue_list_transmit(pcap_t *p, + QList sendQueueList, int sync, + int *p_stop, quint64* p_pkts, quint64* p_bytes, + void (*pf_usleep)(ulong)); + +u_int ost_pcap_sendqueue_transmit (pcap_t *p, + pcap_send_queue *queue, int sync, + int *p_stop, quint64* p_pkts, quint64* p_bytes, + void (*pf_usleep)(ulong)); + +#ifndef Q_OS_WIN32 +// Only for non Win32 + + #define PCAP_OPENFLAG_PROMISCUOUS 1 struct pcap_send_queue @@ -21,7 +46,6 @@ pcap_send_queue* pcap_sendqueue_alloc (u_int memsize); void pcap_sendqueue_destroy (pcap_send_queue *queue); int pcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); -u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync); #endif From 53bcc077dae3a220d2ba8f7a524d549e6ef261e8 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Tue, 10 Mar 2009 16:48:03 +0000 Subject: [PATCH 18/98] - Implemented the "Stop" and "Goto Stream" per stream "nextWhat" options (Goto can only go to first stream for now - not any arbitrary stream) - StreamListView now has a delegate to display a combobox for "nextWhat" and a checkbox for "status" - StreamListView now has reasonable default widths for its columns --- client/ostinato.pro | 2 + client/portswindow.cpp | 9 +- client/streamconfigdialog.cpp | 8 +- client/streamconfigdialog.ui | 3 + client/streamlistdelegate.cpp | 175 ++++++++++++++++++++++++++++++++++ client/streamlistdelegate.h | 29 ++++++ client/streammodel.cpp | 65 ++++++++----- client/streammodel.h | 22 +++-- server/myservice.cpp | 55 +++++++++-- server/myservice.h | 1 + server/pcapextra.cpp | 18 +++- server/pcapextra.h | 2 +- 12 files changed, 342 insertions(+), 47 deletions(-) create mode 100644 client/streamlistdelegate.cpp create mode 100644 client/streamlistdelegate.h diff --git a/client/ostinato.pro b/client/ostinato.pro index 572abb2..ec44eb0 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -20,6 +20,7 @@ HEADERS += \ portstatswindow.h \ portswindow.h \ streamconfigdialog.h \ + streamlistdelegate.h \ streammodel.h FORMS += \ @@ -45,6 +46,7 @@ SOURCES += \ portstatswindow.cpp \ portswindow.cpp \ streamconfigdialog.cpp \ + streamlistdelegate.cpp \ streammodel.cpp # Protocol Buffer Sources diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 27dec05..1789e5e 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -1,18 +1,20 @@ #include "portswindow.h" +#include "streamlistdelegate.h" #include "streamconfigdialog.h" #include #include PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) { + StreamListDelegate *delegate = new StreamListDelegate; //slm = new StreamListModel(); //plm = new PortGroupList(); plm = pgl; setupUi(this); - tvStreamList->horizontalHeader()->resizeSections( - QHeaderView::ResizeToContents); + tvStreamList->setItemDelegate(delegate); + tvStreamList->verticalHeader()->setDefaultSectionSize( tvStreamList->verticalHeader()->minimumSectionSize()); @@ -53,6 +55,9 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&))); #endif + tvStreamList->resizeColumnToContents(StreamModel::StreamIcon); + tvStreamList->resizeColumnToContents(StreamModel::StreamStatus); + // Initially we don't have any ports/streams - so send signal triggers when_portView_currentChanged(QModelIndex(), QModelIndex()); when_streamView_currentChanged(QModelIndex(), QModelIndex()); diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 7ee59f7..e7f1f0b 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -173,7 +173,8 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, pbPrev->setDisabled(true); pbNext->setDisabled(true); //! \todo Support Goto Stream Id - rbActionGotoStream->setDisabled(true); + leStreamId->setDisabled(true); + disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool))); //! \todo Support Continuous Mode rbModeContinuous->setDisabled(true); } @@ -824,10 +825,11 @@ void StreamConfigDialog::LoadCurrentStream() leNumPackets->setText(QString().setNum(pStream->numPackets())); leNumBursts->setText(QString().setNum(pStream->numBursts())); - lePacketsPerBurst->setText(QString().setNum( - pStream->burstSize())); + lePacketsPerBurst->setText(QString().setNum(pStream->burstSize())); lePacketsPerSec->setText(QString().setNum(pStream->packetRate())); leBurstsPerSec->setText(QString().setNum(pStream->burstRate())); + // TODO(MED): Change this when we support goto to specific stream + leStreamId->setText(QString("0")); } } diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index b94e107..178e966 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -1915,6 +1915,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
+ + false + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter diff --git a/client/streamlistdelegate.cpp b/client/streamlistdelegate.cpp new file mode 100644 index 0000000..f67b99e --- /dev/null +++ b/client/streamlistdelegate.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#include + +#include "streammodel.h" +#include "streamlistdelegate.h" + +StreamListDelegate::StreamListDelegate(QObject *parent) +: QItemDelegate(parent) +{ +} + + +QWidget *StreamListDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QWidget *editor = NULL; + + switch ((StreamModel::StreamFields) index.column()) + { + case StreamModel::StreamStatus: + { + editor = new QCheckBox(parent); + goto _handled; + } + case StreamModel::StreamNextWhat: + { + editor = new QComboBox(parent); + static_cast(editor)->insertItems(0, + StreamModel::nextWhatOptionList()); + goto _handled; + } + + case StreamModel::StreamIcon: + case StreamModel::StreamName: + default: + break; + } + + editor = QItemDelegate::createEditor(parent, option, index); + +_handled: + return editor; + +} + + +void StreamListDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const +{ + switch ((StreamModel::StreamFields) index.column()) + { + case StreamModel::StreamStatus: + { + QCheckBox *cb = static_cast(editor); + cb->setChecked( + index.model()->data(index, Qt::EditRole).toBool()); + goto _handled; + } + case StreamModel::StreamNextWhat: + { + QComboBox *cb = static_cast(editor); + cb->setCurrentIndex( + index.model()->data(index, Qt::EditRole).toInt()); + goto _handled; + } + + case StreamModel::StreamIcon: + case StreamModel::StreamName: + default: + break; + } + + QItemDelegate::setEditorData(editor, index); + +_handled: + return; +} + + +void StreamListDelegate::setModelData(QWidget *editor, + QAbstractItemModel *model, const QModelIndex &index) const +{ + switch ((StreamModel::StreamFields) index.column()) + { + case StreamModel::StreamStatus: + { + QCheckBox *cb = static_cast(editor); + model->setData(index, cb->isChecked(), Qt::EditRole); + goto _handled; + } + + case StreamModel::StreamNextWhat: + { + QComboBox *cb = static_cast(editor); + model->setData(index, cb->currentIndex(), Qt::EditRole); + goto _handled; + } + + case StreamModel::StreamIcon: + case StreamModel::StreamName: + default: + break; + } + + QItemDelegate::setModelData(editor, model, index); + +_handled: + return; +} + + +void StreamListDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + switch ((StreamModel::StreamFields) index.column()) + { + case StreamModel::StreamStatus: + { + /* + * extra 'coz QItemDelegate does it - otherwise the editor + * placement is incorrect + */ + int extra = 2 * (qApp->style()->pixelMetric( + QStyle::PM_FocusFrameHMargin, 0) + 1); + + editor->setGeometry(option.rect.translated(extra, 0)); + goto _handled; + } + case StreamModel::StreamIcon: + case StreamModel::StreamName: + case StreamModel::StreamNextWhat: + default: + break; + } + + QItemDelegate::updateEditorGeometry(editor, option, index); + +_handled: + return; +} + + +bool StreamListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) +{ + /* + * Special Handling so that user can use the "Stream status" checkbox + * without double clicking first. Copied from QItemDelegate::editorEvent() + * and modified suitably + */ + if ((StreamModel::StreamFields)index.column() == + StreamModel::StreamStatus) + { + // make sure that we have the right event type + if ((event->type() == QEvent::MouseButtonRelease) + || (event->type() == QEvent::MouseButtonDblClick)) + { + QRect checkRect = check(option, option.rect, Qt::Checked); + QRect emptyRect; + doLayout(option, &checkRect, &emptyRect, &emptyRect, false); + if (!checkRect.contains(static_cast(event)->pos())) + return false; + + Qt::CheckState state = (static_cast(index.data( + Qt::CheckStateRole).toInt()) == Qt::Checked ? Qt::Unchecked : Qt::Checked); + return model->setData(index, state, Qt::CheckStateRole); + } + } + + return QItemDelegate::editorEvent(event, model, option, index); +} + diff --git a/client/streamlistdelegate.h b/client/streamlistdelegate.h new file mode 100644 index 0000000..a4e8d35 --- /dev/null +++ b/client/streamlistdelegate.h @@ -0,0 +1,29 @@ +#ifndef STREAM_LIST_DELEGATE_H +#define STREAM_LIST_DELEGATE_H + +#include +#include + +class StreamListDelegate : public QItemDelegate +{ + Q_OBJECT + +public: + StreamListDelegate(QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; + + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const; + + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index); +}; + +#endif + diff --git a/client/streammodel.cpp b/client/streammodel.cpp index 32dce31..6680f58 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -1,3 +1,4 @@ +#include "stream.h" #include "streammodel.h" #include "portgrouplist.h" #include "qicon.h" @@ -38,17 +39,19 @@ Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const flags |= Qt::ItemIsEditable; break; case StreamStatus: -#if 0 - flags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable; -#endif + flags |= Qt::ItemIsUserCheckable; + break; + case StreamNextWhat: flags |= Qt::ItemIsEditable; break; default: + //qFatal("Missed case in switch!"); break; } return flags; } + QVariant StreamModel::data(const QModelIndex &index, int role) const { // Check for a valid index @@ -72,10 +75,6 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const { if (role == Qt::DecorationRole) return QIcon(":/icons/stream_edit.png"); -#if 0 - else if ((role == Qt::DisplayRole)) - return QString("EDIT"); -#endif else return QVariant(); break; @@ -90,12 +89,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const } case StreamStatus: { - if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) - return mCurrentPort->streamByIndex(index.row()).isEnabled(); - else - return QVariant(); - #if 0 - if ((role == Qt::CheckStateRole) || (role == Qt::EditRole)) + if ((role == Qt::CheckStateRole)) { if (mCurrentPort->streamByIndex(index.row()).isEnabled()) return Qt::Checked; @@ -104,11 +98,23 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const } else return QVariant(); - #endif + break; + } + case StreamNextWhat: + { + int val = mCurrentPort->streamByIndex(index.row()).nextWhat(); + + if (role == Qt::DisplayRole) + return nextWhatOptionList().at(val); + else if (role == Qt::EditRole) + return val; + else + return QVariant(); + break; } default: - qDebug("-------------UNHANDLED STREAM FIELD----------------"); + qFatal("-------------UNHANDLED STREAM FIELD----------------"); } return QVariant(); @@ -119,24 +125,35 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r if (mCurrentPort == NULL) return false; - if (index.isValid() && role == Qt::EditRole) + if (index.isValid()) { - // Edit Supported Fields switch (index.column()) { + // Edit Supported Fields case StreamName: mCurrentPort->streamByIndex(index.row()).setName(value.toString()); + emit(dataChanged(index, index)); return true; - break; + case StreamStatus: mCurrentPort->streamByIndex(index.row()).setIsEnabled(value.toBool()); + emit(dataChanged(index, index)); return true; - break; + + case StreamNextWhat: + if (role == Qt::EditRole) + { + mCurrentPort->streamByIndex(index.row()).setNextWhat( + (Stream::NextWhat)value.toInt()); + emit(dataChanged(index, index)); + return true; + } + else + return false; // Edit Not Supported Fields case StreamIcon: return false; - break; // Unhandled Stream Field default: @@ -144,6 +161,7 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r break; } } + return false; } @@ -157,13 +175,16 @@ QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int r switch(section) { case StreamIcon: - return QString("Icon"); + return QString(""); break; case StreamName: return QString("Name"); break; case StreamStatus: - return QString("Enabled"); + return QString(""); + break; + case StreamNextWhat: + return QString("Goto"); break; default: qDebug("-------------UNHANDLED STREAM FIELD----------------"); diff --git a/client/streammodel.h b/client/streammodel.h index 697517d..95af6fe 100644 --- a/client/streammodel.h +++ b/client/streammodel.h @@ -1,6 +1,7 @@ #ifndef _STREAM_MODEL_H #define _STREAM_MODEL_H +#include #include #include "port.h" @@ -10,14 +11,6 @@ class StreamModel : public QAbstractTableModel { Q_OBJECT - enum StreamFields { - StreamIcon = 0, - StreamName, - StreamStatus, - - StreamMaxFields - }; - Port *mCurrentPort; PortGroupList *pgl; @@ -43,6 +36,19 @@ class StreamModel : public QAbstractTableModel { return &mCurrentPort->mStreams; } #endif + public: + enum StreamFields { + StreamIcon = 0, + StreamName, + StreamStatus, + StreamNextWhat, + + StreamMaxFields + }; + + static QStringList nextWhatOptionList() + { return QStringList() << "Stop" << "Next" << "Goto first"; } + public slots: void setCurrentPortIndex(const QModelIndex ¤t); diff --git a/server/myservice.cpp b/server/myservice.cpp index dd19090..085f6f5 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -559,6 +559,7 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) // We'll create sendqueue later when required sendQueueList.clear(); + returnToQIdx = -1; pcapExtra.txPkts = 0; pcapExtra.txBytes = 0; isSendQueueDirty=true; @@ -581,6 +582,8 @@ void PortInfo::update() foreach(sendQ, sendQueueList) pcap_sendqueue_destroy(sendQ.sendQueue); } + sendQueueList.clear(); + returnToQIdx = -1; // TODO(LOW): calculate sendqueue size sendQ.sendQueue = pcap_sendqueue_alloc(1*MB); @@ -589,8 +592,11 @@ void PortInfo::update() // First sort the streams by ordinalValue qSort(streamList); + pktHdr.ts.tv_sec = 0; + pktHdr.ts.tv_usec = 0; for (int i = 0; i < streamList.size(); i++) { +//_restart: if (streamList[i].d.core().is_enabled()) { long numPackets, numBursts; @@ -619,8 +625,6 @@ void PortInfo::update() numBursts, numPackets); qDebug("ibg = %ld, ipg = %ld\n", ibg, ipg); - pktHdr.ts.tv_sec = 0; - pktHdr.ts.tv_usec = 0; for (int j = 0; j < numBursts; j++) { for (int k = 0; k < numPackets; k++) @@ -655,6 +659,9 @@ void PortInfo::update() #endif } + qDebug("q(%d, %d, %d) sec = %lu usec = %lu", + i, j, k, pktHdr.ts.tv_sec, pktHdr.ts.tv_usec); + if (-1 == pcap_sendqueue_queue(sendQ.sendQueue, &pktHdr, (u_char*) pktBuf)) { @@ -664,17 +671,48 @@ void PortInfo::update() else sendQ.sendQueueCumLen.append(sendQ.sendQueue->len); } - } + } // for (numPackets) pktHdr.ts.tv_usec += ibg; if (pktHdr.ts.tv_usec > 1000000) { pktHdr.ts.tv_sec++; pktHdr.ts.tv_usec -= 1000000; } - } - } - } + } // for (numBursts) + switch(streamList[i].d.control().next()) + { + case ::OstProto::StreamControl::e_nw_stop: + goto _stop_no_more_pkts; + + case ::OstProto::StreamControl::e_nw_goto_id: + // TODO(MED): define and use + // streamList[i].d.control().goto_stream_id(); + + // TODO(MED): assumes goto Id is less than current!!!! + // To support goto to any id, do + // if goto_id > curr_id then + // i = goto_id; + // goto restart; + // else + // returnToQIdx = 0; + + returnToQIdx=0; + goto _stop_no_more_pkts; + + case ::OstProto::StreamControl::e_nw_goto_next: + break; + + default: + qFatal("---------- %s: Unhandled case (%d) -----------", + __FUNCTION__, streamList[i].d.control().next() ); + break; + } + + } // if (stream is enabled) + } // for (numStreams) + +_stop_no_more_pkts: // The last alloc'ed sendQ appended here sendQueueList.append(sendQ); @@ -1061,8 +1099,9 @@ void PortInfo::PortTransmitter::run() m_stop = 0; ost_pcap_sendqueue_list_transmit(port->devHandleRx, port->sendQueueList, - true, &m_stop, &port->pcapExtra.txPkts, &port->pcapExtra.txBytes, - QThread::usleep); + port->returnToQIdx, true, &m_stop, + &port->pcapExtra.txPkts, &port->pcapExtra.txBytes, + QThread::usleep); m_stop = 0; } diff --git a/server/myservice.h b/server/myservice.h index 7f1cb88..bbf019c 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -133,6 +133,7 @@ class PortInfo pcap_t *devHandleRx; pcap_t *devHandleTx; QList sendQueueList; + int returnToQIdx; // FIXME(MED): combine with sendQList bool isSendQueueDirty; PcapExtra pcapExtra; PortMonitorRx monitorRx; diff --git a/server/pcapextra.cpp b/server/pcapextra.cpp index 78d57e0..3246397 100644 --- a/server/pcapextra.cpp +++ b/server/pcapextra.cpp @@ -62,20 +62,32 @@ int pcap_sendqueue_queue (pcap_send_queue *queue, #endif u_int ost_pcap_sendqueue_list_transmit(pcap_t *p, - QList sendQueueList, int sync, + QList sendQueueList, int returnToQIdx, int sync, int *p_stop, quint64* p_pkts, quint64* p_bytes, void (*pf_usleep)(ulong)) { - uint ret = 0; + uint i, ret = 0; + ost_pcap_send_queue sq; - foreach(ost_pcap_send_queue sq, sendQueueList) + for(i = 0; i < sendQueueList.size(); i++) { +_restart: + sq = sendQueueList.at(i); ret += ost_pcap_sendqueue_transmit(p, sq.sendQueue, sync, p_stop, p_pkts, p_bytes, pf_usleep); + if (*p_stop) + return ret; + // TODO(HI): Timing between subsequent sendQueues } + if (returnToQIdx >= 0) + { + i = returnToQIdx; + goto _restart; + } + return ret; } diff --git a/server/pcapextra.h b/server/pcapextra.h index 3d2f8f4..5c597df 100644 --- a/server/pcapextra.h +++ b/server/pcapextra.h @@ -17,7 +17,7 @@ struct ost_pcap_send_queue // Common for all OS - *nix or Win32 u_int ost_pcap_sendqueue_list_transmit(pcap_t *p, - QList sendQueueList, int sync, + QList sendQueueList, int returnToQIdx, int sync, int *p_stop, quint64* p_pkts, quint64* p_bytes, void (*pf_usleep)(ulong)); From 238f332ac43005c0136b1995b174fdf74b1ca90d Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 5 Apr 2009 07:19:37 +0000 Subject: [PATCH 19/98] - About Dialog added - Stream Dialog now remembers the "selected" tabs across close and reopen - Other trivial UI enhancements --- client/about.ui | 206 +++++++++++++++------------ client/icons/portstats_clear.png | Bin 0 -> 367 bytes client/icons/portstats_clear_all.png | Bin 0 -> 736 bytes client/mainwindow.cpp | 41 ++++-- client/mainwindow.h | 15 +- client/mainwindow.ui | 117 +-------------- client/ostinato.pro | 1 + client/ostinato.qrc | 2 + client/portstatsfilter.ui | 6 +- client/portstatsmodel.cpp | 4 +- client/portstatswindow.ui | 6 + client/portswindow.cpp | 3 + client/portswindow.ui | 122 ++++++++-------- client/stream.cpp | 5 +- client/stream.h | 3 + client/streamconfigdialog.cpp | 12 +- client/streamconfigdialog.h | 6 + client/streamconfigdialog.ui | 2 +- server/pcapextra.cpp | 3 + 19 files changed, 271 insertions(+), 283 deletions(-) create mode 100644 client/icons/portstats_clear.png create mode 100644 client/icons/portstats_clear_all.png diff --git a/client/about.ui b/client/about.ui index 2256d60..c7f914c 100644 --- a/client/about.ui +++ b/client/about.ui @@ -1,88 +1,118 @@ - - Dialog - - - - 0 - 0 - 400 - 300 - - - - Dialog - - - - - - QFrame::Box - - - QFrame::Raised - - - - - - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:29pt; font-weight:600;">Ostinato</span></p></body></html> - - - Qt::AlignCenter - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - Dialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Dialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - + + About + + + + 0 + 0 + 400 + 300 + + + + About + + + + + + QFrame::Box + + + QFrame::Raised + + + + + + Qt::Vertical + + + + 360 + 51 + + + + + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:29pt; font-weight:600;">Ostinato</span></p></body></html> + + + Qt::AlignCenter + + + + + + + Copyright (c) 2007-2009 Srivats P. + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Icons (c): Mark James (http://www.famfamfam.com/lab/icons/silk/) + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + About + accept() + + + 353 + 280 + + + 286 + 262 + + + + + diff --git a/client/icons/portstats_clear.png b/client/icons/portstats_clear.png new file mode 100644 index 0000000000000000000000000000000000000000..48cfa9756ffa84b209ef6e18cfdb75c139d1c9f5 GIT binary patch literal 367 zcmV-#0g(QQP)%zBB+uQIj;+Mu^GVlA1NAvn$4NnL{6}C{AT#~>o>#S z&z~7SfBN?S|KESVKw$uM1yKCYN7a}+;#ge(RJ8Ng=jT5^K70A|)5|wMSw;OAxH)7P z1!Y6n|NmiT|M&CHQe@3w0CE8?{ONMb|9h+S{@-4rG69zwtkDPp4>stWXXjRA`1|Xd zgi7@7mn5Zw`)jqX0{tr@8L*j=fe^svtUD{z&GC5+8KcAkIbh&369D%X=xO)W1B(Cv N002ovPDHLkV1h;6wt@@v-Jo56-xpcZCLFvFo+sh%yoi{VZ?9B7cjqH@ z8!|K0K+I4z)ErSm)DSg96%|L#evN4{_Y+flvN@i^7vC@LifQSMZsr<)pJA<0#?&w| zOa&KZT_b+%+Dp|_hzX*?r~AGp1Wm_0Rk|^m+?;%ybY_6erk!{YJP6vXQ(u{gS1-+DVsvCiz+&=4Z_!gK zprJ`^=?3>+I>|eGM~G4xHY`4{oCq*90 zHfq~Hqng;lg=?$CiB$~Pv85Boz}<0ozC3%&%PVDHJU8YKX5RO?@Ai3R;RkPKA6bUws5yfGJ=?vs`Qc_KTWo0goouiTL-$h^=J)M zL(O?@u!DuWRi0($mT-4AOn) #include "mainwindow.h" -#include "portswindow.h" -#include "portstatswindow.h" #include "portgrouplist.h" +#include "ui_about.h" + PortGroupList *pgl; MainWindow::MainWindow(QWidget *parent) @@ -11,20 +10,38 @@ MainWindow::MainWindow(QWidget *parent) { pgl = new PortGroupList; - PortsWindow *portsWindow = new PortsWindow(pgl, this); - PortStatsWindow *statsWindow = new PortStatsWindow(pgl, this); - QDockWidget *dock = new QDockWidget(tr("Ports"), this); - QDockWidget *dock2 = new QDockWidget(tr("Stats"), this); + portsWindow = new PortsWindow(pgl, this); + statsWindow = new PortStatsWindow(pgl, this); + portsDock = new QDockWidget(tr("Ports"), this); + statsDock = new QDockWidget(tr("Stats"), this); setupUi(this); - dock2->setWidget(statsWindow); - addDockWidget(Qt::BottomDockWidgetArea, dock2); - dock->setWidget(portsWindow); - addDockWidget(Qt::TopDockWidgetArea, dock); + statsDock->setWidget(statsWindow); + addDockWidget(Qt::BottomDockWidgetArea, statsDock); + portsDock->setWidget(portsWindow); + addDockWidget(Qt::TopDockWidgetArea, portsDock); + + connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close())); } -void MainWindow::on_actionPreferences_triggered() +MainWindow::~MainWindow() { + delete statsDock; + delete portsDock; + delete statsWindow; + delete portsWindow; +} + +void MainWindow::on_actionHelpAbout_triggered() +{ + QDialog *aboutDialog = new QDialog; + + Ui::About about; + about.setupUi(aboutDialog); + + aboutDialog->exec(); + + delete aboutDialog; } diff --git a/client/mainwindow.h b/client/mainwindow.h index da412ec..a5d31a6 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -2,16 +2,29 @@ #define _MAIN_WINDOW_H #include +#include + #include "ui_mainwindow.h" +#include "portswindow.h" +#include "portstatswindow.h" + class MainWindow : public QMainWindow, private Ui::MainWindow { Q_OBJECT + +private: + PortsWindow *portsWindow; + PortStatsWindow *statsWindow; + QDockWidget *portsDock; + QDockWidget *statsDock; + public: MainWindow(QWidget *parent = 0); + ~MainWindow(); public slots: - void on_actionPreferences_triggered(); + void on_actionHelpAbout_triggered(); }; #endif diff --git a/client/mainwindow.ui b/client/mainwindow.ui index 98ab4c2..1f93f5e 100644 --- a/client/mainwindow.ui +++ b/client/mainwindow.ui @@ -10,7 +10,7 @@ - MainWindow + Ostinato @@ -26,131 +26,26 @@ File - - - - - View - - - - - - Window - - - - - - - - + Help - + - - - - - Open Config - - - - - Save Config - - - - - Save Config As ... - - - - - Open Capture - - - - - Save Capture - - - - - Save Capture As ... - - - + E&xit - + - Copy Port Config - - - - - Paste Port Config - - - - - Preferences - - - - - Minimize - - - - - Maximize/Restore - - - - - Minimize All - - - - - Maximize/Restoe All - - - - - Arrange All - Cascade - - - - - Arrange All - Tile - - - - - Dock - - - - - Help - - - - - About + &About diff --git a/client/ostinato.pro b/client/ostinato.pro index ec44eb0..9bb3cd2 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -24,6 +24,7 @@ HEADERS += \ streammodel.h FORMS += \ + about.ui \ mainwindow.ui \ portstatsfilter.ui \ portstatswindow.ui \ diff --git a/client/ostinato.qrc b/client/ostinato.qrc index 09fdd4a..7b735f7 100644 --- a/client/ostinato.qrc +++ b/client/ostinato.qrc @@ -12,6 +12,8 @@ icons/portgroup_connect.png icons/portgroup_delete.png icons/portgroup_disconnect.png + icons/portstats_clear.png + icons/portstats_clear_all.png icons/portstats_filter.png icons/sound_mute.png icons/sound_none.png diff --git a/client/portstatsfilter.ui b/client/portstatsfilter.ui index a681c65..8423db3 100644 --- a/client/portstatsfilter.ui +++ b/client/portstatsfilter.ui @@ -5,12 +5,12 @@ 0 0 - 588 - 320 + 319 + 193 - Dialog + Select Ports diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index bcc0f54..9961e12 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -171,9 +171,9 @@ QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, in getDomainIndexes(index(0, section), portGroupIdx, portIdx); #ifdef Q_OS_WIN32 - return QString("Port %1/%2 (*)").arg(portGroupIdx).arg(portIdx); + return QString("Port %1-%2 (*)").arg(portGroupIdx).arg(portIdx); #else - return QString("Port %1/%2").arg(portGroupIdx).arg(portIdx); + return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx); #endif } else diff --git a/client/portstatswindow.ui b/client/portstatswindow.ui index a7fc8d5..07fe1b2 100644 --- a/client/portstatswindow.ui +++ b/client/portstatswindow.ui @@ -65,6 +65,9 @@ Clear + + :/icons/portstats_clear.png + @@ -78,6 +81,9 @@ Clear All + + :/icons/portstats_clear_all.png + diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 1789e5e..8b75b65 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -61,6 +61,9 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) // Initially we don't have any ports/streams - so send signal triggers when_portView_currentChanged(QModelIndex(), QModelIndex()); when_streamView_currentChanged(QModelIndex(), QModelIndex()); + + //! \todo Hide the Aggregate Box till we add support + frAggregate->setHidden(true); } PortsWindow::~PortsWindow() diff --git a/client/portswindow.ui b/client/portswindow.ui index 99a32af..b58c356 100644 --- a/client/portswindow.ui +++ b/client/portswindow.ui @@ -6,7 +6,7 @@ 0 0 689 - 320 + 389 @@ -28,11 +28,11 @@ - 0 + 1 - - + + @@ -56,64 +56,59 @@ - - - - - - Qt::Horizontal - - - - 31 - 41 - - - - - - - - Capacity - - - - - - - - - - Aggr fps - - - - - - - - - - % age - - - - - - - - - - Aggr bps - - - - - - - + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Capacity + + + + + + + + + + Aggr fps + + + + + + + + + + % age + + + + + + + + + + Aggr bps + + + + + + + + - + 0 @@ -147,7 +142,10 @@ - Port Group Detail + Select a port to configure streams + + + Qt::AlignCenter diff --git a/client/stream.cpp b/client/stream.cpp index 2d82040..0afd8df 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -15,6 +15,7 @@ QString PayloadProtocol::fieldTextValue(int index) if (parentStream) { + qDebug("phs = %d", parentStream->protocolHeaderSize()); len = parentStream->frameLen() - parentStream->protocolHeaderSize(); pat = parentStream->pattern(); } @@ -48,6 +49,7 @@ QByteArray PayloadProtocol::fieldRawValue(int index) if (parentStream) { + qDebug("phs = %d", parentStream->protocolHeaderSize()); len = parentStream->frameLen() - parentStream->protocolHeaderSize(); pat = parentStream->pattern(); } @@ -1015,7 +1017,8 @@ bool Stream::update(OstProto::Stream *stream) mIp->update(stream->ip()); mArp->update(stream->arp()); - mTcp->update(stream->tcp()); + //mTcp->update(stream->tcp()); + mTcp->setProtoData(stream->mutable_tcp()); mUdp->update(stream->udp()); mIcmp->update(stream->icmp()); mIgmp->update(stream->igmp()); diff --git a/client/stream.h b/client/stream.h index 6e41702..434c008 100644 --- a/client/stream.h +++ b/client/stream.h @@ -33,6 +33,9 @@ public: void getConfig(::google::protobuf::Message *msg) { msg->CopyFrom(data()); } + bool setProtoData(::google::protobuf::Message *msg) + { data().MergeFrom(*msg); return true; } + virtual QString protocolName() { return QString("AbstractProtocol"); } virtual QString protocolShortName() diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index e7f1f0b..8b99561 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -4,6 +4,9 @@ #include "modeltest.h" +int StreamConfigDialog::lastTopLevelTabIndex = 0; +int StreamConfigDialog::lastProtoTabIndex = 0; + // TODO(HI): Write HexLineEdit::setNum() and num() and use it in // Load/Store stream methods @@ -177,6 +180,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool))); //! \todo Support Continuous Mode rbModeContinuous->setDisabled(true); + + // Finally, restore the saved last selected tab for the various tab widgets + twTopLevel->setCurrentIndex(lastTopLevelTabIndex); + if (twProto->isTabEnabled(lastProtoTabIndex)) + twProto->setCurrentIndex(lastProtoTabIndex); } void StreamConfigDialog::setupUiExtra() @@ -230,8 +238,6 @@ void StreamConfigDialog::setupUiExtra() connect(rbModeContinuous, SIGNAL(toggled(bool)), this, SLOT(update_NumPacketsAndNumBursts())); - // Show "Packet Config" page by default - twTopLevel->setCurrentIndex(0); } StreamConfigDialog::~StreamConfigDialog() @@ -1115,6 +1121,8 @@ void StreamConfigDialog::on_pbOk_clicked() // Store dialog contents into stream StoreCurrentStream(); qDebug("stream stored"); + lastTopLevelTabIndex = twTopLevel->currentIndex(); + lastProtoTabIndex = twProto->currentIndex(); } //Junk Line for introducing a compiler error diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index a8fe510..7dbedbe 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -34,6 +34,12 @@ private: PacketModel *mpPacketModel; ModelTest *mpPacketModelTester; + // The following static variables are used to track the "selected" tab + // for the various tab widgets so that it can be restored when the dialog + // is opened the next time + static int lastTopLevelTabIndex; + static int lastProtoTabIndex; + void setupUiExtra(); void LoadCurrentStream(); void StoreCurrentStream(); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 178e966..70fea95 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -13,7 +13,7 @@ - Dialog + Edit Stream QLineEdit:enabled[inputMask = "HH; "], diff --git a/server/pcapextra.cpp b/server/pcapextra.cpp index 3246397..4ad8a51 100644 --- a/server/pcapextra.cpp +++ b/server/pcapextra.cpp @@ -85,6 +85,9 @@ _restart: if (returnToQIdx >= 0) { i = returnToQIdx; + + // FIXME: 1s fixed; Change this to ipg of last stream + (*pf_usleep)(1000000); goto _restart; } From 2d856012cb0fe18564e0d31c3045084b59127177 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 27 Apr 2009 16:51:44 +0000 Subject: [PATCH 20/98] New Protocol Framework - initial checkin; not yet complete --- Makefile | 7 +- client/dumpview.cpp | 99 +- client/hexlineedit.cpp | 8 +- client/mainwindow.cpp | 14 +- client/ostinato.pro | 10 +- client/packetmodel.cpp | 56 +- client/packetmodel.h | 93 +- client/port.cpp | 27 +- client/port.h | 4 +- client/portgroup.cpp | 3 +- client/portstatsfilter.ui | 7 +- client/stream.cpp | 1300 +++----------------------- client/stream.h | 905 +------------------ client/streamconfigdialog.cpp | 860 +++++++----------- client/streamconfigdialog.h | 21 +- client/streamconfigdialog.ui | 1601 +-------------------------------- client/streammodel.cpp | 12 +- common/Makefile | 14 - common/abstractprotocol.cpp | 225 +++++ common/abstractprotocol.h | 62 ++ common/dot3.cpp | 110 +++ common/dot3.h | 50 + common/dot3.proto | 12 + common/dot3.ui | 59 ++ common/eth2.cpp | 129 +++ common/eth2.h | 50 + common/eth2.proto | 12 + common/eth2.ui | 62 ++ common/ip4.cpp | 455 ++++++++++ common/ip4.h | 83 ++ common/ip4.proto | 47 + common/ip4.ui | 479 ++++++++++ common/llc.cpp | 139 +++ common/llc.h | 55 ++ common/llc.proto | 13 + common/llc.ui | 108 +++ common/mac.cpp | 207 +++++ common/mac.h | 63 ++ common/mac.proto | 29 + common/mac.ui | 190 ++++ common/ostproto.pro | 63 ++ common/payload.cpp | 176 ++++ common/payload.h | 55 ++ common/payload.proto | 22 + common/payload.ui | 69 ++ common/protocol.h | 169 ---- common/protocol.proto | 196 +--- common/snap.cpp | 112 +++ common/snap.h | 50 + common/snap.proto | 12 + common/snap.ui | 89 ++ common/tcp.cpp | 360 ++++++++ common/tcp.h | 69 ++ common/tcp.proto | 27 + common/tcp.ui | 228 +++++ common/udp.cpp | 200 ++++ common/udp.h | 56 ++ common/udp.proto | 18 + common/udp.ui | 101 +++ common/vlan.proto | 17 + common/vlan.ui | 168 ++++ rpc/pbrpc.pro | 7 +- server/drone.pro | 6 +- server/myservice.cpp | 186 +++- server/myservice.h | 19 +- 65 files changed, 5349 insertions(+), 4806 deletions(-) delete mode 100644 common/Makefile create mode 100644 common/abstractprotocol.cpp create mode 100644 common/abstractprotocol.h create mode 100644 common/dot3.cpp create mode 100644 common/dot3.h create mode 100644 common/dot3.proto create mode 100644 common/dot3.ui create mode 100644 common/eth2.cpp create mode 100644 common/eth2.h create mode 100644 common/eth2.proto create mode 100644 common/eth2.ui create mode 100644 common/ip4.cpp create mode 100644 common/ip4.h create mode 100644 common/ip4.proto create mode 100644 common/ip4.ui create mode 100644 common/llc.cpp create mode 100644 common/llc.h create mode 100644 common/llc.proto create mode 100644 common/llc.ui create mode 100644 common/mac.cpp create mode 100644 common/mac.h create mode 100644 common/mac.proto create mode 100644 common/mac.ui create mode 100644 common/ostproto.pro create mode 100644 common/payload.cpp create mode 100644 common/payload.h create mode 100644 common/payload.proto create mode 100644 common/payload.ui delete mode 100644 common/protocol.h create mode 100644 common/snap.cpp create mode 100644 common/snap.h create mode 100644 common/snap.proto create mode 100644 common/snap.ui create mode 100644 common/tcp.cpp create mode 100644 common/tcp.h create mode 100644 common/tcp.proto create mode 100644 common/tcp.ui create mode 100644 common/udp.cpp create mode 100644 common/udp.h create mode 100644 common/udp.proto create mode 100644 common/udp.ui create mode 100644 common/vlan.proto create mode 100644 common/vlan.ui diff --git a/Makefile b/Makefile index 8b555c4..c285580 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ all: - $(MAKE) -C rpc install + $(MAKE) -C rpc $(MAKE) -C common $(MAKE) -C server $(MAKE) -C client @@ -11,4 +11,7 @@ clean: $(MAKE) -C client $@ qmake: - for %%d in (rpc common server client) cd %%d; qmake; cd..; + cd rpc && qmake && cd .. + cd common && qmake && cd .. + cd server && qmake && cd .. + cd client && qmake && cd .. diff --git a/client/dumpview.cpp b/client/dumpview.cpp index 79edab9..3393d5b 100644 --- a/client/dumpview.cpp +++ b/client/dumpview.cpp @@ -1,6 +1,7 @@ #include "dumpview.h" -//public: +//! \todo Enable Scrollbars + DumpView::DumpView(QWidget *parent) { int w, h; @@ -78,8 +79,8 @@ QModelIndex DumpView::indexAt( const QPoint &point ) const _exit: // Clear existing selection selrow = -1; -#endif +#endif return QModelIndex(); } @@ -148,55 +149,73 @@ void DumpView::selectionChanged( const QItemSelection &selected, void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize, QModelIndex parent) { - // TODO(LOW): Assumption - only single selection - enforce/ensure this + // FIXME: Use new enum instead of Qt::UserRole + //! \todo (low): generalize this for any model not just our pkt model + + Q_ASSERT(!parent.isValid()); + + qDebug("!!!! %d $$$$", dump.size()); for(int i = 0; i < model()->rowCount(parent); i++) { QModelIndex index = model()->index(i, 0, parent); - if (model()->hasChildren(index)) - { - // Non Leaf + Q_ASSERT(index.isValid()); - // A non-leaf has no dump data of its own but is rather a - // container for its children. So we calculate ofs/size based - // on this fact - if (selectionModel()->isSelected(index)) + // Assumption: protocol data is in bytes (not bits) + qDebug("%d: %d bytes", i, model()->data(index, Qt::UserRole).toByteArray().size()); + dump.append(model()->data(index, Qt::UserRole).toByteArray()); + + } + + if (selectionModel()->selectedIndexes().size()) + { + int j, bits; + QModelIndex index; + + Q_ASSERT(selectionModel()->selectedIndexes().size() == 1); + index = selectionModel()->selectedIndexes().at(0); + + if (index.parent().isValid()) + { + // Field + + // SelOfs = SUM(protocol sizes before selected field's protocol) + + // SUM(field sizes before selected field) + + selOfs = 0; + j = index.parent().row() - 1; + while (j >= 0) { - selOfs = dump.size(); - populateDump(dump, selOfs, selSize, index); - selSize = dump.size() - selOfs; + selOfs += model()->data(index.parent().sibling(j,0), + Qt::UserRole).toByteArray().size(); + j--; } - else + + bits = 0; + j = index.row() - 1; + while (j >= 0) { - populateDump(dump, selOfs, selSize, index); + bits += model()->data(index.sibling(j,0), Qt::UserRole+1). + toInt(); + j--; } + selOfs += bits/8; + selSize = model()->data(index, Qt::UserRole).toByteArray().size(); } else { - // Leaf - if (selectionModel()->isSelected(index)) + // Protocol + selOfs = 0; + j = index.row() - 1; + while (j >= 0) { - int size, j; - - selOfs = dump.size(); - size = model()->data(index, Qt::UserRole).toByteArray().size(); - - // Take care of multiple indexes (2 or more) mapping onto - // same dump byte(s) - j = i-1; - while ((size == 0) && (j >= 0)) - { - size = model()->data(index.sibling(j,0), Qt::UserRole). - toByteArray().size(); - selOfs -= size; - j++; - } - selSize = size; + selOfs += model()->data(index.sibling(j,0), Qt::UserRole). + toByteArray().size(); + j--; } - dump.append(model()->data(index, Qt::UserRole).toByteArray()); - } - // FIXME: Use RawValueRole instead of UserRole + selSize = model()->data(index, Qt::UserRole).toByteArray().size(); + } } } @@ -208,7 +227,7 @@ void DumpView::paintEvent(QPaintEvent* event) QRect dumpRect = mDumpPaneTopRect; QRect asciiRect = mAsciiPaneTopRect; QPalette pal = palette(); - QByteArray data; + static QByteArray data; //QByteArray ba; int selOfs = -1, selSize; int curSelOfs, curSelSize; @@ -222,7 +241,10 @@ void DumpView::paintEvent(QPaintEvent* event) painter.fillRect(rect(), QBrush(QColor(Qt::white))); if (model()) + { + data.clear(); populateDump(data, selOfs, selSize); + } // display the offset, dump and ascii panes 8 + 8 bytes on a line for (int i = 0; i < data.size(); i+=16) @@ -289,7 +311,8 @@ void DumpView::paintEvent(QPaintEvent* event) QRect r; QString selectedAsciiStr, selectedDumpStr; - qDebug("dumpview::paintEvent - Highlighted"); + qDebug("dumpview::paintEvent - Highlighted (%d, %d)", + curSelOfs, curSelSize); // construct the dumpStr and asciiStr for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++) diff --git a/client/hexlineedit.cpp b/client/hexlineedit.cpp index 85d5ccf..dcb6c20 100644 --- a/client/hexlineedit.cpp +++ b/client/hexlineedit.cpp @@ -39,15 +39,17 @@ void HexLineEdit::focusOutEvent( QFocusEvent *e ) QLineEdit::focusOutEvent( e ); emit focusOut(); #else +#define uintToHexStr(num, bytesize) \ + QString("%1").arg((num), (bytesize)*2 , 16, QChar('0')) + bool isOk; ulong num; - QString str; qDebug("before = %s\n", text().toAscii().data()); num = text().remove(QChar(' ')).toULong(&isOk, 16); - setText(uintToHexStr(num, str, 4)); + setText(uintToHexStr(num, 4)); qDebug("after = %s\n", text().toAscii().data()); - qDebug("after2 = %s\n", str.toAscii().data()); +#undef uintToHexStr #endif } diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 4e6fb64..0a0e0fb 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -1,6 +1,10 @@ #include "mainwindow.h" #include "portgrouplist.h" +#if 0 +#include "dbgthread.h" +#endif + #include "ui_about.h" PortGroupList *pgl; @@ -23,14 +27,16 @@ MainWindow::MainWindow(QWidget *parent) addDockWidget(Qt::TopDockWidgetArea, portsDock); connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close())); +#if 0 + { + DbgThread *dbg = new DbgThread(pgl); + dbg->start(); + } +#endif } MainWindow::~MainWindow() { - delete statsDock; - delete portsDock; - delete statsWindow; - delete portsWindow; } void MainWindow::on_actionHelpAbout_triggered() diff --git a/client/ostinato.pro b/client/ostinato.pro index 9bb3cd2..707969e 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -1,10 +1,13 @@ TEMPLATE = app CONFIG += qt debug QT += network -INCLUDEPATH += "../rpc/" +INCLUDEPATH += "../rpc/" "../common/" LIBS += -lprotobuf +win32:LIBS += -L"../common/debug" -lostproto +unix: LIBS += -L"../common" -lostproto win32:LIBS += -L"../rpc/debug" -lpbrpc unix:LIBS += -L"../rpc" -lpbrpc +POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" RESOURCES += ostinato.qrc HEADERS += \ dumpview.h \ @@ -50,10 +53,5 @@ SOURCES += \ streamlistdelegate.cpp \ streammodel.cpp -# Protocol Buffer Sources - -SOURCES += \ - ..\common\protocol.pb.cc - # TODO(LOW): Test only include(modeltest.pri) diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index a1d4b7f..f48f713 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -1,26 +1,36 @@ #include #include "packetmodel.h" -PacketModel::PacketModel(Stream *pStream, QObject *parent) +PacketModel::PacketModel(const QList &selectedProtocols, + QObject *parent) { - mpStream = pStream; + mSelectedProtocols = selectedProtocols; +} + +void PacketModel::setSelectedProtocols( + const QList &selectedProtocols) +{ + mSelectedProtocols = selectedProtocols; + reset(); } int PacketModel::rowCount(const QModelIndex &parent) const { IndexId parentId; + // qDebug("in %s", __FUNCTION__); + // Parent == Invalid i.e. Invisible Root. // ==> Children are Protocol (Top Level) Items if (!parent.isValid()) - return mpStream->numProtocols(); + return mSelectedProtocols.size(); // Parent - Valid Item parentId.w = parent.internalId(); switch(parentId.ws.type) { case ITYP_PROTOCOL: - return mpStream->protocol(parentId.ws.protocol)->numFields(); + return mSelectedProtocols.at(parentId.ws.protocol)->frameFieldCount(); case ITYP_FIELD: return 0; default: @@ -125,11 +135,13 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const switch(id.ws.type) { case ITYP_PROTOCOL: - return QByteArray(); + qDebug("*** %d/%d", id.ws.protocol, mSelectedProtocols.size()); + return mSelectedProtocols.at(id.ws.protocol)-> + protocolFrameValue(); case ITYP_FIELD: - return mpStream->protocol(id.ws.protocol)->fieldRawValue( - index.row()); + return mSelectedProtocols.at(id.ws.protocol)->fieldData( + index.row(), AbstractProtocol::FieldFrameValue); default: qWarning("%s: Unhandled ItemType", __FUNCTION__); @@ -137,6 +149,25 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const return QByteArray(); } + // FIXME: Use a new enum here instead of UserRole + if (role == (Qt::UserRole+1)) + { + switch(id.ws.type) + { + case ITYP_PROTOCOL: + return mSelectedProtocols.at(id.ws.protocol)-> + protocolFrameValue().size(); + + case ITYP_FIELD: + return mSelectedProtocols.at(id.ws.protocol)->fieldData( + index.row(), AbstractProtocol::FieldBitSize); + + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + return QVariant(); + } + if (role != Qt::DisplayRole) return QVariant(); @@ -144,13 +175,14 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const { case ITYP_PROTOCOL: return QString("%1 (%2)") - .arg(mpStream->protocol(id.ws.protocol)->protocolShortName()) - .arg(mpStream->protocol(id.ws.protocol)->protocolName()); + .arg(mSelectedProtocols.at(id.ws.protocol)->shortName()) + .arg(mSelectedProtocols.at(id.ws.protocol)->name()); case ITYP_FIELD: - return mpStream->protocol(id.ws.protocol)->fieldName(index.row()) + - QString(" : ") + - mpStream->protocol(id.ws.protocol)->fieldTextValue(index.row()); + return mSelectedProtocols.at(id.ws.protocol)->fieldData(index.row(), + AbstractProtocol::FieldName).toString() + QString(" : ") + + mSelectedProtocols.at(id.ws.protocol)->fieldData(index.row(), + AbstractProtocol::FieldTextValue).toString(); default: qWarning("%s: Unhandled ItemType", __FUNCTION__); diff --git a/client/packetmodel.h b/client/packetmodel.h index 1134a14..b268134 100644 --- a/client/packetmodel.h +++ b/client/packetmodel.h @@ -2,15 +2,16 @@ #define _PACKET_MODEL_H #include -#include "stream.h" - -#define NEW_IMPL // FIXME(HI) - Use this and remove old one +#include "abstractprotocol.h" class PacketModel: public QAbstractItemModel { public: - PacketModel(Stream *pStream, QObject *parent = 0); + PacketModel(const QList &selectedProtocols, + QObject *parent = 0); + void setSelectedProtocols( + const QList &selectedProtocols); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; @@ -33,89 +34,7 @@ private: } ws; } IndexId; - Stream *mpStream; - -#ifdef NEW_IMPL -// Nothing - required stuff is part of Stream Class -#else - QList mPacketProtocols; - - typedef struct - { - QString name; - QString abbr; - QString textValue; - } FieldInfo; - - typedef struct - { - uint handle; - QString name; - QString abbr; - QList fieldList; - } ProtocolInfo; - - //! Contains registration info (name, size etc) for all protocols - // and fields within the protocol - QList mProtocols; - void registerProto(uint handle, char *name, char *abbr); - void registerField(uint protoHandle, char *name, char *abbr); - - void registerFrameTypeProto(); - void registerVlanProto(); - void registerIpProto(); - void registerArpProto(); - void registerTcpProto(); - void registerUdpProto(); - void registerIcmpProto(); - void registerIgmpProto(); - void registerData(); - void registerInvalidProto(); - - void populatePacketProtocols(); - - int protoCount() const; - int fieldCount(int protocol) const; - QString protoName(int protocol) const; - QString fieldName(int protocol, int field) const; - QVariant fieldTextValue(int protocol, int field) const; - - QVariant ethField(int field, int role) const; - QVariant llcField(int field, int role) const; - QVariant snapField(int field, int role) const; - QVariant svlanField(int field, int role) const; - QVariant ipField(int field, int role) const; - QVariant tcpField(int field, int role) const; - QVariant udpField(int field, int role) const; - -// FIXME(HIGH): Is this how I want this? -#define PTYP_L2_NONE 1 -#define PTYP_L2_ETH_2 2 -#define PTYP_L2_802_3_RAW 3 - -#define PTYP_L2_802_3_LLC 4 -#define PTYP_L2_SNAP 5 - -#define PTYP_SVLAN 10 -#define PTYP_CVLAN 11 - -#define PTYP_L3_IP 30 -#define PTYP_L3_ARP 31 - -#define PTYP_L4_TCP 40 -#define PTYP_L4_UDP 41 -#define PTYP_L4_ICMP 42 -#define PTYP_L4_IGMP 43 - -#define PTYP_INVALID 0 -#define PTYP_DATA 0xFF - -#endif // NEW_IMPL - -#define FROL_NAME 1 -#define FROL_TEXT_VALUE 2 - -#define BASE_HEX 16 + QList mSelectedProtocols; }; #endif diff --git a/client/port.cpp b/client/port.cpp index 3ee571e..64c7865 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -32,7 +32,7 @@ void Port::updatePortConfig(OstProto::Port *port) void Port::updateStreamOrdinalsFromIndex() { for (int i=0; i < mStreams.size(); i++) - mStreams[i].setOrdinal(i); + mStreams[i]->setOrdinal(i); } void Port::reorderStreamsByOrdinals() @@ -42,12 +42,12 @@ void Port::reorderStreamsByOrdinals() bool Port::newStreamAt(int index) { - Stream s; + Stream *s = new Stream; if (index > mStreams.size()) return false; - s.setId(newStreamId()); + s->setId(newStreamId()); mStreams.insert(index, s); updateStreamOrdinalsFromIndex(); @@ -59,7 +59,7 @@ bool Port::deleteStreamAt(int index) if (index >= mStreams.size()) return false; - mStreams.removeAt(index); + delete mStreams.takeAt(index); updateStreamOrdinalsFromIndex(); return true; @@ -67,9 +67,9 @@ bool Port::deleteStreamAt(int index) bool Port::insertStream(uint streamId) { - Stream s; + Stream *s = new Stream; - s.setId(streamId); + s->setId(streamId); // FIXME(MED): If a stream with id already exists, what do we do? mStreams.append(s); @@ -88,7 +88,7 @@ bool Port::updateStream(uint streamId, OstProto::Stream *stream) for (i = 0; i < mStreams.size(); i++) { - if (streamId == mStreams[i].id()) + if (streamId == mStreams[i]->id()) goto _found; } @@ -98,7 +98,7 @@ bool Port::updateStream(uint streamId, OstProto::Stream *stream) _found: streamIndex = i; - mStreams[streamIndex].update(stream); + mStreams[streamIndex]->update(stream); reorderStreamsByOrdinals(); return true; @@ -114,7 +114,7 @@ void Port::getDeletedStreamsSinceLastSync( for (j = 0; j < mStreams.size(); j++) { - if (mLastSyncStreamList[i] == mStreams[j].id()) + if (mLastSyncStreamList[i] == mStreams[j]->id()) break; } @@ -140,7 +140,7 @@ void Port::getNewStreamsSinceLastSync( streamIdList.clear_stream_id(); for (int i = 0; i < mStreams.size(); i++) { - if (mLastSyncStreamList.contains(mStreams[i].id())) + if (mLastSyncStreamList.contains(mStreams[i]->id())) { // existing stream! continue; @@ -151,7 +151,7 @@ void Port::getNewStreamsSinceLastSync( OstProto::StreamId *s; s = streamIdList.add_stream_id(); - s->set_id(mStreams[i].id()); + s->set_id(mStreams[i]->id()); } } } @@ -167,8 +167,9 @@ void Port::getModifiedStreamsSinceLastSync( OstProto::Stream *s; s = streamConfigList.add_stream(); - mStreams[i].getConfig(mPortId, s); + mStreams[i]->getConfig(mPortId, *s); } + qDebug("Done %s", __FUNCTION__); } void Port::when_syncComplete() @@ -177,7 +178,7 @@ void Port::when_syncComplete() mLastSyncStreamList.clear(); for (int i=0; iid()); } void Port::updateStats(OstProto::PortStats *portStats) diff --git a/client/port.h b/client/port.h index c10eeb3..126b28d 100644 --- a/client/port.h +++ b/client/port.h @@ -23,7 +23,7 @@ private: QString mUserAlias; // user defined QList mLastSyncStreamList; - QList mStreams; // sorted by stream's ordinal value + QList mStreams; // sorted by stream's ordinal value uint newStreamId(); void updateStreamOrdinalsFromIndex(); @@ -65,7 +65,7 @@ public: //void setExclusive(bool flag); int numStreams() { return mStreams.size(); } - Stream& streamByIndex(int index) + Stream* streamByIndex(int index) { Q_ASSERT(index < mStreams.size()); return mStreams[index]; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 4630c72..f9f84d2 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -1,5 +1,4 @@ #include "portgroup.h" -#include "../common/protocol.h" #include @@ -400,7 +399,7 @@ _request: OstProto::StreamId *s; s = streamIdList.add_stream_id(); - s->set_id(mPorts[portIndex].streamByIndex(j).id()); + s->set_id(mPorts[portIndex].streamByIndex(j)->id()); } streamConfigList->Clear(); diff --git a/client/portstatsfilter.ui b/client/portstatsfilter.ui index 8423db3..af9af02 100644 --- a/client/portstatsfilter.ui +++ b/client/portstatsfilter.ui @@ -12,6 +12,9 @@ Select Ports + + :/icons/portstats_filter.png + @@ -121,7 +124,9 @@ lvSelected buttonBox - + + + buttonBox diff --git a/client/stream.cpp b/client/stream.cpp index 0afd8df..3af3509 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -3,951 +3,21 @@ #include "stream.h" -#include - -#define BASE_HEX 16 - -QString PayloadProtocol::fieldTextValue(int index) -{ - int len; - quint32 pat; - QString textValue; - - if (parentStream) - { - qDebug("phs = %d", parentStream->protocolHeaderSize()); - len = parentStream->frameLen() - parentStream->protocolHeaderSize(); - pat = parentStream->pattern(); - } - else - { - len = 1500; // FIXME(HI): testing only - pat = 0x0a0b0c0d; - } - - // Make a larger string and then resize to the correct size to - // take care of the case where len is not a multiple of pattern size - if (len > 0) - { - // TODO(LOW): allow non-4byte patterns!!! - int w = 4; // data pattern size - - for (int i = 0; i < (len/w + 1); i++) - textValue.append(QString("%1").arg( - pat, w*2, BASE_HEX, QChar('0'))); - textValue.resize(len); - } - - return textValue; -} - -QByteArray PayloadProtocol::fieldRawValue(int index) -{ - int len; - quint32 pat; - QByteArray rawValue; - - if (parentStream) - { - qDebug("phs = %d", parentStream->protocolHeaderSize()); - len = parentStream->frameLen() - parentStream->protocolHeaderSize(); - pat = parentStream->pattern(); - } - else - { - len = 1500; // FIXME(HI): testing only - pat = 0x0a0b0c0d; - } - - // Make a larger byteArray and then resize to the correct size to - // take care of the case where len is not a multiple of pattern size - if (len > 0) - { - // TODO(LOW): allow non-4byte patterns!!! - int w = 4; // data pattern size - - rawValue.resize(len + 4); - for (int i = 0; i < (len/w + 1); i++) - qToBigEndian(pat, (uchar*) (rawValue.data() + i*sizeof(pat))); - rawValue.resize(len); - } - - return rawValue; -} - -QString MacProtocol::fieldName(int index) -{ - QString name; - - switch(index) - { - case 0: - name = QString("Destination Mac Address"); - break; - case 1: - name = QString("Source Mac Address"); - break; - default: - name = QString(); - break; - } - - return name; -} - -QString MacProtocol::fieldTextValue(int index) -{ - QString textValue; - - // FIXME(MED): Mac Addr formatting - switch(index) - { - case 0: - textValue = QString("%1"). - arg(dstMac(), 12, BASE_HEX, QChar('0')); - break; - case 1: - textValue = QString("%1"). - arg(srcMac(), 12, BASE_HEX, QChar('0')); - break; - default: - textValue = QString(); - break; - } - - return textValue; -} - -QByteArray MacProtocol::fieldRawValue(int index) -{ - QByteArray rawValue; - - switch(index) - { - case 0: - rawValue.resize(8); - qToBigEndian(dstMac(), (uchar *) rawValue.data()); - rawValue.remove(0, 2); - qDebug("dstMac(%d): %s", rawValue.size(), rawValue.toHex().constData()); - break; - case 1: - rawValue.resize(8); - qToBigEndian(srcMac(), (uchar *) rawValue.data()); - rawValue.remove(0, 2); - qDebug("srcMac(%d): %s", rawValue.size(), rawValue.toHex().constData()); - break; - default: - break; - } - - return rawValue; -} - -QString LlcProtocol::fieldName(int index) -{ - QString name; - - switch(index) - { - case 0: - name = QString("DSAP"); - break; - case 1: - name = QString("SSAP"); - break; - case 2: - name = QString("Control"); - break; - default: - name = QString(); - break; - } - - return name; -} - -QString LlcProtocol::fieldTextValue(int index) -{ - QString textValue; - - switch(index) - { - case 0: - textValue = QString("0x%1"). - arg(dsap(), 2, BASE_HEX, QChar('0')); - break; - case 1: - textValue = QString("0x%1"). - arg(ssap(), 2, BASE_HEX, QChar('0')); - break; - case 2: - textValue = QString("0x%1"). - arg(ctl(), 2, BASE_HEX, QChar('0')); - break; - default: - textValue = QString(); - break; - } - - return textValue; -} - -QByteArray LlcProtocol::fieldRawValue(int index) -{ - QByteArray rawValue; - - switch(index) - { - case 0: - rawValue.resize(1); - rawValue[0] = dsap(); - break; - case 1: - rawValue.resize(1); - rawValue[0] = ssap(); - break; - case 2: - rawValue.resize(1); - rawValue[0] = ctl(); - break; - default: - break; - } - - return rawValue; -} - -QString SnapProtocol::fieldName(int index) -{ - QString name; - - switch(index) - { - case 0: - name = QString("OUI"); - break; - default: - name = QString(); - break; - } - - return name; -} - -QString SnapProtocol::fieldTextValue(int index) -{ - QString textValue; - - switch(index) - { - case 0: - textValue = QString("0x%1"). - arg(oui(), 6, BASE_HEX, QChar('0')); - break; - default: - textValue = QString(); - break; - } - - return textValue; -} - -QByteArray SnapProtocol::fieldRawValue(int index) -{ - QByteArray rawValue; - - switch(index) - { - case 0: - rawValue.resize(4); - qToBigEndian(oui(), (uchar *) rawValue.data()); - rawValue.remove(0, 1); - break; - default: - break; - } - - return rawValue; -} - -QString Eth2Protocol::fieldName(int index) -{ - QString name; - - switch(index) - { - case 0: - name = QString("Type"); - break; - default: - name = QString(); - break; - } - return name; -} - -QString Eth2Protocol::fieldTextValue(int index) -{ - QString textValue; - - switch(index) - { - case 0: - textValue = QString("0x%1"). - arg(type(), 4, BASE_HEX, QChar('0')); - break; - default: - textValue = QString(); - break; - } - return textValue; -} - -QByteArray Eth2Protocol::fieldRawValue(int index) -{ - QByteArray rawValue; - - switch(index) - { - case 0: - rawValue.resize(2); - qToBigEndian(type(), (uchar*) rawValue.data()); - break; - default: - break; - } - - return rawValue; -} - -QString Dot3Protocol::fieldName(int index) -{ - QString name; - - switch(index) - { - case 0: - name = QString("Length"); - break; - default: - name = QString(); - break; - } - return name; -} - -QString Dot3Protocol::fieldTextValue(int index) -{ - if (parentStream) - return QString("%1").arg(parentStream->frameLen()); - else - return QString("00"); -} - -QByteArray Dot3Protocol::fieldRawValue(int index) -{ - QByteArray ba; - - if (parentStream) - qToBigEndian((quint16) parentStream->frameLen(), (uchar*) ba.data()); - else - { - ba.resize(2); - ba[0] = ba[1] = 0; - } - - return ba; -} - -int VlanProtocol::numFields() -{ - if (isSingleTagged()) - return 4; - else if (isDoubleTagged()) - return 8; - else - { - Q_ASSERT(isUntagged()); - return 0; - } -} - -QString VlanProtocol::fieldName(int index) -{ - QString name; - - if (isDoubleTagged()) - { - switch(index) - { - case 0: - name = QString("TPID"); - break; - case 1: - name = QString("PCP"); - break; - case 2: - name = QString("DE"); - break; - case 3: - name = QString("VlanId"); - break; - default: - index -= 4; - goto _single_tag; - } - - goto _exit; - } - -_single_tag: - switch(index) - { - case 0: - name = QString("TPID"); - break; - case 1: - name = QString("Priority"); - break; - case 2: - name = QString("CFI"); - break; - case 3: - name = QString("VlanId"); - break; - default: - name = QString(); - break; - } - -_exit: - return name; -} - -QString VlanProtocol::fieldTextValue(int index) -{ - QString textValue; - - if (isDoubleTagged()) - { - switch(index) - { - case 0: - textValue = QString("0x%1"). - arg(stpid(), 4, BASE_HEX, QChar('0')); - break; - case 1: - textValue = QString("%1"). - arg(svlanPrio()); - break; - case 2: - textValue = QString("%1"). - arg(svlanCfi()); - break; - case 3: - textValue = QString("%1"). - arg(svlanId()); - break; - default: - index -= 4; - goto _single_tag; - } - - goto _exit; - } - -_single_tag: - switch(index) - { - case 0: - textValue = QString("0x%1"). - arg(ctpid(), 4, BASE_HEX, QChar('0')); - break; - case 1: - textValue = QString("%1"). - arg(cvlanPrio()); - break; - case 2: - textValue = QString("%1"). - arg(cvlanCfi()); - break; - case 3: - textValue = QString("%1"). - arg(cvlanId()); - break; - default: - textValue = QString(); - break; - } - -_exit: - return textValue; -} - -QByteArray VlanProtocol::fieldRawValue(int index) -{ - QByteArray rawValue; - - if (isDoubleTagged()) - { - switch(index) - { - case 0: - rawValue.resize(2); - qToBigEndian(stpid(), (uchar*) rawValue.data()); - break; - case 1: - rawValue.resize(2); - qToBigEndian((svlanPrio() << 13) | (svlanCfi() < 12) | svlanId(), - (uchar*) rawValue.data()); - break; - case 2: - // Combined with prio above - break; - case 3: - // Combined with prio above - break; - default: - index -= 4; - goto _single_tag; - } - - goto _exit; - } - -_single_tag: - switch(index) - { - case 0: - rawValue.resize(2); - qToBigEndian(ctpid(), (uchar*) rawValue.data()); - break; - case 1: - rawValue.resize(2); - qToBigEndian((cvlanPrio() << 13) | (cvlanCfi() < 12) | cvlanId(), - (uchar*) rawValue.data()); - break; - case 2: - // Combined with prio above - break; - case 3: - // Combined with prio above - break; - default: - break; - } - -_exit: - return rawValue; -} - -QString IpProtocol::fieldName(int index) -{ - QString name; - - switch(index) - { - case 0: - name = QString("Version"); - break; - case 1: - name = QString("Header Length"); - break; - case 2: - name = QString("TOS/DSCP"); - break; - case 3: - name = QString("Total Length"); - break; - case 4: - name = QString("ID"); - break; - case 5: - name = QString("Flags"); - break; - case 6: - name = QString("Fragment Offset"); - break; - case 7: - name = QString("TTL"); - break; - case 8: - name = QString("Protocol Type"); - break; - case 9: - name = QString("Checksum"); - break; - case 10: - name = QString("Source IP"); - break; - case 11: - name = QString("Destination IP"); - break; - default: - name = QString(); - } - - return name; -} - -QString IpProtocol::fieldTextValue(int index) -{ - QString textValue; - - switch(index) - { - case 0: - textValue = QString("%1"). - arg(ver()); - break; - case 1: - textValue = QString("%1"). - arg(hdrLen()); - break; - case 2: - textValue = QString("0x%1"). - arg(tos(), 2, BASE_HEX, QChar('0')); - break; - case 3: - textValue = QString("%1"). - arg(totLen()); - break; - case 4: - textValue = QString("0x%1"). - arg(id(), 2, BASE_HEX, QChar('0')); - break; - case 5: - textValue = QString("0x%1"). - arg(flags(), 2, BASE_HEX, QChar('0')); // FIXME(MED): bitmap? - break; - case 6: - textValue = QString("%1"). - arg(fragOfs()); - break; - case 7: - textValue = QString("%1"). - arg(ttl()); - break; - case 8: - textValue = QString("0x%1"). - arg(proto(), 2, BASE_HEX, QChar('0')); - break; - case 9: - textValue = QString("0x%1"). - arg(cksum(), 4, BASE_HEX, QChar('0')); - break; - case 10: - textValue = QHostAddress(srcIp()).toString(); - break; - case 11: - textValue = QHostAddress(dstIp()).toString(); - break; - default: - textValue = QString(); - } - - return textValue; -} - -QByteArray IpProtocol::fieldRawValue(int index) -{ - QByteArray rawValue; - - switch(index) - { - case 0: - rawValue.resize(1); - //qToBigEndian((ver() << 4) | hdrLen(), (uchar*) rawValue.data()); - rawValue[0]=(ver() << 4) | hdrLen(); - break; - case 1: - // Combined with previous 4 bits of ver!! - break; - case 2: - rawValue.resize(1); - qToBigEndian(tos(), (uchar*) rawValue.data()); - break; - case 3: - rawValue.resize(2); - qToBigEndian(totLen(), (uchar*) rawValue.data()); - break; - case 4: - rawValue.resize(2); - qToBigEndian(id(), (uchar*) rawValue.data()); - break; - case 5: - rawValue.resize(2); - qToBigEndian((quint16)((flags() << 13) | fragOfs()), - (uchar*) rawValue.data()); - break; - case 6: - // Combined with previous 3 bits of flags!! - break; - case 7: - rawValue.resize(1); - qToBigEndian(ttl(), (uchar*) rawValue.data()); - break; - case 8: - rawValue.resize(1); - qToBigEndian(proto(), (uchar*) rawValue.data()); - break; - case 9: - rawValue.resize(2); - qToBigEndian(cksum(), (uchar*) rawValue.data()); - break; - case 10: - rawValue.resize(4); - qToBigEndian(srcIp(), (uchar*) rawValue.data()); - break; - case 11: - rawValue.resize(4); - qToBigEndian(dstIp(), (uchar*) rawValue.data()); - break; - default: - break; - } - - return rawValue; -} - -QString TcpProtocol::fieldName(int index) -{ - QString name; - - switch(index) - { - case 0: - name = QString("Source Port"); - break; - case 1: - name = QString("Destination Port"); - break; - case 2: - name = QString("Seq Number"); - break; - case 3: - name = QString("Ack Number"); - break; - case 4: - name = QString("Header Length"); - break; - case 5: - name = QString("Reserved"); - break; - case 6: - name = QString("Flags"); - break; - case 7: - name = QString("Window"); - break; - case 8: - name = QString("Checksum"); - break; - case 9: - name = QString("Urgent Pointer"); - break; - default: - name = QString(); - } - - return name; -} - -QString TcpProtocol::fieldTextValue(int index) -{ - QString textValue; - - switch(index) - { - case 0: - textValue = QString("%1"). - arg(srcPort()); - break; - case 1: - textValue = QString("%1"). - arg(dstPort()); - break; - case 2: - textValue = QString("%1"). - arg(seqNum()); - break; - case 3: - textValue = QString("%1"). - arg(ackNum()); - break; - case 4: - textValue = QString("%1"). - arg(hdrLen()); - break; - case 5: - textValue = QString("%1"). - arg(rsvd()); - break; - case 6: - textValue = QString("0x%1"). - arg(flags(), 2, BASE_HEX, QChar('0')); - break; - case 7: - textValue = QString("%1"). - arg(window(), 2, BASE_HEX, QChar('0')); - break; - case 8: - textValue = QString("0x%1"). - arg(cksum(), 4, BASE_HEX, QChar('0')); - break; - case 9: - textValue = QString("%1"). - arg(urgPtr()); - break; - default: - textValue = QString(); - } - - return textValue; -} - -QByteArray TcpProtocol::fieldRawValue(int index) -{ - QByteArray rawValue; - - switch(index) - { - case 0: - rawValue.resize(2); - qToBigEndian(srcPort(), (uchar*) rawValue.data()); - break; - case 1: - rawValue.resize(2); - qToBigEndian(dstPort(), (uchar*) rawValue.data()); - break; - case 2: - rawValue.resize(4); - qToBigEndian(seqNum(), (uchar*) rawValue.data()); - break; - case 3: - rawValue.resize(4); - qToBigEndian(ackNum(), (uchar*) rawValue.data()); - break; - case 4: - rawValue.resize(1); - rawValue[0] = (hdrLen() << 4) | rsvd(); - break; - case 5: - // Combined with hdrLen above - break; - case 6: - rawValue.resize(1); - rawValue[0] = flags(); - break; - case 7: - rawValue.resize(2); - qToBigEndian(window(), (uchar*) rawValue.data()); - break; - case 8: - rawValue.resize(2); - qToBigEndian(cksum(), (uchar*) rawValue.data()); - break; - case 9: - rawValue.resize(2); - qToBigEndian(urgPtr(), (uchar*) rawValue.data()); - break; - default: - break; - } - - return rawValue; -} - -QString UdpProtocol::fieldName(int index) -{ - QString name; - - switch(index) - { - case 0: - name = QString("Source Port"); - break; - case 1: - name = QString("Destination Port"); - break; - case 2: - name = QString("Total Length"); - break; - case 3: - name = QString("Checksum"); - break; - default: - name = QString(); - } - - return name; -} - -QString UdpProtocol::fieldTextValue(int index) -{ - QString textValue; - - switch(index) - { - case 0: - textValue = QString("%1"). - arg(srcPort()); - break; - case 1: - textValue = QString("%1"). - arg(dstPort()); - break; - case 2: - textValue = QString("%1"). - arg(totLen()); - break; - case 3: - textValue = QString("0x%1"). - arg(cksum(), 4, BASE_HEX, QChar('0')); - break; - default: - textValue = QString(); - } - - return textValue; -} - -QByteArray UdpProtocol::fieldRawValue(int index) -{ - QByteArray rawValue; - - switch(index) - { - case 0: - rawValue.resize(2); - qToBigEndian(srcPort(), (uchar*) rawValue.data()); - break; - case 1: - rawValue.resize(2); - qToBigEndian(dstPort(), (uchar*) rawValue.data()); - break; - case 2: - rawValue.resize(2); - qToBigEndian(totLen(), (uchar*) rawValue.data()); - break; - case 3: - rawValue.resize(2); - qToBigEndian(cksum(), (uchar*) rawValue.data()); - break; - default: - break; - } - - return rawValue; -} - +#include "../common/mac.h" +#include "../common/payload.h" + +#include "../common/eth2.h" // FIXME: proto DB +#include "../common/dot3.h" // FIXME: proto DB +#include "../common/llc.h" // FIXME: proto DB +#include "../common/snap.h" // FIXME: proto DB +#include "../common/ip4.h" // FIXME: proto DB +#include "../common/tcp.h" // FIXME: proto DB +#include "../common/udp.h" // FIXME: proto DB //----------------------------------------------------- // Stream Class Methods //----------------------------------------------------- - - Stream::Stream() { mId = 0xFFFFFFFF; @@ -958,274 +28,148 @@ Stream::Stream() // mCore->set_port_id(0xFFFFFFFF); // mCore->set_stream_id(mId); - mUnknown = new UnknownProtocol; - mPayload = new PayloadProtocol(); //FIXME(MED): need to pass parent stream + mProtocolList.append(new MacProtocol); + mProtocolList.append(new PayloadProtocol(this)); - mMac = new MacProtocol; - - mLlc = new LlcProtocol; - mSnap = new SnapProtocol; - mEth2 = new Eth2Protocol; - mDot3 = new Dot3Protocol(); // FIXME(MED): need to pass parent stream - mVlan = new VlanProtocol; - - mIp = new IpProtocol; - mArp = new ArpProtocol; - - mTcp = new TcpProtocol; - mUdp = new UdpProtocol; - mIcmp = new IcmpProtocol; - mIgmp = new IgmpProtocol; + // FIXME: proto DB + mProtocolList.append(new Eth2Protocol); + mProtocolList.append(new Dot3Protocol); + mProtocolList.append(new LlcProtocol); + mProtocolList.append(new SnapProtocol); + mProtocolList.append(new Ip4Protocol); + mProtocolList.append(new TcpProtocol); + mProtocolList.append(new UdpProtocol); mCore->set_is_enabled(true); + mCore->add_frame_proto(51); // MAC (FIXME: hardcoding) + mCore->add_frame_proto(52); // Payload (FIXME: hardcoding) } -void Stream::getConfig(uint portId, OstProto::Stream *s) +Stream::~Stream() { - s->mutable_stream_id()->set_id(mId); + for (int i = 0; i < mProtocolList.size(); i++) + delete mProtocolList.at(i); - s->mutable_core()->CopyFrom(*mCore); - s->mutable_control()->CopyFrom(*mControl); + delete mControl; + delete mCore; +} - mMac->getConfig(s->mutable_mac()); - mMac->getConfig(s->mutable_mac()); - mLlc->getConfig(s->mutable_llc()); - mSnap->getConfig(s->mutable_snap()); - mEth2->getConfig(s->mutable_eth2()); - mVlan->getConfig(s->mutable_vlan()); +void Stream::protoDataCopyFrom(Stream& stream) +{ + OstProto::Stream data; - mIp->getConfig(s->mutable_ip()); - mArp->getConfig(s->mutable_arp()); + stream.getConfig(0, data); + update(&data); +} - mTcp->getConfig(s->mutable_tcp()); - mUdp->getConfig(s->mutable_udp()); - mIcmp->getConfig(s->mutable_icmp()); - mIgmp->getConfig(s->mutable_igmp()); +void Stream::loadProtocolWidgets() +{ + for (int i=0; i < mProtocolList.size(); i++) + mProtocolList[i]->loadConfigWidget(); +} + +void Stream::storeProtocolWidgets() +{ + for (int i=0; i < mProtocolList.size(); i++) + mProtocolList[i]->storeConfigWidget(); +} + +/*! Copy current client side config into the OstProto::Stream */ +// FIXME - remove portId unused param! +void Stream::getConfig(uint portId, OstProto::Stream &s) +{ + s.mutable_stream_id()->set_id(mId); + + s.mutable_core()->CopyFrom(*mCore); + s.mutable_control()->CopyFrom(*mControl); + + // FIXME - this doesn't take care of multiple headers of same proto + // e.g. IPinIP or double VLAN Tagged + // FIXME: change s from pointer to reference? + for (int i = 0; i < mProtocolList.size(); i++) + { + qDebug("%s: protocol %d", __FUNCTION__, i); + mProtocolList[i]->protoDataCopyInto(s); + } + + qDebug("%s: Done", __FUNCTION__); } bool Stream::update(OstProto::Stream *stream) - { - mCore->MergeFrom(stream->core()); - mControl->MergeFrom(stream->control()); - mMac->update(stream->mac()); - - mLlc->update(stream->llc()); - mSnap->update(stream->snap()); - mEth2->update(stream->eth2()); - mVlan->update(stream->vlan()); - - mIp->update(stream->ip()); - mArp->update(stream->arp()); - - //mTcp->update(stream->tcp()); - mTcp->setProtoData(stream->mutable_tcp()); - mUdp->update(stream->udp()); - mIcmp->update(stream->icmp()); - mIgmp->update(stream->igmp()); - - // FIXME(MED): Re-eval why not store complete OstProto::Stream - // instead of components - return true; - } -// FIXME(HIGH): Replace this by some Protocol Registration mechanism at Init -#define PTYP_L2_NONE 1 -#define PTYP_L2_ETH_2 2 -#define PTYP_L2_802_3_RAW 3 - -#define PTYP_L2_802_3_LLC 4 -#define PTYP_L2_SNAP 5 - -#define PTYP_VLAN 10 - -#define PTYP_L3_IP 30 -#define PTYP_L3_ARP 31 - -#define PTYP_L4_TCP 40 -#define PTYP_L4_UDP 41 -#define PTYP_L4_ICMP 42 -#define PTYP_L4_IGMP 43 - -#define PTYP_INVALID 0 -#define PTYP_DATA 0xFF - -void Stream::updateSelectedProtocols() { - int proto; + mCore->clear_frame_proto(); + mCore->MergeFrom(stream->core()); + mControl->MergeFrom(stream->control()); - // Clear the selected protocols list - selectedProtocols.clear(); - - // Check and populate L2 Protocol - switch(frameType()) + // FIXME - this doesn't take care of multiple headers of same proto + // e.g. IPinIP or double VLAN Tagged + // FIXME: change s from pointer to reference? + for (int i = 0; i < mProtocolList.size(); i++) { - case Stream::e_ft_none: - proto = PTYP_L2_NONE; - break; - - case Stream::e_ft_eth_2: - selectedProtocols.append(PTYP_L2_NONE); - proto = PTYP_L2_ETH_2; - break; - - case Stream::e_ft_802_3_raw: - selectedProtocols.append(PTYP_L2_NONE); - proto = PTYP_L2_802_3_RAW; - break; - - case Stream::e_ft_802_3_llc: - selectedProtocols.append(PTYP_L2_NONE); - proto = PTYP_L2_802_3_LLC; - break; - - case Stream::e_ft_snap: - selectedProtocols.append(PTYP_L2_NONE); - selectedProtocols.append(PTYP_L2_802_3_LLC); - proto = PTYP_L2_SNAP; - break; - - default: - qDebug("%s: Unsupported frametype %d", __FUNCTION__, - frameType()); - proto = PTYP_INVALID; + mProtocolList[i]->protoDataCopyFrom(*stream); } - selectedProtocols.append(proto); - // Check and populate VLANs, if present - if (!vlan()->isUntagged()) - selectedProtocols.append(PTYP_VLAN); + // FIXME(MED): Re-eval why not store complete OstProto::Stream + // instead of components + return true; +} - // Check and populate L3 protocols - switch (l3Proto()) - { - case Stream::e_l3_none : - goto _data; - break; +QList Stream::frameProtocol() +{ + QList protocolList; - case Stream::e_l3_ip : - proto = PTYP_L3_IP; - break; + for (int i = 0; i < mCore->frame_proto_size(); i++) + protocolList.append(mCore->frame_proto(i)); - case Stream::e_l3_arp: - proto = PTYP_L3_ARP; - break; + return protocolList; +} - default: - qDebug("%s: Unsupported L3 Proto %d", __FUNCTION__, - l3Proto()); - proto = PTYP_INVALID; - } - selectedProtocols.append(proto); - - // Check and populate L4 protocol - switch(l4Proto()) - { - case Stream::e_l4_none: - goto _data; - break; - case Stream::e_l4_tcp: - proto = PTYP_L4_TCP; - break; - case Stream::e_l4_udp: - proto = PTYP_L4_UDP; - break; - case Stream::e_l4_icmp: - proto = PTYP_L4_ICMP; - break; - case Stream::e_l4_igmp: - proto = PTYP_L4_IGMP; - break; - default: - qDebug("%s: Unsupported L4 Proto %d", __FUNCTION__, - l4Proto()); - proto = PTYP_INVALID; - }; - selectedProtocols.append(proto); - -_data: - - mProtocolHeaderSize = 0; -#ifndef SRIVATSP -#if 0 - for (int i = 0; i < selectedProtocols.size(); i++) - mProtocolHeaderSize += protocol(i)->protocolRawValue().size(); -#endif -#endif - selectedProtocols.append(PTYP_DATA); +void Stream::setFrameProtocol(QList protocolList) +{ + mCore->clear_frame_proto(); + for (int i = 0; i < protocolList.size(); i++) + mCore->add_frame_proto(protocolList.at(i)); } int Stream::protocolHeaderSize() { - updateSelectedProtocols(); // FIXME(HI): shd not happen everytime - return mProtocolHeaderSize; + int size = 0; + + for (int i = 0; i < mCore->frame_proto_size(); i++) + size += protocolById(mCore->frame_proto(i))-> + protocolFrameValue().size(); + + return size; } -int Stream::numProtocols() +AbstractProtocol* Stream::protocolById(int id) { - updateSelectedProtocols(); // FIXME(HI): shd not happen everytime - return selectedProtocols.size(); -} - -#if 0 -int Stream::protocolId(int index) -{ - updateSelectedProtocols(); // FIXME(HI): shd not happen everytime - if (index < selectedProtocols.size()) - return selectedProtocols.at(index); - else - return -1; -} -int Stream::protocolIndex(int id) -{ - -} + // FIXME BAD BAD VERY BAD! + switch(id) { + case 51: + return mProtocolList.at(0); + case 52: + return mProtocolList.at(1); + case 121: + return mProtocolList.at(2); + case 122: + return mProtocolList.at(3); + case 123: + return mProtocolList.at(4); + case 124: + return mProtocolList.at(5); + // case 125 (unused) +#if 0 // todo VLAN + case 126: + return mProtocolList.at(x); #endif - -AbstractProtocol* Stream::protocol(int index) -{ - int id; - - updateSelectedProtocols(); // FIXME(HI): shd not happen everytime - - id = selectedProtocols.at(index); - - switch(id) - { - case PTYP_L2_NONE: - return mac(); - case PTYP_L2_ETH_2: - return eth2(); - case PTYP_L2_802_3_RAW: - return dot3(); - - case PTYP_L2_802_3_LLC: - return llc(); - - case PTYP_L2_SNAP: - return snap(); - - case PTYP_VLAN: - return vlan(); - - case PTYP_L3_IP: - return ip(); - case PTYP_L3_ARP: - return arp(); - - case PTYP_L4_TCP: - return tcp(); - case PTYP_L4_UDP: - return udp(); - case PTYP_L4_ICMP: - return icmp(); - case PTYP_L4_IGMP: - return igmp(); - - case PTYP_INVALID: - return mUnknown; - case PTYP_DATA: - return mPayload; + case 130: + return mProtocolList.at(6); + case 140: + return mProtocolList.at(7); + case 141: + return mProtocolList.at(8); default: - return mUnknown; + return NULL; } } - diff --git a/client/stream.h b/client/stream.h index 434c008..c4884d4 100644 --- a/client/stream.h +++ b/client/stream.h @@ -6,10 +6,7 @@ #include #include #include "../common/protocol.pb.h" - -class StreamConfigDialog; -class StreamModel; -class PacketModel; +#include "../common/abstractprotocol.h" // Convenience Defines FIXME #define IP_PROTO_ICMP 0x01 @@ -17,864 +14,19 @@ class PacketModel; #define IP_PROTO_TCP 0x06 #define IP_PROTO_UDP 0x11 - -class Stream; - -class AbstractProtocol -{ - // TODO(LOW) -public: - /*! - Subclasses should return reference to their protocol specific - ::google::protobuf::Message - */ - virtual ::google::protobuf::Message& data() = 0; - /*! Subclasses can directly use this method. No need for overload */ - void getConfig(::google::protobuf::Message *msg) - { msg->CopyFrom(data()); } - - bool setProtoData(::google::protobuf::Message *msg) - { data().MergeFrom(*msg); return true; } - - virtual QString protocolName() - { return QString("AbstractProtocol"); } - virtual QString protocolShortName() - { return QString("AbsProto"); } - virtual int numFields() - { return 1; } - QByteArray protocolRawValue() - { - QByteArray ba; -#ifndef SRIVATSP -#else - for (int i=0; i < numFields(); i++) - ba.append(fieldRawValue(i)); -#endif - return ba; - } - virtual QString fieldName(int index) - { return QString("AbstractField"); } - virtual QString fieldTextValue(int index) - { return QString("AbstractFieldValue"); } - virtual QByteArray fieldRawValue(int index) - { return QByteArray(4, '\0'); } -}; - -class UnknownProtocol: public AbstractProtocol -{ - OstProto::Ack d; // FIXME(HI): replace 'Ack' with something else - -public: - virtual ~UnknownProtocol() {} - - virtual ::google::protobuf::Message& data() { return d; } - - virtual QString protocolName() - { return QString("UnknownProtocol"); } - QString protocolShortName() - { return QString("???Proto"); } - int numFields() - { return 1; } - QString fieldName(int index) - { return QString("UnknownField"); } - QString fieldTextValue(int index) - { return QString("UnknownFieldValue"); } - QByteArray fieldRawValue(int index) - { return QByteArray(); } -}; - -class PayloadProtocol: public AbstractProtocol -{ - Stream *parentStream; - OstProto::Ack d; // FIXME(HI): move payload related vars from - // stream into here - -public: - PayloadProtocol (Stream *stream = NULL) { parentStream = stream; } - virtual ~PayloadProtocol() {} - - virtual ::google::protobuf::Message& data() { return d; } - - virtual QString protocolName() - { return QString("Payload Data"); } - QString protocolShortName() - { return QString("DATA"); } - int numFields() - { return 1; } - QString fieldName(int index) - { return QString("Data"); } - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; - -class MacProtocol : public AbstractProtocol -{ -private: - OstProto::Mac d; - -public: - enum MacAddrMode { - MacAddrFixed, - MacAddrInc, - MacAddrDec - }; - virtual ~MacProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - - bool update(OstProto::Mac mac) { d.MergeFrom(mac); return true; } - - // Dst Mac - quint64 dstMac() - { return d.dst_mac(); } - - bool setDstMac(quint64 dstMac) - { d.set_dst_mac(dstMac); return true; } - - MacAddrMode dstMacMode() - { return (MacAddrMode) d.dst_mac_mode(); } - bool setDstMacMode(MacAddrMode dstMacMode) - { d.set_dst_mac_mode((OstProto::Mac::MacAddrMode)dstMacMode); return true; } - - quint16 dstMacCount() - { return d.dst_mac_count(); } - bool setDstMacCount(quint16 dstMacCount) - { d.set_dst_mac_count(dstMacCount); return true; } - - quint16 dstMacStep() - { return d.dst_mac_step(); } - bool setDstMacStep(quint16 dstMacStep) - { d.set_dst_mac_step(dstMacStep); return true; } - - // Src Mac - quint64 srcMac() - { return d.src_mac(); } - - bool setSrcMac(quint64 srcMac) - { d.set_src_mac(srcMac); return true; } - - MacAddrMode srcMacMode() - { return (MacAddrMode) d.src_mac_mode(); } - bool setSrcMacMode(MacAddrMode srcMacMode) - { d.set_src_mac_mode((OstProto::Mac::MacAddrMode)srcMacMode); return true; } - - quint16 srcMacCount() - { return d.src_mac_count(); } - bool setSrcMacCount(quint16 srcMacCount) - { d.set_src_mac_count(srcMacCount); return true; } - - quint16 srcMacStep() - { return d.src_mac_step(); } - bool setSrcMacStep(quint16 srcMacStep) - { d.set_src_mac_step(srcMacStep); return true; } - - - virtual QString protocolName() - { return QString("Media Access Control"); } - QString protocolShortName() - { return QString("MAC"); } - int numFields() - { return 2; } - QString fieldName(int index); - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; - -class LlcProtocol : public AbstractProtocol -{ -private: - OstProto::Llc d; - -public: - virtual ~LlcProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - - bool update(OstProto::Llc llc) { d.MergeFrom(llc); return true; } - - quint8 dsap() - { return d.dsap(); } - bool setDsap(quint8 dsap) - { d.set_dsap(dsap); return true; } - - quint8 ssap() - { return d.ssap(); } - bool setSsap(quint8 ssap) - { d.set_ssap(ssap); return true; } - - quint8 ctl() - { return d.ctl(); } - bool setCtl(quint8 ctl) - { d.set_ctl(ctl); return true; } - - - virtual QString protocolName() - { return QString("802.3 Logical Link Control"); } - QString protocolShortName() - { return QString("LLC"); } - int numFields() - { return 3; } - QString fieldName(int index); - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; - -class SnapProtocol : public AbstractProtocol -{ -private: - OstProto::Snap d; - -public: - virtual ~SnapProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - bool update(OstProto::Snap snap) { d.MergeFrom(snap); return true; } - - quint32 oui() - { return d.oui(); } - bool setOui(quint32 oui) - { d.set_oui(oui); return true; } - -// "Type" field: use from eth2 -#if 0 - quint16 type() - { return d.type(); } - bool setType(quint16 type) - { d.set_type(type); return true; } -#endif - virtual QString protocolName() - { return QString("SubNetwork Access Protocol"); } - QString protocolShortName() - { return QString("SNAP"); } - int numFields() - { return 1; } - QString fieldName(int index); - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; - - -class Eth2Protocol : public AbstractProtocol -{ -private: - OstProto::Eth2 d; - -public: - virtual ~Eth2Protocol() {} - virtual ::google::protobuf::Message& data() {return d;} - bool update(OstProto::Eth2 eth2) { d.MergeFrom(eth2); return true; } - - quint16 type() - { return d.type(); } - bool setType(quint16 type) - { d.set_type(type); return true; } - - - virtual QString protocolName() - { return QString("Protocol Type"); } - QString protocolShortName() - { return QString("TYPE"); } - int numFields() - { return 1; } - QString fieldName(int index); - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; - - -class Dot3Protocol : public AbstractProtocol -{ -private: - Stream *parentStream; - OstProto::Ack d; // FIXME(HI): replace 'ack' with somehting else - -public: - Dot3Protocol(Stream *stream = NULL) - { parentStream = stream; qDebug("parentStream = %p", stream); } - virtual ~Dot3Protocol() {} - virtual ::google::protobuf::Message& data() {return d;} - -#if 0 // FIXME(HI): remove? - quint16 length() - { return d.length(); } - bool setLength(quint16 length) - { return true; } -#endif - - virtual QString protocolName() - { return QString("802.3 Length"); } - QString protocolShortName() - { return QString("LEN"); } - int numFields() - { return 1; } - QString fieldName(int index); - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; - -class VlanProtocol : public AbstractProtocol -{ - OstProto::Vlan d; -public: - virtual ~VlanProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - bool update(OstProto::Vlan vlan) { d.MergeFrom(vlan); return true; } - - enum VlanFlag { - VlanCvlanTagged = 0x01, - VlanCtpidOverride = 0x02, - VlanSvlanTagged = 0x04, - VlanStpidOverride = 0x08, - }; - Q_DECLARE_FLAGS(VlanFlags, VlanFlag); - - VlanFlags vlanFlags() - { - VlanFlags f; - - if (d.is_cvlan_tagged()) f|= VlanCvlanTagged; - if (d.is_ctpid_override()) f|= VlanCtpidOverride; - if (d.is_svlan_tagged()) f|= VlanSvlanTagged; - if (d.is_stpid_override()) f|= VlanStpidOverride; - - return f; - } - - bool setVlanFlags(VlanFlags vlanFlags) - { - d.set_is_cvlan_tagged(vlanFlags.testFlag(VlanCvlanTagged)); - d.set_is_ctpid_override(vlanFlags.testFlag(VlanCtpidOverride)); - d.set_is_svlan_tagged(vlanFlags.testFlag(VlanSvlanTagged)); - d.set_is_stpid_override(vlanFlags.testFlag(VlanStpidOverride)); - - return true; - } - - bool isUntagged() - { - if (!d.is_cvlan_tagged() && !d.is_svlan_tagged()) - return true; - else - return false; - } - - bool isSingleTagged() - { - if (( d.is_cvlan_tagged() && !d.is_svlan_tagged()) || - (!d.is_cvlan_tagged() && d.is_svlan_tagged()) ) - return true; - else - return false; - } - - bool isDoubleTagged() - { - if (d.is_cvlan_tagged() && d.is_svlan_tagged()) - return true; - else - return false; - } - - // CVLAN - quint16 ctpid() - { return d.ctpid(); } - bool setCtpid(quint16 ctpid) - { d.set_ctpid(ctpid); return true; } - - quint8 cvlanPrio() - { return (d.cvlan_tag() >> 13); } - bool setCvlanPrio(quint8 cvlanPrio) - { d.set_cvlan_tag((d.cvlan_tag() & 0x1FFF) | ((cvlanPrio & 0x3) << 13)); - return true; } - - quint8 cvlanCfi() - { return ((d.cvlan_tag() & 0x1000) >> 12); } - bool setCvlanCfi(quint8 cvlanCfi) - { d.set_cvlan_tag((d.cvlan_tag() & 0xEFFF) | ((cvlanCfi & 0x01) << 12)); - return true; } - - quint16 cvlanId() - { return (d.cvlan_tag() & 0x0FFF); } - bool setCvlanId(quint16 cvlanId) - { d.set_cvlan_tag((d.cvlan_tag() & 0xF000) | ((cvlanId & 0x0FFF))); - return true; } - - // SVLAN - quint16 stpid() - { return d.stpid(); } - bool setStpid(quint16 stpid) - { d.set_stpid(stpid); return true; } - quint8 svlanPrio() - { return (d.svlan_tag() >> 13); } - bool setSvlanPrio(quint8 svlanPrio) - { d.set_svlan_tag((d.svlan_tag() & 0x1FFF) | ((svlanPrio & 0x3) << 13)); - return true; } - - quint8 svlanCfi() - { return ((d.svlan_tag() & 0x1000) >> 12); } - bool setSvlanCfi(quint8 svlanCfi) - { d.set_svlan_tag((d.svlan_tag() & 0xEFFF) | ((svlanCfi & 0x01) << 12)); - return true; } - - quint16 svlanId() - { return (d.svlan_tag() & 0x0FFF); } - bool setSvlanId(quint16 svlanId) - { d.set_svlan_tag((d.svlan_tag() & 0xF000) | ((svlanId & 0x0FFF))); - return true; } - - virtual QString protocolName() - { return QString("Virtual Local Access Network"); } - QString protocolShortName() - { return QString("VLAN"); } - int numFields(); - QString fieldName(int index); - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; - -// IP -class IpProtocol : public AbstractProtocol -{ -private: - OstProto::Ip d; - -public: - virtual ~IpProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - - bool update(OstProto::Ip ip) { d.MergeFrom(ip); return true; } - - enum IpAddrMode { - IpAddrFixed, - IpAddrIncHost, - IpAddrDecHost, - IpAddrRandomHost - }; - - enum IpFlag { - IpOverrideVersion = 0x01, - IpOverrideHdrLen = 0x02, - IpOverrideTotLen = 0x04, - IpOverrideCksum = 0x08 - }; - Q_DECLARE_FLAGS(IpFlags, IpFlag); - - IpFlags ipFlags() - { - IpFlags f; - - if (d.is_override_ver()) f|= IpOverrideVersion; - if (d.is_override_hdrlen()) f|= IpOverrideHdrLen; - if (d.is_override_totlen()) f|= IpOverrideTotLen; - if (d.is_override_cksum()) f|= IpOverrideCksum; - - return f; - } - - bool setIpFlags(IpFlags ipFlags) - { - if (ipFlags.testFlag(IpOverrideVersion)) - d.set_is_override_ver(true); - else - d.set_is_override_ver(false); - - if (ipFlags.testFlag(IpOverrideHdrLen)) - d.set_is_override_hdrlen(true); - else - d.set_is_override_hdrlen(false); - - if (ipFlags.testFlag(IpOverrideTotLen)) - d.set_is_override_totlen(true); - else - d.set_is_override_totlen(false); - - if (ipFlags.testFlag(IpOverrideCksum)) - d.set_is_override_cksum(true); - else - d.set_is_override_cksum(false); - - return true; - } - - quint8 ver() - { return (d.ver_hdrlen() >> 4); } - bool setVer(quint8 ver) - { d.set_ver_hdrlen((d.ver_hdrlen() & 0x0F) | (ver << 4)); return true; } - - quint8 hdrLen() - { return (d.ver_hdrlen() & 0xF); } - bool setHdrLen(quint8 hdrLen) - { d.set_ver_hdrlen((d.ver_hdrlen() & 0xF0) | hdrLen); return true; } - - quint8 tos() - { return d.tos(); } - bool setTos(quint8 tos) - { d.set_tos(tos); return true; } - - quint16 totLen() - { return d.tot_len(); } - bool setTotLen(quint16 totLen) - { d.set_tot_len(totLen); return true; } - - quint16 id() - { return d.id(); } - bool setId(quint16 id) - { d.set_id(id); return true; } - - quint16 flags() - { return d.flags(); } - bool setFlags(quint16 flags) - { d.set_flags(flags); return true; } -#define IP_FLAG_UNUSED 0x1 -#define IP_FLAG_DF 0x2 -#define IP_FLAG_MF 0x4 - - quint16 fragOfs() - { return d.frag_ofs(); } - bool setFragOfs(quint16 fragOfs) - { d.set_frag_ofs(fragOfs); return true; } - - quint8 ttl() - { return d.ttl(); } - bool setTtl(quint8 ttl) - { d.set_ttl(ttl); return true; } - - quint8 proto() - { return d.proto(); } - bool setProto(quint8 proto) - { d.set_proto(proto); return true; } - - quint16 cksum() - { return d.cksum(); } - bool setCksum(quint16 cksum) - { d.set_cksum(cksum); return true; } - - // Source IP - quint32 srcIp() - { return d.src_ip(); } - bool setSrcIp(quint32 srcIp) - { d.set_src_ip(srcIp); return true; } - - IpAddrMode srcIpMode() - { return (IpAddrMode) d.src_ip_mode(); } - bool setSrcIpMode(IpAddrMode srcIpMode) - { d.set_src_ip_mode((OstProto::Ip::IpAddrMode)srcIpMode); return true; } - - quint16 srcIpCount() - { return d.src_ip_count(); } - bool setSrcIpCount(quint16 srcIpCount) - { d.set_src_ip_count(srcIpCount); return true; } - - quint32 srcIpMask() - { return d.src_ip_mask(); } - bool setSrcIpMask(quint32 srcIpMask) - { d.set_src_ip_mask(srcIpMask); return true; } - - // Destination IP - quint32 dstIp() - { return d.dst_ip(); } - bool setDstIp(quint32 dstIp) - { d.set_dst_ip(dstIp); return true; } - - IpAddrMode dstIpMode() - { return (IpAddrMode) d.dst_ip_mode(); } - bool setDstIpMode(IpAddrMode dstIpMode) - { d.set_dst_ip_mode((OstProto::Ip::IpAddrMode)dstIpMode); return true; } - - quint16 dstIpCount() - { return d.dst_ip_count(); } - bool setDstIpCount(quint16 dstIpCount) - { d.set_dst_ip_count(dstIpCount); return true; } - - quint32 dstIpMask() - { return d.dst_ip_mask(); } - bool setDstIpMask(quint32 dstIpMask) - { d.set_dst_ip_mask(dstIpMask); return true; } - - // TODO(LOW): Options - - - virtual QString protocolName() - { return QString("Internet Protocol version 4"); } - QString protocolShortName() - { return QString("IPv4"); } - int numFields() - { return 12; } - QString fieldName(int index); - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(IpProtocol::IpFlags) - -class ArpProtocol: public AbstractProtocol -{ - // TODO(LOW): ARP - OstProto::Arp d; - -public: - virtual ~ArpProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - bool update(OstProto::Arp arp) { d.MergeFrom(arp); return true; } -}; - -// TCP -class TcpProtocol : public AbstractProtocol -{ -private: - OstProto::Tcp d; - -public: - virtual ~TcpProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - - bool update(OstProto::Tcp tcp) { d.MergeFrom(tcp); return true; } - - enum TcpFlag - { - TcpOverrideHdrLen = 0x01, - TcpOverrideCksum = 0x02 - }; - Q_DECLARE_FLAGS(TcpFlags, TcpFlag); - - TcpFlags tcpFlags() - { - TcpFlags f; - - if (d.is_override_hdrlen()) f|= TcpOverrideHdrLen; - if (d.is_override_cksum()) f|= TcpOverrideCksum; - - return f; - } - - bool setTcpFlags(TcpFlags tcpFlags) - { - if (tcpFlags.testFlag(TcpOverrideHdrLen)) - d.set_is_override_hdrlen(true); - else - d.set_is_override_hdrlen(false); - - if (tcpFlags.testFlag(TcpOverrideCksum)) - d.set_is_override_cksum(true); - else - d.set_is_override_cksum(false); - - return true; - } - - quint16 srcPort() - { return d.src_port(); } - bool setSrcPort(quint16 srcPort) - { d.set_src_port(srcPort); return true; } - - quint16 dstPort() - { return d.dst_port(); } - bool setDstPort(quint16 dstPort) - { d.set_dst_port(dstPort); return true; } - - quint32 seqNum() - { return d.seq_num(); } - bool setSeqNum(quint32 seqNum) - { d.set_seq_num(seqNum); return true;} - - quint32 ackNum() - { return d.ack_num(); } - bool setAckNum(quint32 ackNum) - { d.set_ack_num(ackNum); return true;} - - quint8 hdrLen() - { return (d.hdrlen_rsvd() >> 4); } - bool setHdrLen(quint8 hdrLen) - { d.set_hdrlen_rsvd((d.hdrlen_rsvd() & 0x0F) | (hdrLen << 4)); return true; } - - quint8 rsvd() - { return (d.hdrlen_rsvd() & 0xF); } - bool setRsvd(quint8 rsvd) - { d.set_hdrlen_rsvd((d.hdrlen_rsvd() & 0xF0) | rsvd); return true; } - - - // TODO(MED): convert to enum maybe? - quint8 flags() - { return d.flags(); } - bool setFlags(quint8 flags) - { d.set_flags(flags); return true; } -#define TCP_FLAG_URG 0x01 -#define TCP_FLAG_ACK 0x02 -#define TCP_FLAG_PSH 0x04 -#define TCP_FLAG_RST 0x08 -#define TCP_FLAG_SYN 0x10 -#define TCP_FLAG_FIN 0x20 - - quint16 window() - { return d.window(); } - bool setWindow(quint16 window) - { d.set_window(window); return true; } - - quint16 cksum() - { return d.cksum(); } - bool setCksum(quint16 cksum) - { d.set_cksum(cksum); return true; } - - quint16 urgPtr() - { return d.urg_ptr(); } - bool setUrgPtr(quint16 urg_ptr) - { d.set_urg_ptr(urg_ptr); return true; } - - - virtual QString protocolName() - { return QString("Transmission Control Protocol"); } - QString protocolShortName() - { return QString("TCP"); } - int numFields() - { return 10; } - QString fieldName(int index); - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; -Q_DECLARE_OPERATORS_FOR_FLAGS(TcpProtocol::TcpFlags) - - -// UDP -class UdpProtocol : public AbstractProtocol -{ -private: - OstProto::Udp d; - -public: - virtual ~UdpProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - - bool update(OstProto::Udp udp) { d.MergeFrom(udp); return true; } - - enum UdpFlag - { - UdpOverrideTotLen = 0x01, - UdpOverrideCksum = 0x02 - }; - Q_DECLARE_FLAGS(UdpFlags, UdpFlag); - - UdpFlags udpFlags() - { - UdpFlags f; - - if (d.is_override_totlen()) f|= UdpOverrideTotLen; - if (d.is_override_cksum()) f|= UdpOverrideCksum; - - return f; - } - - bool setUdpFlags(UdpFlags udpFlags) - { - if (udpFlags.testFlag(UdpOverrideTotLen)) - d.set_is_override_totlen(true); - else - d.set_is_override_totlen(false); - - if (udpFlags.testFlag(UdpOverrideCksum)) - d.set_is_override_cksum(true); - else - d.set_is_override_cksum(false); - - return true; - } - - quint16 srcPort() - { return d.src_port(); } - bool setSrcPort(quint16 srcPort) - { d.set_src_port(srcPort); return true; } - - quint16 dstPort() - { return d.dst_port(); } - bool setDstPort(quint16 dstPort) - { d.set_dst_port(dstPort); return true; } - - quint16 totLen() - { return d.totlen(); } - bool setTotLen(quint16 totLen) - { d.set_totlen(totLen); return true; } - - quint16 cksum() - { return d.cksum(); } - bool setCksum(quint16 cksum) - { d.set_cksum(cksum); return true; } - - - virtual QString protocolName() - { return QString("User Datagram Protocol"); } - QString protocolShortName() - { return QString("UDP"); } - int numFields() - { return 4; } - QString fieldName(int index); - QString fieldTextValue(int index); - QByteArray fieldRawValue(int index); -}; - -class IcmpProtocol : public AbstractProtocol -{ -// TODO(LOW): ICMP - OstProto::Icmp d; - -public: - virtual ~IcmpProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - bool update(OstProto::Icmp icmp) { d.MergeFrom(icmp); return true; } -}; - -class IgmpProtocol : public AbstractProtocol -{ -// TODO(LOW): IGMP - OstProto::Igmp d; - -public: - virtual ~IgmpProtocol() {} - virtual ::google::protobuf::Message& data() {return d;} - bool update(OstProto::Igmp igmp) { d.MergeFrom(igmp); return true; } -}; - - class Stream { quint32 mId; OstProto::StreamCore *mCore; OstProto::StreamControl *mControl; - UnknownProtocol *mUnknown; - PayloadProtocol *mPayload; - MacProtocol *mMac; - - LlcProtocol *mLlc; - SnapProtocol *mSnap; - Eth2Protocol *mEth2; - Dot3Protocol *mDot3; - - VlanProtocol *mVlan; - - IpProtocol *mIp; - ArpProtocol *mArp; - - TcpProtocol *mTcp; - UdpProtocol *mUdp; - IcmpProtocol *mIcmp; - IgmpProtocol *mIgmp; + QList mProtocolList; public: - //PayloadProtocol* Payload() { return mPayload; } - MacProtocol* mac() { return mMac; } void* core() { return mCore; } // FIXME(HI): Debug ONLY - - LlcProtocol* llc() { return mLlc; } - SnapProtocol* snap() { return mSnap; } - Eth2Protocol* eth2() { return mEth2; } - Dot3Protocol* dot3() { return mDot3; } - VlanProtocol* vlan() { return mVlan; } - - IpProtocol* ip() { return mIp; } - ArpProtocol* arp() { return mArp; } - - TcpProtocol* tcp() { return mTcp; } - UdpProtocol* udp() { return mUdp; } - IcmpProtocol* icmp() { return mIcmp; } - IgmpProtocol* igmp() { return mIgmp; } - + void loadProtocolWidgets(); + void storeProtocolWidgets(); public: enum FrameType { @@ -933,12 +85,15 @@ public: // Methods // ------------------------------------------------------- Stream(); + ~Stream(); + + void protoDataCopyFrom(Stream& stream); bool operator < (const Stream &s) const { return(mCore->ordinal() < s.mCore->ordinal()); } - void getConfig(uint portId, OstProto::Stream *s); + void getConfig(uint portId, OstProto::Stream &s); bool update(OstProto::Stream *stream); quint32 id() @@ -968,23 +123,6 @@ public: bool setName(QString name) { mCore->set_name(name.toStdString()); return true; } - FrameType frameType() - { return (FrameType) mCore->ft(); } - bool setFrameType(FrameType frameType) - { mCore->set_ft((OstProto::StreamCore::FrameType) frameType); return true; } - - // Data Pattern - DataPatternMode patternMode() - { return (DataPatternMode) mCore->pattern_mode(); } - bool setPatternMode(DataPatternMode patternMode) - { mCore->set_pattern_mode( - (OstProto::StreamCore::DataPatternMode) patternMode); return true; } - - quint32 pattern() - { return mCore->pattern(); } - bool setPattern(quint32 pattern) - { mCore->set_pattern(pattern); return true; } - // TODO(HI) : ????? #if 0 quint16 dataStartOfs; @@ -1012,18 +150,6 @@ public: bool setFrameLenMax(quint16 frameLenMax) { mCore->set_frame_len_max(frameLenMax); return true; } - L3Proto l3Proto() - { return (L3Proto) mCore->l3_proto(); } - bool setL3Proto(L3Proto l3Proto) - { mCore->set_l3_proto((OstProto::StreamCore::L3Proto) l3Proto); - return true; } - - L4Proto l4Proto() - { return (L4Proto) mCore->l4_proto(); } - bool setL4Proto(L4Proto l4Proto) - { mCore->set_l4_proto((OstProto::StreamCore::L4Proto) l4Proto); - return true; } - SendUnit sendUnit() { return (SendUnit) mControl->unit(); } bool setSendUnit(SendUnit sendUnit) @@ -1070,21 +196,12 @@ public: //--------------------------------------------------------------- // Methods for use by Packet Model //--------------------------------------------------------------- - - int numProtocols(); + QList frameProtocol(); + void setFrameProtocol(QList protocolList); //! Includes ALL protocol headers excluding payload data int protocolHeaderSize(); -#if 0 - int protocolId(int index); - int protocolIndex(int id); -#endif - AbstractProtocol* protocol(int index); -private: - QList selectedProtocols; - int mProtocolHeaderSize; - void updateSelectedProtocols(); - + AbstractProtocol* protocolById(int id); }; #endif diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 8b99561..0079240 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -13,6 +13,11 @@ int StreamConfigDialog::lastProtoTabIndex = 0; StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent) : QDialog (parent), mPort(port) { + mCurrentStreamIndex = streamIndex; + + mpStream = new Stream; + mpStream->protoDataCopyFrom(*(mPort.streamByIndex(mCurrentStreamIndex))); + setupUi(this); setupUiExtra(); @@ -158,19 +163,15 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, rbFtNone->click(); #endif - //mpStreamList = streamList; - mCurrentStreamIndex = streamIndex; + //mmpStreamList = streamList; LoadCurrentStream(); - mpPacketModel = new PacketModel(&mPort.streamByIndex(mCurrentStreamIndex), - this); + mpPacketModel = new PacketModel(QList(), this); tvPacketTree->setModel(mpPacketModel); mpPacketModelTester = new ModelTest(mpPacketModel); tvPacketTree->header()->hide(); vwPacketDump->setModel(mpPacketModel); vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); - - // TODO(MED): //! \todo Enable navigation of streams pbPrev->setDisabled(true); @@ -180,7 +181,6 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool))); //! \todo Support Continuous Mode rbModeContinuous->setDisabled(true); - // Finally, restore the saved last selected tab for the various tab widgets twTopLevel->setCurrentIndex(lastTopLevelTabIndex); if (twProto->isTabEnabled(lastProtoTabIndex)) @@ -193,6 +193,16 @@ void StreamConfigDialog::setupUiExtra() QRegExp reHex4B("[0-9,a-f,A-F]{1,8}"); QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); + // Add the Payload widget to the dialog + { + QGridLayout *layout; + + layout = static_cast(twTopLevel->widget(0)->layout()); + + layout->addWidget(mpStream->protocolById(52)->configWidget(), 0, 1); + qDebug("setupUi wgt = %p", mpStream->protocolById(52)->configWidget()); + } + // ---- Setup default stuff that cannot be done in designer ---- // Since the dialog defaults are FT = None, L3 = None, L4 = None; @@ -218,6 +228,7 @@ void StreamConfigDialog::setupUiExtra() lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); // L2 Ethernet +#if 0 // Proto FW leDstMac->setValidator(new QRegExpValidator(reMac, this)); leSrcMac->setValidator(new QRegExpValidator(reMac, this)); leDstMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); @@ -225,6 +236,7 @@ void StreamConfigDialog::setupUiExtra() leCvlanTpid->setValidator(new QRegExpValidator(reHex2B, this)); leSvlanTpid->setValidator(new QRegExpValidator(reHex2B, this)); //leEtherType->setValidator(new QRegExpValidator(reHex2B, this)); +#endif /* ** Setup Connections @@ -244,31 +256,93 @@ StreamConfigDialog::~StreamConfigDialog() { delete mpPacketModelTester; delete mpPacketModel; + + // Remove payload data widget so that it is not deleted when this object + // is destroyed + { + QLayout *layout = twTopLevel->widget(0)->layout(); + if (layout) + { + qDebug("dstrct wgt = %p", mpStream->protocolById(52)->configWidget()); +#if 0 + int i = layout->indexOf(mpStream->protocolById(52)->configWidget()); + if (i >= 0) + { + layout->takeAt(i); + mpStream->protocolById(52)->configWidget()->setParent(0); + } +#endif + layout->removeWidget(mpStream->protocolById(52)->configWidget()); + mpStream->protocolById(52)->configWidget()->setParent(0); + + } + } + + // Remove any existing widget on the L2-L4 Tabs lest they are deleted + // when this object is destoryed + for (int i = 1; i <= 3; i++) + { + QLayout *layout = twProto->widget(i)->layout(); + if (layout) + { + QLayoutItem *child; + while ((child = layout->takeAt(0)) != 0) + { + Q_ASSERT(child->widget() != 0); + // Don't delete the child widget - reparent it + child->widget()->setParent(0); + } + delete layout; + } + } + + delete mpStream; } -void StreamConfigDialog::on_cmbPatternMode_currentIndexChanged(QString mode) +void StreamConfigDialog::updateSelectedProtocols() { - if (mode == "Fixed Word") + mSelectedProtocols.clear(); + + // FIXME: Hardcoded numbers! + + // Mac + mSelectedProtocols.append(51); + + if (rbFtEthernet2->isChecked()) + mSelectedProtocols.append(121); + else if (rbFt802Dot3Raw->isChecked()) + mSelectedProtocols.append(122); + else if (rbFt802Dot3Llc->isChecked()) { - lePattern->setEnabled(true); + mSelectedProtocols.append(122); + mSelectedProtocols.append(123); } - else if (mode == "Increment Byte") + else if (rbFtLlcSnap->isChecked()) { - lePattern->setDisabled(true); - } - else if (mode == "Decrement Byte") - { - lePattern->setDisabled(true); - } - if (mode == "Random") - { - lePattern->setDisabled(true); - } - else - { - qWarning("Unhandled/Unknown PatternMode = %s", mode.toAscii().data()); + mSelectedProtocols.append(122); + mSelectedProtocols.append(123); + mSelectedProtocols.append(124); } + + if (rbL3Ipv4->isChecked()) + mSelectedProtocols.append(130); + else if (rbL3Arp->isChecked()) + mSelectedProtocols.append(131); + + if (rbL4Tcp->isChecked()) + mSelectedProtocols.append(140); + else if (rbL4Udp->isChecked()) + mSelectedProtocols.append(141); + else if (rbL4Icmp->isChecked()) + mSelectedProtocols.append(142); + else if (rbL4Igmp->isChecked()) + mSelectedProtocols.append(143); + + // Payload + mSelectedProtocols.append(52); } + + void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode) { if (mode == "Fixed") @@ -301,63 +375,6 @@ void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode) } } - -void StreamConfigDialog::on_cmbDstMacMode_currentIndexChanged(QString mode) -{ - if (mode == "Fixed") - { - leDstMacCount->setEnabled(false); - leDstMacStep->setEnabled(false); - } - else - { - leDstMacCount->setEnabled(true); - leDstMacStep->setEnabled(true); - } -} - -void StreamConfigDialog::on_cmbSrcMacMode_currentIndexChanged(QString mode) -{ - if (mode == "Fixed") - { - leSrcMacCount->setEnabled(false); - leSrcMacStep->setEnabled(false); - } - else - { - leSrcMacCount->setEnabled(true); - leSrcMacStep->setEnabled(true); - } -} - -void StreamConfigDialog::on_cmbIpSrcAddrMode_currentIndexChanged(QString mode) -{ - if (mode == "Fixed") - { - leIpSrcAddrCount->setDisabled(true); - leIpSrcAddrMask->setDisabled(true); - } - else - { - leIpSrcAddrCount->setEnabled(true); - leIpSrcAddrMask->setEnabled(true); - } -} - -void StreamConfigDialog::on_cmbIpDstAddrMode_currentIndexChanged(QString mode) -{ - if (mode == "Fixed") - { - leIpDstAddrCount->setDisabled(true); - leIpDstAddrMask->setDisabled(true); - } - else - { - leIpDstAddrCount->setEnabled(true); - leIpDstAddrMask->setEnabled(true); - } -} - void StreamConfigDialog::on_pbPrev_clicked() { #if 0 @@ -412,10 +429,13 @@ void StreamConfigDialog::on_rbL3Ipv4_toggled(bool checked) { if (checked) { - swL3Proto->setCurrentIndex(0); twProto->setTabEnabled(2, TRUE); twProto->setTabText(2, "L3 (IPv4)"); leType->setText("08 00"); + + // FIXME: Hardcoding + mpStream->protocolById(121)->setFieldData(0 /* type */, 0x800); + mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param } else { @@ -428,10 +448,13 @@ void StreamConfigDialog::on_rbL3Arp_toggled(bool checked) { if (checked) { - swL3Proto->setCurrentIndex(1); twProto->setTabEnabled(2, TRUE); twProto->setTabText(2, "L3 (ARP)"); leType->setText("08 06"); + + // FIXME: Hardcoding + mpStream->protocolById(121)->setFieldData(0 /* type */, 0x806); + mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param } else { @@ -446,10 +469,11 @@ void StreamConfigDialog::on_rbL4Icmp_toggled(bool checked) if (checked) { - swL4Proto->setCurrentIndex(2); twProto->setTabEnabled(3, TRUE); twProto->setTabText(3, "L4 (ICMP)"); - leIpProto->setText(uintToHexStr(IP_PROTO_ICMP, str, 1)); + // FIXME: Hardcoding + mpStream->protocolById(130)->setFieldData(8 /* proto */, IP_PROTO_ICMP); + mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param } else { @@ -464,10 +488,11 @@ void StreamConfigDialog::on_rbL4Igmp_toggled(bool checked) if (checked) { - swL4Proto->setCurrentIndex(3); twProto->setTabEnabled(3, TRUE); twProto->setTabText(3, "L4 (IGMP)"); - leIpProto->setText(uintToHexStr(IP_PROTO_IGMP, str, 1)); + // FIXME: Hardcoding + mpStream->protocolById(130)->setFieldData(8 /* proto */, IP_PROTO_IGMP); + mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param } else { @@ -482,10 +507,11 @@ void StreamConfigDialog::on_rbL4Tcp_toggled(bool checked) if (checked) { - swL4Proto->setCurrentIndex(0); twProto->setTabEnabled(3, TRUE); twProto->setTabText(3, "L4 (TCP)"); - leIpProto->setText(uintToHexStr(IP_PROTO_TCP, str, 1)); + // FIXME: Hardcoding + mpStream->protocolById(130)->setFieldData(8 /* proto */, IP_PROTO_TCP); + mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param } else { @@ -500,10 +526,11 @@ void StreamConfigDialog::on_rbL4Udp_toggled(bool checked) if (checked) { - swL4Proto->setCurrentIndex(1); twProto->setTabEnabled(3, TRUE); twProto->setTabText(3, "L4 (UDP)"); - leIpProto->setText(uintToHexStr(IP_PROTO_UDP, str, 1)); + // FIXME: Hardcoding + mpStream->protocolById(130)->setFieldData(8 /* proto */, IP_PROTO_UDP); + mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param } else { @@ -512,6 +539,88 @@ void StreamConfigDialog::on_rbL4Udp_toggled(bool checked) } } +void StreamConfigDialog::on_twTopLevel_currentChanged(int index) +{ + QList protoList; + + // We only process the "Packet View" tab + if (index != 2) + return; + + updateSelectedProtocols(); + foreach(int i, mSelectedProtocols) + if (mpStream->protocolById(i)) + protoList.append(mpStream->protocolById(i)); + + mpPacketModel->setSelectedProtocols(protoList); + StoreCurrentStream(mpStream); +} + +void StreamConfigDialog::on_twProto_currentChanged(int index) +{ + QLayout *layout; + QList wl; + + // We need to process only indices 1-3 i.e. the L2, L3 and L4 tabs + if ((index < 1) || (index > 3)) + return; + + // Remove any existing widget on the activated tab + layout = twProto->widget(index)->layout(); + if (layout) + { + QLayoutItem *child; + while ((child = layout->takeAt(0)) != 0) + { + Q_ASSERT(child->widget() != 0); + // Don't delete the child widget - reparent it + child->widget()->setParent(0); + } + delete layout; + } + + // FIXME: protocol id hardcodings + switch(index) + { + case 1: // L2 + wl.append(mpStream->protocolById(51)->configWidget()); + if (rbFtEthernet2->isChecked()) + wl.append(mpStream->protocolById(121)->configWidget()); + else if (rbFt802Dot3Raw->isChecked()) + wl.append(mpStream->protocolById(122)->configWidget()); + else if (rbFt802Dot3Llc->isChecked()) + { + wl.append(mpStream->protocolById(122)->configWidget()); + wl.append(mpStream->protocolById(123)->configWidget()); + } + else if (rbFtLlcSnap->isChecked()) + { + wl.append(mpStream->protocolById(122)->configWidget()); + wl.append(mpStream->protocolById(123)->configWidget()); + wl.append(mpStream->protocolById(124)->configWidget()); + } + break; + case 2: // L3 + if (rbL3Ipv4->isChecked()) + wl.append(mpStream->protocolById(130)->configWidget()); + break; + case 3: // L4 + if (rbL4Tcp->isChecked()) + wl.append(mpStream->protocolById(140)->configWidget()); + else if (rbL4Udp->isChecked()) + wl.append(mpStream->protocolById(141)->configWidget()); + break; + } + + if (wl.size()) + layout = new QVBoxLayout; + + for (int i=0; i < wl.size(); i++) + layout->addWidget(wl.at(i)); + + twProto->widget(index)->setLayout(layout); +} + void StreamConfigDialog::update_NumPacketsAndNumBursts() { if (rbSendPackets->isChecked() && rbModeFixed->isChecked()) @@ -525,28 +634,6 @@ void StreamConfigDialog::update_NumPacketsAndNumBursts() leNumBursts->setEnabled(false); } -QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets) -{ - int i; - QChar zero('0'); - - hexStr = ""; - - for (i = octets; i > 0; i--) - { - ushort byte; - QString str1 = "%1"; - QString str; - - byte = num & 0xff; - str = str1.arg(byte, 2, 16, zero).append(' '); - hexStr.prepend(str); - num = num >> 8; - } - - return hexStr; -} - #if 0 void StreamConfigDialog::on_lePattern_editingFinished() { @@ -563,234 +650,133 @@ void StreamConfigDialog::on_lePattern_editingFinished() void StreamConfigDialog::LoadCurrentStream() { - Stream *pStream = &mPort.streamByIndex(mCurrentStreamIndex); QString str; - qDebug("loading pStream %p", pStream); + qDebug("loading mpStream %p", mpStream); // Meta Data { - cmbPatternMode->setCurrentIndex(pStream->patternMode()); - lePattern->setText(uintToHexStr(pStream->pattern(), str, 4)); - - cmbPktLenMode->setCurrentIndex(pStream->lenMode()); - lePktLen->setText(str.setNum(pStream->frameLen())); - lePktLenMin->setText(str.setNum(pStream->frameLenMin())); - lePktLenMax->setText(str.setNum(pStream->frameLenMax())); + cmbPktLenMode->setCurrentIndex(mpStream->lenMode()); + lePktLen->setText(str.setNum(mpStream->frameLen())); + lePktLenMin->setText(str.setNum(mpStream->frameLenMin())); + lePktLenMax->setText(str.setNum(mpStream->frameLenMax())); } // Protocols { - qDebug("ft = %d\n", pStream->frameType()); - switch(pStream->frameType()) + int i; + + qDebug("Selected Protocols.size() = %d", mSelectedProtocols.size()); + mSelectedProtocols = mpStream->frameProtocol(); + qDebug("Selected Protocols.size() = %d", mSelectedProtocols.size()); + for (i = 0; i < mSelectedProtocols.size(); i++) + qDebug("%d: %d", i, mSelectedProtocols.at(i)); + + Q_ASSERT(mSelectedProtocols.size() >= 2); // Mac + Payload: mandatory + + i = 0; + Q_ASSERT(mSelectedProtocols.at(i) == 51); // Mac + i++; + + if (mSelectedProtocols.at(i) == 52) // Payload { - case Stream::e_ft_none: - rbFtNone->setChecked(TRUE); - break; - case Stream::e_ft_eth_2: - rbFtEthernet2->setChecked(TRUE); - break; - case Stream::e_ft_802_3_raw: - rbFt802Dot3Raw->setChecked(TRUE); - break; - case Stream::e_ft_802_3_llc: - rbFt802Dot3Llc->setChecked(TRUE); - break; - case Stream::e_ft_snap: - rbFtLlcSnap->setChecked(TRUE); - break; + i++; + goto _proto_parse_done; } - - leDsap->setText(uintToHexStr(pStream->llc()->dsap(), str, 1)); - leSsap->setText(uintToHexStr(pStream->llc()->ssap(), str, 1)); - leControl->setText(uintToHexStr(pStream->llc()->ctl(), str, 1)); - leOui->setText(uintToHexStr(pStream->snap()->oui(), str, 3)); - - leType->setText(uintToHexStr(pStream->eth2()->type(), str, 2)); - - switch(pStream->l3Proto()) + else if (mSelectedProtocols.at(i) == 121) // Eth2 { - case Stream::e_l3_none: - rbL3None->setChecked(true); - break; - case Stream::e_l3_ip: - rbL3Ipv4->setChecked(true); - break; - case Stream::e_l3_arp: - rbL3Arp->setChecked(true); - break; - default: - qDebug("%s: unknown L3 Protocol %d", __FUNCTION__, - pStream->l3Proto()); + rbFtEthernet2->setChecked(true); + i++; } - - switch(pStream->l4Proto()) + else if (mSelectedProtocols.at(i) == 122) // 802.3 RAW { - case Stream::e_l4_none: - rbL4None->setChecked(true); - break; - case Stream::e_l4_tcp: - rbL4Tcp->setChecked(true); - break; - case Stream::e_l4_udp: - rbL4Udp->setChecked(true); - break; - case Stream::e_l4_icmp: - rbL4Icmp->setChecked(true); - break; - case Stream::e_l4_igmp: - rbL4Igmp->setChecked(true); - break; - default: - qDebug("%s: unknown l4 Protocol %d", __FUNCTION__, - pStream->l4Proto()); - } - } - - // L2 - { - // L2 | Ethernet - { - leDstMac->setText(uintToHexStr(pStream->mac()->dstMac(), str, 6)); - cmbDstMacMode->setCurrentIndex(pStream->mac()->dstMacMode()); - leDstMacCount->setText(str.setNum(pStream->mac()->dstMacCount())); - leDstMacStep->setText(str.setNum(pStream->mac()->dstMacStep())); - - leSrcMac->setText(uintToHexStr(pStream->mac()->srcMac(), str, 6)); - cmbSrcMacMode->setCurrentIndex(pStream->mac()->srcMacMode()); - leSrcMacCount->setText(str.setNum(pStream->mac()->srcMacCount())); - leSrcMacStep->setText(str.setNum(pStream->mac()->srcMacStep())); - + if ((mSelectedProtocols.size() > (i+1)) && + (mSelectedProtocols.at(i+1) == 123)) // 802.3 LLC { - VlanProtocol *vlan = pStream->vlan(); - VlanProtocol::VlanFlags f; - - cmbCvlanPrio->setCurrentIndex(vlan->cvlanPrio()); - cmbCvlanCfi->setCurrentIndex(vlan->cvlanCfi()); - leCvlanId->setText(str.setNum(vlan->cvlanId())); - leCvlanTpid->setText(str.setNum(vlan->ctpid())); - cbCvlanTpidOverride->setChecked(vlan->vlanFlags().testFlag( - VlanProtocol::VlanCtpidOverride)); - gbCvlan->setChecked(vlan->vlanFlags().testFlag( - VlanProtocol::VlanCvlanTagged)); - - cmbSvlanPrio->setCurrentIndex(vlan->svlanPrio()); - cmbSvlanCfi->setCurrentIndex(vlan->svlanCfi()); - leSvlanId->setText(str.setNum(vlan->svlanId())); - leSvlanTpid->setText(str.setNum(vlan->stpid())); - cbSvlanTpidOverride->setChecked(vlan->vlanFlags().testFlag( - VlanProtocol::VlanStpidOverride)); - gbSvlan->setChecked(vlan->vlanFlags().testFlag( - VlanProtocol::VlanSvlanTagged)); + if ((mSelectedProtocols.size() > (i+2)) && + (mSelectedProtocols.at(i+2) == 124)) // SNAP + { + rbFtLlcSnap->setChecked(true); + i+=3; + } + else + { + rbFt802Dot3Llc->setChecked(true); + i+=2; + } + } + else + { + rbFt802Dot3Raw->setChecked(true); + i++; } } - } + else + rbFtNone->setChecked(true); - // L3 - { - // L3 | IP + // L3 + if (mSelectedProtocols.at(i) == 52) // Payload { - leIpVersion->setText(str.setNum(pStream->ip()->ver())); - cbIpVersionOverride->setChecked( - pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideVersion)); - leIpHdrLen->setText(str.setNum(pStream->ip()->hdrLen())); - cbIpHdrLenOverride->setChecked( - pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideHdrLen)); - - leIpTos->setText(uintToHexStr(pStream->ip()->tos(), str, 1)); - - leIpLength->setText(str.setNum(pStream->ip()->totLen())); - cbIpLengthOverride->setChecked( - pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideTotLen)); - - leIpId->setText(uintToHexStr(pStream->ip()->id(), str, 2)); - leIpFragOfs->setText(str.setNum(pStream->ip()->fragOfs())); - cbIpFlagsDf->setChecked((pStream->ip()->flags() & IP_FLAG_DF) > 0); - cbIpFlagsMf->setChecked((pStream->ip()->flags() & IP_FLAG_MF) > 0); - - leIpTtl->setText(str.setNum(pStream->ip()->ttl())); - leIpProto->setText(uintToHexStr(pStream->ip()->proto(), str, 1)); - - leIpCksum->setText(uintToHexStr(pStream->ip()->cksum(), str, 2)); - cbIpCksumOverride->setChecked( - pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideCksum)); - - leIpSrcAddr->setText(QHostAddress(pStream->ip()->srcIp()).toString()); - cmbIpSrcAddrMode->setCurrentIndex(pStream->ip()->srcIpMode()); - leIpSrcAddrCount->setText(str.setNum(pStream->ip()->srcIpCount())); - leIpSrcAddrMask->setText(QHostAddress(pStream->ip()->srcIpMask()).toString()); - - leIpDstAddr->setText(QHostAddress(pStream->ip()->dstIp()).toString()); - cmbIpDstAddrMode->setCurrentIndex(pStream->ip()->dstIpMode()); - leIpDstAddrCount->setText(str.setNum(pStream->ip()->dstIpCount())); - leIpDstAddrMask->setText(QHostAddress(pStream->ip()->dstIpMask()).toString()); + i++; + goto _proto_parse_done; } - - // L3 | ARP + else if (mSelectedProtocols.at(i) == 130) // IP4 { - // TODO(LOW) + rbL3Ipv4->setChecked(true); + i++; } - } - - // L4 - { - // L4 | TCP + else if (mSelectedProtocols.at(i) == 131) // ARP { - leTcpSrcPort->setText(str.setNum(pStream->tcp()->srcPort())); - leTcpDstPort->setText(str.setNum(pStream->tcp()->dstPort())); - - leTcpSeqNum->setText(str.setNum(pStream->tcp()->seqNum())); - leTcpAckNum->setText(str.setNum(pStream->tcp()->ackNum())); - - leTcpHdrLen->setText(str.setNum(pStream->tcp()->hdrLen())); - cbTcpHdrLenOverride->setChecked((pStream->tcp()->tcpFlags(). - testFlag(TcpProtocol::TcpOverrideHdrLen))); - - leTcpWindow->setText(str.setNum(pStream->tcp()->window())); - - leTcpCksum->setText(str.setNum(pStream->tcp()->cksum())); - cbTcpCksumOverride->setChecked((pStream->tcp()->tcpFlags(). - testFlag(TcpProtocol::TcpOverrideCksum))); - - leTcpUrgentPointer->setText(str.setNum(pStream->tcp()->urgPtr())); - - cbTcpFlagsUrg->setChecked((pStream->tcp()->flags() & TCP_FLAG_URG) > 0); - cbTcpFlagsAck->setChecked((pStream->tcp()->flags() & TCP_FLAG_ACK) > 0); - cbTcpFlagsPsh->setChecked((pStream->tcp()->flags() & TCP_FLAG_PSH) > 0); - cbTcpFlagsRst->setChecked((pStream->tcp()->flags() & TCP_FLAG_RST) > 0); - cbTcpFlagsSyn->setChecked((pStream->tcp()->flags() & TCP_FLAG_SYN) > 0); - cbTcpFlagsFin->setChecked((pStream->tcp()->flags() & TCP_FLAG_FIN) > 0); + rbL3Arp->setChecked(true); + i++; } + else + rbL3None->setChecked(true); - // L4 | UDP + if (i == mSelectedProtocols.size()) + goto _proto_parse_done; + + // L4 + if (mSelectedProtocols.at(i) == 52) // Payload { - leUdpSrcPort->setText(str.setNum(pStream->udp()->srcPort())); - leUdpDstPort->setText(str.setNum(pStream->udp()->dstPort())); - - leUdpLength->setText(str.setNum(pStream->udp()->totLen())); - cbUdpLengthOverride->setChecked((pStream->udp()->udpFlags(). - testFlag(UdpProtocol::UdpOverrideTotLen))); - - - leUdpCksum->setText(str.setNum(pStream->udp()->cksum())); - cbUdpCksumOverride->setChecked((pStream->udp()->udpFlags(). - testFlag(UdpProtocol::UdpOverrideCksum))); + i++; + goto _proto_parse_done; } - - // L4 | ICMP + else if (mSelectedProtocols.at(i) == 140) // TCP { - // TODO(LOW) + rbL4Tcp->setChecked(true); + i++; } - - // L4 | IGMP + else if (mSelectedProtocols.at(i) == 141) // UDP { - // TODO(LOW) + rbL4Udp->setChecked(true); + i++; } + else if (mSelectedProtocols.at(i) == 142) // ICMP + { + rbL4Icmp->setChecked(true); + i++; + } + else if (mSelectedProtocols.at(i) == 143) // IGMP + { + rbL4Igmp->setChecked(true); + i++; + } + else + rbL4None->setChecked(true); + + Q_ASSERT(mSelectedProtocols.at(i) == 52); // Payload + i++; + +_proto_parse_done: + Q_ASSERT(i == mSelectedProtocols.size()); + + mpStream->loadProtocolWidgets(); } // Stream Control { - switch (pStream->sendUnit()) + switch (mpStream->sendUnit()) { case Stream::e_su_packets: rbSendPackets->setChecked(true); @@ -799,10 +785,10 @@ void StreamConfigDialog::LoadCurrentStream() rbSendBursts->setChecked(true); break; default: - qWarning("Unhandled sendUnit = %d\n", pStream->sendUnit()); + qWarning("Unhandled sendUnit = %d\n", mpStream->sendUnit()); } - switch (pStream->sendMode()) + switch (mpStream->sendMode()) { case Stream::e_sm_fixed: rbModeFixed->setChecked(true); @@ -811,10 +797,10 @@ void StreamConfigDialog::LoadCurrentStream() rbModeContinuous->setChecked(true); break; default: - qWarning("Unhandled sendMode = %d\n", pStream->sendMode()); + qWarning("Unhandled sendMode = %d\n", mpStream->sendMode()); } - switch(pStream->nextWhat()) + switch(mpStream->nextWhat()) { case Stream::e_nw_stop: rbActionStop->setChecked(true); @@ -826,31 +812,27 @@ void StreamConfigDialog::LoadCurrentStream() rbActionGotoStream->setChecked(true); break; default: - qWarning("Unhandled nextAction = %d\n", pStream->nextWhat()); + qWarning("Unhandled nextAction = %d\n", mpStream->nextWhat()); } - leNumPackets->setText(QString().setNum(pStream->numPackets())); - leNumBursts->setText(QString().setNum(pStream->numBursts())); - lePacketsPerBurst->setText(QString().setNum(pStream->burstSize())); - lePacketsPerSec->setText(QString().setNum(pStream->packetRate())); - leBurstsPerSec->setText(QString().setNum(pStream->burstRate())); + leNumPackets->setText(QString().setNum(mpStream->numPackets())); + leNumBursts->setText(QString().setNum(mpStream->numBursts())); + lePacketsPerBurst->setText(QString().setNum(mpStream->burstSize())); + lePacketsPerSec->setText(QString().setNum(mpStream->packetRate())); + leBurstsPerSec->setText(QString().setNum(mpStream->burstRate())); // TODO(MED): Change this when we support goto to specific stream leStreamId->setText(QString("0")); } } -void StreamConfigDialog::StoreCurrentStream() +void StreamConfigDialog::StoreCurrentStream(Stream *pStream) { - Stream *pStream = &mPort.streamByIndex(mCurrentStreamIndex); QString str; bool isOk; qDebug("storing pStream %p", pStream); // Meta Data - pStream->setPatternMode((Stream::DataPatternMode) cmbPatternMode->currentIndex()); - pStream->setPattern(lePattern->text().remove(QChar(' ')).toULong(&isOk, 16)); - pStream->setLenMode((Stream::FrameLengthMode) cmbPktLenMode->currentIndex()); pStream->setFrameLen(lePktLen->text().toULong(&isOk)); pStream->setFrameLenMin(lePktLenMin->text().toULong(&isOk)); @@ -858,235 +840,9 @@ void StreamConfigDialog::StoreCurrentStream() // Protocols { - if (rbFtNone->isChecked()) - pStream->setFrameType(Stream::e_ft_none); - else if (rbFtEthernet2->isChecked()) - pStream->setFrameType(Stream::e_ft_eth_2); - else if (rbFt802Dot3Raw->isChecked()) - pStream->setFrameType(Stream::e_ft_802_3_raw); - else if (rbFt802Dot3Llc->isChecked()) - pStream->setFrameType(Stream::e_ft_802_3_llc); - else if (rbFtLlcSnap->isChecked()) - pStream->setFrameType(Stream::e_ft_snap); - qDebug("store ft(%d)\n", pStream->frameType()); - - pStream->llc()->setDsap(leDsap->text().remove(QChar(' ')).toULong(&isOk, 16)); - pStream->llc()->setSsap(leSsap->text().remove(QChar(' ')).toULong(&isOk, 16)); - pStream->llc()->setCtl(leControl->text().remove(QChar(' ')).toULong(&isOk, 16)); - pStream->snap()->setOui(leOui->text().remove(QChar(' ')).toULong(&isOk, 16)); - pStream->eth2()->setType(leType->text().remove(QChar(' ')).toULong(&isOk, 16)); - - if (rbL3None->isChecked()) - pStream->setL3Proto(Stream::e_l3_none); - else if (rbL3Ipv4->isChecked()) - pStream->setL3Proto(Stream::e_l3_ip); - else if (rbL3Arp->isChecked()) - pStream->setL3Proto(Stream::e_l3_arp); - else - { - qCritical("No L3 Protocol??? Problem in Code!!!"); - pStream->setL3Proto(Stream::e_l3_none); - } - - if (rbL4None->isChecked()) - pStream->setL4Proto(Stream::e_l4_none); - else if (rbL4Tcp->isChecked()) - pStream->setL4Proto(Stream::e_l4_tcp); - else if (rbL4Udp->isChecked()) - pStream->setL4Proto(Stream::e_l4_udp); - else if (rbL4Icmp->isChecked()) - pStream->setL4Proto(Stream::e_l4_icmp); - else if (rbL4Igmp->isChecked()) - pStream->setL4Proto(Stream::e_l4_igmp); - else - { - qCritical("No L4 Protocol??? Problem in Code!!!"); - pStream->setL4Proto(Stream::e_l4_none); - } - } - - // L2 - { - // L2 | Ethernet - { - qDebug("%s: LL dstMac = %llx", __FUNCTION__, - leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); - pStream->mac()->setDstMac( - leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); -#if 1 - qDebug("%s: dstMac = %llx", __FUNCTION__, - pStream->mac()->dstMac()); - qDebug("%s: dstMac = [%s] %d", __FUNCTION__, - leDstMac->text().toAscii().constData(), isOk); -#endif - pStream->mac()->setDstMacMode( - (MacProtocol::MacAddrMode) cmbDstMacMode->currentIndex()); - pStream->mac()->setDstMacCount( - leDstMacCount->text().toULong(&isOk)); - pStream->mac()->setDstMacStep( - leDstMacStep->text().toULong(&isOk)); - - pStream->mac()->setSrcMac( - leSrcMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); - qDebug("%s: srcMac = %llx", __FUNCTION__, - pStream->mac()->srcMac()); - qDebug("%s: srcMac = [%s] %d", __FUNCTION__, - leSrcMac->text().toAscii().constData(), isOk); - pStream->mac()->setSrcMacMode( - (MacProtocol::MacAddrMode) cmbSrcMacMode->currentIndex()); - pStream->mac()->setSrcMacCount( - leSrcMacCount->text().toULong(&isOk)); - pStream->mac()->setSrcMacStep( - - leSrcMacStep->text().toULong(&isOk)); - - { - VlanProtocol *vlan = pStream->vlan(); - VlanProtocol::VlanFlags f = 0; - - vlan->setCvlanPrio(cmbCvlanPrio->currentIndex()); - vlan->setCvlanCfi(cmbCvlanCfi->currentIndex()); - vlan->setCvlanId(leCvlanId->text().toULong(&isOk)); - vlan->setCtpid(leCvlanTpid->text().remove(QChar(' ')).toULong(&isOk, 16)); - if (cbCvlanTpidOverride->isChecked()) - f |= VlanProtocol::VlanCtpidOverride; - if (gbCvlan->isChecked()) - f |= VlanProtocol::VlanCvlanTagged; - - vlan->setSvlanPrio(cmbSvlanPrio->currentIndex()); - vlan->setSvlanCfi(cmbSvlanCfi->currentIndex()); - vlan->setSvlanId(leSvlanId->text().toULong(&isOk)); - vlan->setStpid(leSvlanTpid->text().remove(QChar(' ')).toULong(&isOk, 16)); - if (cbSvlanTpidOverride->isChecked()) - f |= VlanProtocol::VlanStpidOverride; - if (gbSvlan->isChecked()) - f |= VlanProtocol::VlanSvlanTagged; - - vlan->setVlanFlags(f); - } - } - } - - // L3 - { - // L3 | IP - { - IpProtocol *ip = pStream->ip(); - IpProtocol::IpFlags f = 0; - int ff = 0; - - ip->setVer(leIpVersion->text().toULong(&isOk)); - if (cbIpVersionOverride->isChecked()) - f |= IpProtocol::IpOverrideVersion; - ip->setHdrLen(leIpHdrLen->text().toULong(&isOk)); - if (cbIpHdrLenOverride->isChecked()) - f |= IpProtocol::IpOverrideHdrLen; - - ip->setTos(leIpTos->text().toULong(&isOk, 16)); - - ip->setTotLen(leIpLength->text().toULong(&isOk)); - if (cbIpLengthOverride->isChecked()) - f |= IpProtocol::IpOverrideHdrLen; - - ip->setId(leIpId->text().remove(QChar(' ')).toULong(&isOk, 16)); - ip->setFragOfs(leIpFragOfs->text().toULong(&isOk)); - - if (cbIpFlagsDf->isChecked()) ff |= IP_FLAG_DF; - if (cbIpFlagsMf->isChecked()) ff |= IP_FLAG_MF; - ip->setFlags(ff); - - ip->setTtl(leIpTtl->text().toULong(&isOk)); - ip->setProto(leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16)); - - ip->setCksum(leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); - if (cbIpCksumOverride->isChecked()) - f |= IpProtocol::IpOverrideCksum; - - ip->setSrcIp(QHostAddress(leIpSrcAddr->text()).toIPv4Address()); - ip->setSrcIpMode((IpProtocol::IpAddrMode) cmbIpSrcAddrMode->currentIndex()); - ip->setSrcIpCount(leIpSrcAddrCount->text().toULong(&isOk)); - ip->setSrcIpMask(QHostAddress(leIpSrcAddrMask->text()).toIPv4Address()); - - ip->setDstIp(QHostAddress(leIpDstAddr->text()).toIPv4Address()); - ip->setDstIpMode((IpProtocol::IpAddrMode) cmbIpDstAddrMode->currentIndex()); - ip->setDstIpCount(leIpDstAddrCount->text().toULong(&isOk)); - ip->setDstIpMask(QHostAddress(leIpDstAddrMask->text()).toIPv4Address()); - - ip->setIpFlags(f); - } - - // L3 | ARP - { - // TODO(LOW) - } - } - - // L4 - { - // L4 | TCP - { - TcpProtocol *tcp = pStream->tcp(); - TcpProtocol::TcpFlags f = 0; - int ff = 0; - - tcp->setSrcPort(leTcpSrcPort->text().toULong(&isOk)); - tcp->setDstPort(leTcpDstPort->text().toULong(&isOk)); - - tcp->setSeqNum(leTcpSeqNum->text().toULong(&isOk)); - tcp->setAckNum(leTcpAckNum->text().toULong(&isOk)); - - tcp->setHdrLen(leTcpHdrLen->text().toULong(&isOk)); - if (cbTcpHdrLenOverride->isChecked()) - f |= TcpProtocol::TcpOverrideHdrLen; - - tcp->setWindow(leTcpWindow->text().toULong(&isOk)); - - tcp->setCksum(leTcpCksum->text().remove(QChar(' ')).toULong(&isOk)); - if (cbTcpCksumOverride->isChecked()) - f |= TcpProtocol::TcpOverrideCksum; - - tcp->setUrgPtr(leTcpUrgentPointer->text().toULong(&isOk)); - - if (cbTcpFlagsUrg->isChecked()) ff |= TCP_FLAG_URG; - if (cbTcpFlagsAck->isChecked()) ff |= TCP_FLAG_ACK; - if (cbTcpFlagsPsh->isChecked()) ff |= TCP_FLAG_PSH; - if (cbTcpFlagsRst->isChecked()) ff |= TCP_FLAG_RST; - if (cbTcpFlagsSyn->isChecked()) ff |= TCP_FLAG_SYN; - if (cbTcpFlagsFin->isChecked()) ff |= TCP_FLAG_FIN; - tcp->setFlags(ff); - - tcp->setTcpFlags(f); - } - - // L4 | UDP - { - UdpProtocol *udp = pStream->udp(); - UdpProtocol::UdpFlags f = 0; - - udp->setSrcPort(leUdpSrcPort->text().toULong(&isOk)); - udp->setDstPort(leUdpDstPort->text().toULong(&isOk)); - - udp->setTotLen(leUdpLength->text().toULong(&isOk)); - - if (cbUdpLengthOverride->isChecked()) - f |= UdpProtocol::UdpOverrideTotLen; - - udp->setCksum(leUdpCksum->text().remove(QChar(' ')).toULong(&isOk)); - if (cbUdpCksumOverride->isChecked()) - f |= UdpProtocol::UdpOverrideCksum; - - udp->setUdpFlags(f); - } - - // L4 | ICMP - { - // TODO)(LOW) - } - - // L4 | IGMP - { - // TODO(LOW) - } + updateSelectedProtocols(); + pStream->setFrameProtocol(mSelectedProtocols); + pStream->storeProtocolWidgets(); } // Stream Control @@ -1119,11 +875,9 @@ void StreamConfigDialog::StoreCurrentStream() void StreamConfigDialog::on_pbOk_clicked() { // Store dialog contents into stream - StoreCurrentStream(); + StoreCurrentStream(mPort.streamByIndex(mCurrentStreamIndex)); qDebug("stream stored"); lastTopLevelTabIndex = twTopLevel->currentIndex(); lastProtoTabIndex = twProto->currentIndex(); } -//Junk Line for introducing a compiler error - diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 7dbedbe..f6c5a41 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -14,7 +14,7 @@ /* ** TODO -** - Improve HexStr handling +** \todo Improve HexStr handling ** */ @@ -31,9 +31,13 @@ private: Port& mPort; uint mCurrentStreamIndex; + Stream *mpStream; + QList mSelectedProtocols; + PacketModel *mpPacketModel; ModelTest *mpPacketModelTester; + // The following static variables are used to track the "selected" tab // for the various tab widgets so that it can be restored when the dialog // is opened the next time @@ -41,16 +45,12 @@ private: static int lastProtoTabIndex; void setupUiExtra(); + void updateSelectedProtocols(); void LoadCurrentStream(); - void StoreCurrentStream(); + void StoreCurrentStream(Stream *pStream); private slots: - void on_cmbPatternMode_currentIndexChanged(QString mode); void on_cmbPktLenMode_currentIndexChanged(QString mode); - void on_cmbDstMacMode_currentIndexChanged(QString mode); - void on_cmbSrcMacMode_currentIndexChanged(QString mode); - void on_cmbIpSrcAddrMode_currentIndexChanged(QString mode); - void on_cmbIpDstAddrMode_currentIndexChanged(QString mode); void on_pbPrev_clicked(); void on_pbNext_clicked(); @@ -59,21 +59,20 @@ private slots: void on_rbFt802Dot3Raw_toggled(bool checked); void on_rbFt802Dot3Llc_toggled(bool checked); void on_rbFtLlcSnap_toggled(bool checked); - void on_rbL3Ipv4_toggled(bool checked); void on_rbL3Arp_toggled(bool checked); - void on_rbL4Icmp_toggled(bool checked); void on_rbL4Igmp_toggled(bool checked); void on_rbL4Tcp_toggled(bool checked); void on_rbL4Udp_toggled(bool checked); + void on_twTopLevel_currentChanged(int index); + void on_twProto_currentChanged(int index); + void update_NumPacketsAndNumBursts(); void on_pbOk_clicked(); }; -QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets); - #endif diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 70fea95..e410c81 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,13 +8,16 @@ 0 0 - 534 - 521 + 590 + 517 Edit Stream + + :/icons/stream_edit.png + QLineEdit:enabled[inputMask = "HH; "], QLineEdit:enabled[inputMask = "HH HH; "], @@ -35,7 +38,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff 0 - + Packet Config @@ -53,57 +56,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - - - Data Pattern - - - - - - - Fixed Word - - - - - Increment Byte - - - - - Decrement Byte - - - - - Random - - - - - - - - HH HH HH HH; - - - - - - 11 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - + Frame Length (including CRC) @@ -494,1198 +448,24 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff L2 - - - - - Ethernet - - - - - - Destination - - - - - - - HH HH HH HH HH HH; - - - - - - - - - - - Fixed - - - - - Increment - - - - - Decrement - - - - - - - - Count - - - - - - - false - - - 1 - - - 1 - - - - - - - Step - - - - - - - false - - - 1 - - - 1 - - - - - - - Source - - - - - - - HH HH HH HH HH HH; - - - - - - - - - - - Fixed - - - - - Increment - - - - - Decrement - - - - - - - - Count - - - - - - - false - - - 1 - - - - - - - Step - - - - - - - false - - - 1 - - - 1 - - - - - - - - - - VLAN/CVLAN - - - true - - - false - - - - - - Priority - - - - - - - CFI - - - - - - - VLAN - - - - - - - false - - - Override TPID - - - - - - - false - - - - 0 - - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - - - - false - - - - 0 - - - - - 1 - - - - - - - - false - - - 0 - - - - - - - false - - - HH HH; - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - SVLAN - - - true - - - false - - - - - - Priority - - - - - - - CFI - - - - - - - VLAN - - - - - - - false - - - Override TPID - - - - - - - false - - - - 0 - - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - - - - false - - - - 0 - - - - - 1 - - - - - - - - false - - - 0 - - - - - - - false - - - HH HH; - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + L3 - - - - - 0 - - - - - - - - - Override Version - - - - - - - false - - - 4 - - - - - - - Override Header Length - - - - - - - false - - - 5 - - - - - - - TOS/DSCP - - - - - - - HH; - - - - - - - - - - false - - - ... - - - - - - - Override Length - - - - - - - false - - - - - - - Identification - - - - - - - HH HH; - - - - - - - - - Qt::Vertical - - - - - - - - - Fragment Offset - - - - - - - - - - Don't Fragment - - - - - - - More Fragments - - - - - - - Time To Live (TTL) - - - - - - - 64 - - - - - - - Protocol - - - - - - - false - - - - - - - - - - Override Checksum - - - - - - - false - - - HH HH; - - - - - - - - - - - - false - - - - - - Mode - - - - - - - Count - - - - - - - Mask - - - - - - - Source - - - - - - - 009.009.009.009; - - - ... - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - Fixed - - - - - Increment Host - - - - - Decrement Host - - - - - Random Host - - - - - - - - false - - - - - - - - - - false - - - 255.255.255.255 - - - - - - - Destination - - - - - - - 000.000.000.000; - - - ... - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - Fixed - - - - - Increment Host - - - - - Decrement Host - - - - - Random Host - - - - - - - - false - - - - - - - - - - false - - - 255.255.255.255 - - - - - - - - - - - - Options - - - - - - - false - - - TODO - - - - - - - false - - - ... - - - - - - - - - Qt::Vertical - - - - 469 - 16 - - - - - - - - - - - 105 - 100 - 296 - 76 - - - - ARP : TODO - - - Qt::AlignCenter - - - - - - L4 - - - - - 0 - - - - - - - - - Source Port - - - - - - - - - - Destination Port - - - - - - - - - - Sequence Number - - - - - - - - - - Acknowledgement Number - - - - - - - - - - Override Header Length (x4) - - - - - - - false - - - - - - - Window - - - - - - - - - - Override Checksum - - - - - - - false - - - HH HH; - - - - - - - Urgent Pointer - - - - - - - - - - - - Qt::Vertical - - - - - - - Flags - - - - - - URG - - - - - - - ACK - - - - - - - PSH - - - - - - - RST - - - - - - - SYN - - - - - - - FIN - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 181 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - Source Port - - - - - - - - - - Destination Port - - - - - - - - - - Override Length - - - - - - - false - - - - - - - Override Checksum - - - - - - - false - - - HH HH; - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - ICMP: TODO - - - - - - - - - - - IGMP: TODO - - - - - - - - + - + Stream Control @@ -2042,7 +822,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + Packet View @@ -2118,11 +898,6 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - HexLineEdit - QLineEdit -
hexlineedit.h
-
DumpView QWidget @@ -2132,326 +907,16 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
twTopLevel - cmbPatternMode - lePattern cmbPktLenMode lePktLen lePktLenMin lePktLenMax twProto - leDstMac - cmbDstMacMode - leDstMacCount - leDstMacStep - leSrcMac - cmbSrcMacMode - leSrcMacCount - leSrcMacStep - gbCvlan - cmbCvlanPrio - cmbCvlanCfi - leCvlanId - cbCvlanTpidOverride - leCvlanTpid - gbSvlan - cmbSvlanPrio - cmbSvlanCfi - leSvlanId - cbSvlanTpidOverride - leSvlanTpid - - cbCvlanTpidOverride - toggled(bool) - leCvlanTpid - setEnabled(bool) - - - 112 - 267 - - - 112 - 267 - - - - - cbSvlanTpidOverride - toggled(bool) - leSvlanTpid - setEnabled(bool) - - - 112 - 267 - - - 112 - 267 - - - - - gbCvlan - toggled(bool) - cmbCvlanPrio - setEnabled(bool) - - - 92 - 267 - - - 92 - 267 - - - - - gbCvlan - toggled(bool) - cmbCvlanCfi - setEnabled(bool) - - - 92 - 267 - - - 92 - 267 - - - - - gbCvlan - toggled(bool) - leCvlanId - setEnabled(bool) - - - 92 - 267 - - - 92 - 267 - - - - - gbCvlan - toggled(bool) - cbCvlanTpidOverride - setEnabled(bool) - - - 92 - 267 - - - 112 - 267 - - - - - gbSvlan - toggled(bool) - cmbSvlanPrio - setEnabled(bool) - - - 92 - 267 - - - 92 - 267 - - - - - gbSvlan - toggled(bool) - leSvlanId - setEnabled(bool) - - - 92 - 267 - - - 92 - 267 - - - - - gbSvlan - toggled(bool) - cbSvlanTpidOverride - setEnabled(bool) - - - 92 - 267 - - - 112 - 267 - - - - - gbSvlan - toggled(bool) - cmbSvlanCfi - setEnabled(bool) - - - 92 - 267 - - - 92 - 267 - - - - - cbUdpLengthOverride - toggled(bool) - leUdpLength - setEnabled(bool) - - - 145 - 334 - - - 145 - 334 - - - - - cbUdpCksumOverride - toggled(bool) - leUdpCksum - setEnabled(bool) - - - 145 - 334 - - - 145 - 334 - - - - - cbIpVersionOverride - toggled(bool) - leIpVersion - setEnabled(bool) - - - 123 - 305 - - - 123 - 305 - - - - - cbIpHdrLenOverride - toggled(bool) - leIpHdrLen - setEnabled(bool) - - - 123 - 305 - - - 123 - 305 - - - - - cbIpLengthOverride - toggled(bool) - leIpLength - setEnabled(bool) - - - 123 - 305 - - - 123 - 305 - - - - - cbIpCksumOverride - toggled(bool) - leIpCksum - setEnabled(bool) - - - 192 - 305 - - - 192 - 305 - - - - - cbTcpHdrLenOverride - toggled(bool) - leTcpHdrLen - setEnabled(bool) - - - 145 - 334 - - - 145 - 334 - - - - - cbTcpCksumOverride - toggled(bool) - leTcpCksum - setEnabled(bool) - - - 145 - 334 - - - 145 - 334 - - - pbOk clicked() @@ -2459,11 +924,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff accept() - 460 - 510 + 440 + 466 - 565 + 533 433 @@ -2475,11 +940,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff reject() - 543 - 510 + 523 + 466 - 561 + 533 466 @@ -2491,12 +956,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 136 - 120 + 281 + 137 - 136 - 120 + 281 + 169 @@ -2507,12 +972,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 41 - 101 + 30 + 66 - 96 - 120 + 30 + 266 @@ -2523,12 +988,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 41 - 120 + 30 + 91 - 78 - 120 + 30 + 312 @@ -2539,12 +1004,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 41 - 120 + 30 + 91 - 136 - 120 + 134 + 177 diff --git a/client/streammodel.cpp b/client/streammodel.cpp index 6680f58..c1b887c 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -82,7 +82,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const case StreamName: { if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) - return mCurrentPort->streamByIndex(index.row()).name(); + return mCurrentPort->streamByIndex(index.row())->name(); else return QVariant(); break; @@ -91,7 +91,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const { if ((role == Qt::CheckStateRole)) { - if (mCurrentPort->streamByIndex(index.row()).isEnabled()) + if (mCurrentPort->streamByIndex(index.row())->isEnabled()) return Qt::Checked; else return Qt::Unchecked; @@ -102,7 +102,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const } case StreamNextWhat: { - int val = mCurrentPort->streamByIndex(index.row()).nextWhat(); + int val = mCurrentPort->streamByIndex(index.row())->nextWhat(); if (role == Qt::DisplayRole) return nextWhatOptionList().at(val); @@ -131,19 +131,19 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r { // Edit Supported Fields case StreamName: - mCurrentPort->streamByIndex(index.row()).setName(value.toString()); + mCurrentPort->streamByIndex(index.row())->setName(value.toString()); emit(dataChanged(index, index)); return true; case StreamStatus: - mCurrentPort->streamByIndex(index.row()).setIsEnabled(value.toBool()); + mCurrentPort->streamByIndex(index.row())->setIsEnabled(value.toBool()); emit(dataChanged(index, index)); return true; case StreamNextWhat: if (role == Qt::EditRole) { - mCurrentPort->streamByIndex(index.row()).setNextWhat( + mCurrentPort->streamByIndex(index.row())->setNextWhat( (Stream::NextWhat)value.toInt()); emit(dataChanged(index, index)); return true; diff --git a/common/Makefile b/common/Makefile deleted file mode 100644 index 7c95f2b..0000000 --- a/common/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -RM=del -PROTOC=protoc - -#-#-# - -all: protocol.pb.cc - -protocol.pb.cc: protocol.proto - $(PROTOC) --cpp_out=. $< - -clean: - $(RM) *.pb.h *.pb.cc - -distclean: clean diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp new file mode 100644 index 0000000..429c6a3 --- /dev/null +++ b/common/abstractprotocol.cpp @@ -0,0 +1,225 @@ +#include "abstractprotocol.h" + +/*! + \class AbstractProtocol + + // FIXME - update this text + Bare Minimum set of methods that a subclass needs to reimplement + - protoDataCopyInto() [pure virtual] + - protoDataCopyFrom() [pure virtual] + - fieldCount() + + Any useful protocol should also provide implementations for + - name() + - shortName() + - fieldName() + + Protocols with meta fields should additionally implement + - metaFieldCount() + - isMetaField() +*/ +AbstractProtocol::AbstractProtocol(Stream *parent) +{ + stream = parent; + metaCount = -1; +} + +AbstractProtocol::~AbstractProtocol() +{ +} + + +/*! + \fn virtual void protoDataCopyInto(OstProto::Stream &stream) = 0; + + Copy the protocol's protobuf into the passed in stream \n + In the base class this is a pure virtual function. Subclasses should + implement this function by using - \n + stream.AddExtension()->CopyFrom() */ + +/* + \fn virtual void protoDataCopyFrom(const OstProto::Stream &stream) = 0; + FIXME */ + +/*! Returns the full name of the protocol \n + The default implementation returns a null string */ +QString AbstractProtocol::name() const +{ + return QString(); +} + +/*! Returns the short name or abbreviation of the protocol \n + The default implementation forms and returns a abbreviation composed + of all the upper case chars in name() \n + The default implementation caches the abbreviation on its first invocation + and subsequently returns the cached abbreviation */ +QString AbstractProtocol::shortName() const +{ + if (protoAbbr.isNull()) + { + QString abbr; + + for (int i = 0; i < name().size(); i++) + if (name().at(i).isUpper()) abbr.append(name().at(i)); + + if (abbr.size()) + protoAbbr = abbr; + else + protoAbbr = QString(""); + } + + return protoAbbr; +} + +/*! Returns the number of fields (both Frame and Meta fields) \n + The default implementation returns zero */ +int AbstractProtocol::fieldCount() const +{ + return 0; +} + +/*! Returns the number of meta fields \n + The default implementation counts and returns the number of fields for which + fieldData(index, FieldIsMeta) return true\n + The default implementation caches the count on its first invocation + and subsequently returns the cached count */ +int AbstractProtocol::metaFieldCount() const +{ + if (metaCount < 0) + { + int c = 0; + for (int i = 0; i < fieldCount() ; i++) + if (fieldData(i, FieldIsMeta).toBool()) + c++; + metaCount = c; + } + + return metaCount; +} + +/*! Returns the number of frame fields \n + Convenience method - same as fieldCount() minus metaFieldCount() */ +int AbstractProtocol::frameFieldCount() const +{ + //qDebug("%s:%d, %d", __FUNCTION__, fieldCount(), metaFieldCount()); + return (fieldCount() - metaFieldCount()); +} + +/*! Returns the requested field attribute data \n + Protocols which have meta fields that vary a frame field across + streams may use the streamIndex to return the appropriate field value \n + Some field attriubutes e.g. FieldName may be invariant across streams\n + The default implementation returns the fieldValue() converted to string + The FieldTextValue attribute may include additional information about + the field's value e.g. a checksum field may include "(correct)" or + "(incorrect)" alongwith the actual checksum value. \n + The default implementation returns FIXME + */ +QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (attrib) + { + case FieldName: + return QString(); + case FieldBitSize: + return fieldData(index, FieldFrameValue, streamIndex). + toByteArray().size() * 8; + case FieldValue: + return 0; + case FieldFrameValue: + return QByteArray(); + case FieldTextValue: + return QString(); + case FieldIsMeta: + return false; + + default: + qFatal("%s:%d: unhandled case %d\n", __FUNCTION__, __LINE__, + attrib); + } + + return QVariant(); +} + +/*! Sets the value of a field corresponding to index \n + Returns true if field is successfully set, false otherwise \n + The default implementation always returns false */ +bool AbstractProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + return false; +} + +/*! Returns a byte array encoding the protocol (and its fields) which can be + inserted into the stream's frame + The default implementation forms and returns an ordered concatenation of + the FrameValue of all the 'frame' fields of the protocol taking care of fields + which are not an integral number of bytes\n */ +QByteArray AbstractProtocol::protocolFrameValue(int streamIndex) const +{ + QByteArray proto, field; + int bits, lastbitpos = 0; + + for (int i=0; i < fieldCount() ; i++) + { + if (!fieldData(i, FieldIsMeta).toBool()) + { + field = fieldData(i, FieldFrameValue, streamIndex).toByteArray(); + bits = fieldData(i, FieldBitSize, streamIndex).toUInt(); + if (bits == 0) + continue; + + qDebug("<<< %d, %d >>>>", proto.size(), field.size()); + + if (bits == field.size() * 8) + { + if (lastbitpos == 0) + proto.append(field); + else + { + Q_ASSERT(field.size() > 0); + + char c = proto[proto.size() - 1]; + proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos); + for (int j = 0; j < field.size() - 1; j++) + proto.append(field.at(j) << lastbitpos | + field.at(j+1) >> lastbitpos); + } + } + else if (bits < field.size() * 8) + { + int u, v; + + u = bits / 8; + v = bits % 8; + if (lastbitpos == 0) + { + proto.append(field.left(u+1)); + char c = proto[proto.size() - 1]; + proto[proto.size() - 1] = c & (0xFF << (8 - v)); + lastbitpos = v; + } + else + { + char c = proto[proto.size() - 1]; + proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos); + for (int j = 0; j < (u - 1); j++) + proto.append(field.at(j) << lastbitpos | + field.at(j+1) >> lastbitpos); + if (u) + proto.append( field.at(u) & (0xFF << (8 - v)) ); + lastbitpos = (lastbitpos + bits) % 8; + } + } + else // if (bits > field.size() * 8) + { + qFatal("bitsize more than FrameValue size. skipping..."); + continue; + } + } + } + + return proto; +} + diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h new file mode 100644 index 0000000..7c7255e --- /dev/null +++ b/common/abstractprotocol.h @@ -0,0 +1,62 @@ +#ifndef _ABSTRACT_PROTOCOL_H +#define _ABSTRACT_PROTOCOL_H + +#include +#include +#include +#include + +#include "../common/protocol.pb.h" + +#define BASE_BIN (2) +#define BASE_OCT (8) +#define BASE_DEC (10) +#define BASE_HEX (16) + +class Stream; + +class AbstractProtocol +{ +private: + mutable int metaCount; + mutable QString protoAbbr; + +protected: + Stream *stream; + +public: + enum FieldAttrib { + FieldName, //! name + FieldValue, //! value in host byte order (user editable) + FieldTextValue, //! value as text + FieldFrameValue, //! frame encoded value in network byte order + FieldBitSize, //! size in bits + FieldIsMeta //! bool indicating if field is meta + }; + + AbstractProtocol(Stream *parent = 0); + virtual ~AbstractProtocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream) = 0; + virtual void protoDataCopyFrom(const OstProto::Stream &stream) = 0; + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + virtual int metaFieldCount() const; + int frameFieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + QByteArray protocolFrameValue(int streamIndex = 0) const; + + virtual QWidget* configWidget() = 0; + virtual void loadConfigWidget() = 0; + virtual void storeConfigWidget() = 0; +}; + +#endif diff --git a/common/dot3.cpp b/common/dot3.cpp new file mode 100644 index 0000000..67b70d9 --- /dev/null +++ b/common/dot3.cpp @@ -0,0 +1,110 @@ +#include +#include + +#include "Dot3.h" + +Dot3ConfigForm *Dot3Protocol::configForm = NULL; + +Dot3ConfigForm::Dot3ConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +Dot3Protocol::Dot3Protocol(Stream *parent) + : AbstractProtocol(parent) +{ + if (configForm == NULL) + configForm = new Dot3ConfigForm; +} + +Dot3Protocol::~Dot3Protocol() +{ +} + +void Dot3Protocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::dot3)->CopyFrom(data); +} + +void Dot3Protocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::dot3)) + data.MergeFrom(stream.GetExtension(OstProto::dot3)); +} + +QString Dot3Protocol::name() const +{ + return QString("802.3"); +} + +QString Dot3Protocol::shortName() const +{ + return QString("802.3"); +} + +int Dot3Protocol::fieldCount() const +{ + return dot3_fieldCount; +} + +QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case dot3_length: + switch(attrib) + { + case FieldName: + return QString("Length"); + case FieldValue: + return data.length(); + case FieldTextValue: + return QString("%1").arg(data.length()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.length(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool Dot3Protocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* Dot3Protocol::configWidget() +{ + return configForm; +} + +void Dot3Protocol::loadConfigWidget() +{ + configForm->leLength->setText(QString().setNum(data.length())); +} + +void Dot3Protocol::storeConfigWidget() +{ + bool isOk; + + data.set_length(configForm->leLength->text().toULong(&isOk)); +} + diff --git a/common/dot3.h b/common/dot3.h new file mode 100644 index 0000000..e49f312 --- /dev/null +++ b/common/dot3.h @@ -0,0 +1,50 @@ +#ifndef _DOT3_H +#define _DOT3_H + +#include "abstractprotocol.h" + +#include "dot3.pb.h" +#include "ui_Dot3.h" + +class Dot3ConfigForm : public QWidget, public Ui::dot3 +{ + Q_OBJECT +public: + Dot3ConfigForm(QWidget *parent = 0); +}; + +class Dot3Protocol : public AbstractProtocol +{ +private: + OstProto::Dot3 data; + static Dot3ConfigForm *configForm; + enum Dot3field + { + dot3_length, + + dot3_fieldCount + }; + +public: + Dot3Protocol(Stream *parent = 0); + virtual ~Dot3Protocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/dot3.proto b/common/dot3.proto new file mode 100644 index 0000000..37f78ca --- /dev/null +++ b/common/dot3.proto @@ -0,0 +1,12 @@ +import "protocol.proto"; + +package OstProto; + +// 802.3 +message Dot3 { + optional uint32 length = 1; +} + +extend Stream { + optional Dot3 dot3 = 122; +} diff --git a/common/dot3.ui b/common/dot3.ui new file mode 100644 index 0000000..d452bd0 --- /dev/null +++ b/common/dot3.ui @@ -0,0 +1,59 @@ + + dot3 + + + + 0 + 0 + 131 + 72 + + + + Form + + + + + + 802.3 + + + + + + Length + + + leLength + + + + + + + false + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + diff --git a/common/eth2.cpp b/common/eth2.cpp new file mode 100644 index 0000000..caaf75b --- /dev/null +++ b/common/eth2.cpp @@ -0,0 +1,129 @@ +#include +#include + +#include "eth2.h" + +Eth2ConfigForm *Eth2Protocol::configForm = NULL; + +Eth2ConfigForm::Eth2ConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +Eth2Protocol::Eth2Protocol(Stream *parent) + : AbstractProtocol(parent) +{ + if (configForm == NULL) + configForm = new Eth2ConfigForm; +} + +Eth2Protocol::~Eth2Protocol() +{ +} + +void Eth2Protocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::eth2)->CopyFrom(data); +} + +void Eth2Protocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::eth2)) + data.MergeFrom(stream.GetExtension(OstProto::eth2)); +} + +QString Eth2Protocol::name() const +{ + return QString("Ethernet II"); +} + +QString Eth2Protocol::shortName() const +{ + return QString("Eth II"); +} + +int Eth2Protocol::fieldCount() const +{ + return eth2_fieldCount; +} + +QVariant Eth2Protocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case eth2_type: + switch(attrib) + { + case FieldName: + return QString("Type"); + case FieldValue: + return data.type(); + case FieldTextValue: + return QString("%1").arg(data.type(), 16); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.type(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool Eth2Protocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + bool isOk = false; + + if (attrib != FieldValue) + return false; + + switch (index) + { + case eth2_type: + { + uint type = value.toUInt(&isOk); + if (isOk) + data.set_type(type); + } + default: + break; + } + return isOk; +} + +QWidget* Eth2Protocol::configWidget() +{ + return configForm; +} + +void Eth2Protocol::loadConfigWidget() +{ +#define uintToHexStr(num, bytesize) \ + QString("%1").arg((num), (bytesize)*2 , 16, QChar('0')) + + configForm->leType->setText(uintToHexStr(data.type(), 2)); + +#undef uintToHexStr +} + +void Eth2Protocol::storeConfigWidget() +{ + bool isOk; + + data.set_type(configForm->leType->text().remove(QChar(' ')).toULong(&isOk, 16)); +} + diff --git a/common/eth2.h b/common/eth2.h new file mode 100644 index 0000000..580b712 --- /dev/null +++ b/common/eth2.h @@ -0,0 +1,50 @@ +#ifndef _ETH2_H +#define _ETH2_H + +#include "abstractprotocol.h" + +#include "eth2.pb.h" +#include "ui_eth2.h" + +class Eth2ConfigForm : public QWidget, public Ui::eth2 +{ + Q_OBJECT +public: + Eth2ConfigForm(QWidget *parent = 0); +}; + +class Eth2Protocol : public AbstractProtocol +{ +private: + OstProto::Eth2 data; + static Eth2ConfigForm *configForm; + enum eth2field + { + eth2_type = 0, + + eth2_fieldCount + }; + +public: + Eth2Protocol(Stream *parent = 0); + virtual ~Eth2Protocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/eth2.proto b/common/eth2.proto new file mode 100644 index 0000000..224c25d --- /dev/null +++ b/common/eth2.proto @@ -0,0 +1,12 @@ +import "protocol.proto"; + +package OstProto; + +// Ethernet II +message Eth2 { + optional uint32 type = 1; +} + +extend Stream { + optional Eth2 eth2 = 121; +} diff --git a/common/eth2.ui b/common/eth2.ui new file mode 100644 index 0000000..9099dbb --- /dev/null +++ b/common/eth2.ui @@ -0,0 +1,62 @@ + + eth2 + + + + 0 + 0 + 166 + 72 + + + + Form + + + + + + Ethernet II + + + + + + Ethernet Type + + + leType + + + + + + + true + + + HH HH; + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + diff --git a/common/ip4.cpp b/common/ip4.cpp new file mode 100644 index 0000000..625d3c7 --- /dev/null +++ b/common/ip4.cpp @@ -0,0 +1,455 @@ +#include +#include + +#include "ip4.h" + +Ip4ConfigForm *Ip4Protocol::configForm = NULL; + +Ip4ConfigForm::Ip4ConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + connect(cmbIpSrcAddrMode, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_cmbIpSrcAddrMode_currentIndexChanged(int))); + connect(cmbIpDstAddrMode, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_cmbIpDstAddrMode_currentIndexChanged(int))); +} + +void Ip4ConfigForm::on_cmbIpSrcAddrMode_currentIndexChanged(int index) +{ + if (index == OstProto::Ip4::e_im_fixed) + { + leIpSrcAddrCount->setDisabled(true); + leIpSrcAddrMask->setDisabled(true); + } + else + { + leIpSrcAddrCount->setEnabled(true); + leIpSrcAddrMask->setEnabled(true); + } +} + +void Ip4ConfigForm::on_cmbIpDstAddrMode_currentIndexChanged(int index) +{ + if (index == OstProto::Ip4::e_im_fixed) + { + leIpDstAddrCount->setDisabled(true); + leIpDstAddrMask->setDisabled(true); + } + else + { + leIpDstAddrCount->setEnabled(true); + leIpDstAddrMask->setEnabled(true); + } +} + +Ip4Protocol::Ip4Protocol(Stream *parent) + : AbstractProtocol(parent) +{ + if (configForm == NULL) + configForm = new Ip4ConfigForm; +} + +Ip4Protocol::~Ip4Protocol() +{ +} + +void Ip4Protocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::ip4)->CopyFrom(data); +} + +void Ip4Protocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::ip4)) + data.MergeFrom(stream.GetExtension(OstProto::ip4)); +} + +QString Ip4Protocol::name() const +{ + return QString("Internet Protocol ver 4"); +} + +QString Ip4Protocol::shortName() const +{ + return QString("IPv4"); +} + +int Ip4Protocol::fieldCount() const +{ + return ip4_fieldCount; +} + +QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case ip4_ver: + switch(attrib) + { + case FieldName: + return QString("Version"); + case FieldValue: + return (data.ver_hdrlen() >> 4) & 0x0F; + case FieldTextValue: + return QString("%1").arg((data.ver_hdrlen() >> 4) & 0x0F); + case FieldFrameValue: + return QByteArray(1, (char)(data.ver_hdrlen() & 0xF0)); + case FieldBitSize: + return 4; + default: + break; + } + break; + case ip4_hdrLen: + switch(attrib) + { + case FieldName: + return QString("Header Length"); + case FieldValue: + return data.ver_hdrlen() & 0x0F; + case FieldTextValue: + return QString("%1").arg(data.ver_hdrlen() & 0x0F); + case FieldFrameValue: + return QByteArray(1, (char)(data.ver_hdrlen() << 4)); + case FieldBitSize: + return 4; + default: + break; + } + break; + case ip4_tos: + switch(attrib) + { + case FieldName: + return QString("TOS/DSCP"); + case FieldValue: + return data.tos(); + case FieldFrameValue: + return QByteArray(1, (char) data.tos()); + case FieldTextValue: + return QString("0x%1"). + arg(data.tos(), 2, BASE_HEX, QChar('0'));; + default: + break; + } + break; + case ip4_totLen: + switch(attrib) + { + case FieldName: + return QString("Total Length"); + case FieldValue: + return data.totlen(); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.totlen(), (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("%1").arg(data.totlen()); + default: + break; + } + break; + case ip4_id: + switch(attrib) + { + case FieldName: + return QString("Identification"); + case FieldValue: + return data.id(); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.id(), (uchar*)fv.data()); + return fv; + } + case FieldTextValue: + return QString("0x%1"). + arg(data.id(), 2, BASE_HEX, QChar('0'));; + default: + break; + } + break; + case ip4_flags: + switch(attrib) + { + case FieldName: + return QString("Flags"); + case FieldValue: + return data.flags(); + case FieldFrameValue: + return QByteArray(1, (char) data.flags()); + case FieldTextValue: + { + QString s; + s.append("Unused:"); + s.append(data.flags() & IP_FLAG_UNUSED ? "1" : "0"); + s.append(" Don't Fragment:"); + s.append(data.flags() & IP_FLAG_DF ? "1" : "0"); + s.append(" More Fragments:"); + s.append(data.flags() & IP_FLAG_MF ? "1" : "0"); + return s; + } + case FieldBitSize: + return 3; + default: + break; + } + break; + case ip4_fragOfs: + switch(attrib) + { + case FieldName: + return QString("Fragment Offset"); + case FieldValue: + return data.frag_ofs(); + case FieldFrameValue: + { + QByteArray fv; + // FIXME need to shift for 13 bits + fv.resize(2); + qToBigEndian((quint16) data.frag_ofs(), (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("%1").arg(data.frag_ofs()); + case FieldBitSize: + return 13; + default: + break; + } + break; + case ip4_ttl: + switch(attrib) + { + case FieldName: + return QString("Time to Live"); + case FieldValue: + return data.ttl(); + case FieldFrameValue: + return QByteArray(1, (char)data.ttl()); + case FieldTextValue: + return QString("%1").arg(data.ttl()); + default: + break; + } + break; + case ip4_proto: + switch(attrib) + { + case FieldName: + return QString("Protocol"); + case FieldValue: + return data.proto(); + case FieldFrameValue: + return QByteArray(1, (char)data.proto()); + case FieldTextValue: + return QString("0x%1"). + arg(data.proto(), 2, BASE_HEX, QChar('0')); + default: + break; + } + break; + case ip4_cksum: + switch(attrib) + { + case FieldName: + return QString("Header Checksum"); + case FieldValue: + return data.cksum(); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.cksum(), (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("0x%1"). + arg(data.cksum(), 4, BASE_HEX, QChar('0'));; + default: + break; + } + break; + case ip4_srcAddr: + switch(attrib) + { + case FieldName: + return QString("Source"); + case FieldValue: + return data.src_ip(); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.src_ip(), (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QHostAddress(data.src_ip()).toString(); + default: + break; + } + break; + case ip4_dstAddr: + switch(attrib) + { + case FieldName: + return QString("Destination"); + case FieldValue: + return data.dst_ip(); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.dst_ip(), (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QHostAddress(data.dst_ip()).toString(); + default: + break; + } + break; + + // Meta fields + + case ip4_isOverrideVer: + case ip4_isOverrideHdrLen: + case ip4_isOverrideTotLen: + case ip4_isOverrideCksum: + + case ip4_srcAddrMode: + case ip4_srcAddrCount: + case ip4_srcAddrMask: + + case ip4_dstAddrMode: + case ip4_dstAddrCount: + case ip4_dstAddrMask: + switch(attrib) + { + case FieldIsMeta: + return true; + default: + break; + } + break; + + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool Ip4Protocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + bool isOk = false; + + if (attrib != FieldValue) + return false; + + switch (index) + { + case ip4_proto: + { + uint proto = value.toUInt(&isOk); + if (isOk) + data.set_proto(proto); + } + default: + break; + } + return isOk; +} + + +QWidget* Ip4Protocol::configWidget() +{ + return configForm; +} + +void Ip4Protocol::loadConfigWidget() +{ +#define uintToHexStr(num, str, size) QString().setNum(num, 16) + configForm->leIpVersion->setText(QString().setNum(data.ver_hdrlen() >> 4)); + configForm->cbIpVersionOverride->setChecked(data.is_override_ver()); + + configForm->leIpHdrLen->setText(QString().setNum(data.ver_hdrlen() & 0x0F)); + configForm->cbIpHdrLenOverride->setChecked(data.is_override_hdrlen()); + + configForm->leIpTos->setText(uintToHexStr(data.tos(), QString(), 1)); + + configForm->leIpLength->setText(QString().setNum(data.totlen())); + configForm->cbIpLengthOverride->setChecked(data.is_override_totlen()); + + configForm->leIpId->setText(uintToHexStr(data.id(), QString(), 2)); + configForm->leIpFragOfs->setText(QString().setNum(data.frag_ofs())); + configForm->cbIpFlagsDf->setChecked((data.flags() & IP_FLAG_DF) > 0); + configForm->cbIpFlagsMf->setChecked((data.flags() & IP_FLAG_MF) > 0); + + configForm->leIpTtl->setText(QString().setNum(data.ttl())); + configForm->leIpProto->setText(uintToHexStr(data.proto(), QString(), 1)); + + configForm->leIpCksum->setText(uintToHexStr(data.cksum(), QString(), 2)); + configForm->cbIpCksumOverride->setChecked(data.is_override_cksum()); + + configForm->leIpSrcAddr->setText(QHostAddress(data.src_ip()).toString()); + configForm->cmbIpSrcAddrMode->setCurrentIndex(data.src_ip_mode()); + configForm->leIpSrcAddrCount->setText(QString().setNum(data.src_ip_count())); + configForm->leIpSrcAddrMask->setText(QHostAddress(data.src_ip_mask()).toString()); + + configForm->leIpDstAddr->setText(QHostAddress(data.dst_ip()).toString()); + configForm->cmbIpDstAddrMode->setCurrentIndex(data.dst_ip_mode()); + configForm->leIpDstAddrCount->setText(QString().setNum(data.dst_ip_count())); + configForm->leIpDstAddrMask->setText(QHostAddress(data.dst_ip_mask()).toString()); +} + +void Ip4Protocol::storeConfigWidget() +{ + uint ff = 0; + bool isOk; + + data.set_is_override_ver(configForm->cbIpVersionOverride->isChecked()); + data.set_ver_hdrlen(((configForm->leIpVersion->text().toULong(&isOk) & 0x0F) << 4) | + (configForm->leIpHdrLen->text().toULong(&isOk) & 0x0F)); + data.set_is_override_hdrlen(configForm->cbIpHdrLenOverride->isChecked()); + + data.set_tos(configForm->leIpTos->text().toULong(&isOk, 16)); + + data.set_totlen(configForm->leIpLength->text().toULong(&isOk)); + data.set_is_override_totlen(configForm->cbIpLengthOverride->isChecked()); + + data.set_id(configForm->leIpId->text().remove(QChar(' ')).toULong(&isOk, 16)); + data.set_frag_ofs(configForm->leIpFragOfs->text().toULong(&isOk)); + + if (configForm->cbIpFlagsDf->isChecked()) ff |= IP_FLAG_DF; + if (configForm->cbIpFlagsMf->isChecked()) ff |= IP_FLAG_MF; + data.set_flags(ff); + + data.set_ttl(configForm->leIpTtl->text().toULong(&isOk)); + data.set_proto(configForm->leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16)); + + data.set_cksum(configForm->leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); + data.set_is_override_cksum(configForm->cbIpCksumOverride->isChecked()); + + data.set_src_ip(QHostAddress(configForm->leIpSrcAddr->text()).toIPv4Address()); + data.set_src_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpSrcAddrMode->currentIndex()); + data.set_src_ip_count(configForm->leIpSrcAddrCount->text().toULong(&isOk)); + data.set_src_ip_mask(QHostAddress(configForm->leIpSrcAddrMask->text()).toIPv4Address()); + + data.set_dst_ip(QHostAddress(configForm->leIpDstAddr->text()).toIPv4Address()); + data.set_dst_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpDstAddrMode->currentIndex()); + data.set_dst_ip_count(configForm->leIpDstAddrCount->text().toULong(&isOk)); +} + diff --git a/common/ip4.h b/common/ip4.h new file mode 100644 index 0000000..73d3004 --- /dev/null +++ b/common/ip4.h @@ -0,0 +1,83 @@ +#ifndef _IPV4_H +#define _IPV4_H + +#include "abstractprotocol.h" + +#include "ip4.pb.h" +#include "ui_ip4.h" + +#define IP_FLAG_UNUSED 0x1 +#define IP_FLAG_DF 0x2 +#define IP_FLAG_MF 0x4 + + +class Ip4ConfigForm : public QWidget, public Ui::ip4 +{ + Q_OBJECT +public: + Ip4ConfigForm(QWidget *parent = 0); +private slots: + void on_cmbIpSrcAddrMode_currentIndexChanged(int index); + void on_cmbIpDstAddrMode_currentIndexChanged(int index); +}; + +class Ip4Protocol : public AbstractProtocol +{ +private: + OstProto::Ip4 data; + static Ip4ConfigForm *configForm; + enum ip4field + { + ip4_ver = 0, + ip4_hdrLen, + ip4_tos, + ip4_totLen, + ip4_id, + ip4_flags, + ip4_fragOfs, + ip4_ttl, + ip4_proto, + ip4_cksum, + ip4_srcAddr, + ip4_dstAddr, + + ip4_isOverrideVer, + ip4_isOverrideHdrLen, + ip4_isOverrideTotLen, + ip4_isOverrideCksum, + + ip4_srcAddrMode, + ip4_srcAddrCount, + ip4_srcAddrMask, + + ip4_dstAddrMode, + ip4_dstAddrCount, + ip4_dstAddrMask, + + ip4_fieldCount + }; + +public: + Ip4Protocol(Stream *parent = 0); + virtual ~Ip4Protocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + + +#endif diff --git a/common/ip4.proto b/common/ip4.proto new file mode 100644 index 0000000..af61255 --- /dev/null +++ b/common/ip4.proto @@ -0,0 +1,47 @@ +import "protocol.proto"; + +package OstProto; +// IPv4 +message Ip4 { + + enum IpAddrMode { + e_im_fixed = 0; + e_im_inc_host = 1; + e_im_dec_host = 2; + e_im_random_host = 3; + } + + optional bool is_override_ver = 1; + optional bool is_override_hdrlen = 2; + optional bool is_override_totlen = 3; + optional bool is_override_cksum = 4; + + optional uint32 ver_hdrlen = 5 [default = 0x45]; + optional uint32 tos = 6; + optional uint32 totlen = 7; + optional uint32 id = 8 [default = 1234]; + // TODO: rename flags to frag_flags + optional uint32 flags = 9; + optional uint32 frag_ofs = 10; + optional uint32 ttl = 11 [default = 127]; + optional uint32 proto = 12; + optional uint32 cksum = 13; + + // Source IP + optional fixed32 src_ip = 14; + optional IpAddrMode src_ip_mode = 15 [default = e_im_fixed]; + optional uint32 src_ip_count = 16 [default = 16]; + optional fixed32 src_ip_mask = 17 [default = 0xFFFFFFFF]; + + // Destination IP + optional fixed32 dst_ip = 18; + optional IpAddrMode dst_ip_mode = 19 [default = e_im_fixed]; + optional uint32 dst_ip_count = 20 [default = 16]; + optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFFFF]; + + // TODO: Options +} + +extend Stream { + optional Ip4 ip4 = 130; +} diff --git a/common/ip4.ui b/common/ip4.ui new file mode 100644 index 0000000..35a85bf --- /dev/null +++ b/common/ip4.ui @@ -0,0 +1,479 @@ + + ip4 + + + + 0 + 0 + 504 + 296 + + + + Form + + + + + + + + Override Version + + + + + + + false + + + 4 + + + + + + + Override Header Length + + + + + + + false + + + 5 + + + + + + + TOS/DSCP + + + + + + + HH; + + + + + + + + + + false + + + ... + + + + + + + Override Length + + + + + + + false + + + + + + + Identification + + + + + + + HH HH; + + + + + + + + + Qt::Vertical + + + + + + + + + Fragment Offset + + + + + + + + + + Don't Fragment + + + + + + + More Fragments + + + + + + + Time To Live (TTL) + + + + + + + 64 + + + + + + + Protocol + + + + + + + false + + + + + + + + + + Override Checksum + + + + + + + false + + + HH HH; + + + + + + + + + + + + false + + + + + + Qt::Horizontal + + + + 101 + 20 + + + + + + + + Mode + + + + + + + Count + + + + + + + Mask + + + + + + + Source + + + + + + + 009.009.009.009; + + + ... + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment Host + + + + + Decrement Host + + + + + Random Host + + + + + + + + false + + + + + + + + + + false + + + 255.255.255.255 + + + + + + + Destination + + + + + + + 000.000.000.000; + + + ... + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment Host + + + + + Decrement Host + + + + + Random Host + + + + + + + + false + + + + + + + + + + false + + + 255.255.255.255 + + + + + + + + + + + + Options + + + + + + + false + + + TODO + + + + + + + false + + + ... + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + cbIpVersionOverride + toggled(bool) + leIpVersion + setEnabled(bool) + + + 108 + 11 + + + 195 + 11 + + + + + cbIpHdrLenOverride + toggled(bool) + leIpHdrLen + setEnabled(bool) + + + 118 + 43 + + + 166 + 43 + + + + + cbIpLengthOverride + toggled(bool) + leIpLength + setEnabled(bool) + + + 79 + 97 + + + 172 + 97 + + + + + cbIpCksumOverride + toggled(bool) + leIpCksum + setEnabled(bool) + + + 345 + 122 + + + 406 + 122 + + + + + diff --git a/common/llc.cpp b/common/llc.cpp new file mode 100644 index 0000000..394ca2c --- /dev/null +++ b/common/llc.cpp @@ -0,0 +1,139 @@ +#include +#include + +#include "llc.h" + +LlcConfigForm *LlcProtocol::configForm = NULL; + +LlcConfigForm::LlcConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +LlcProtocol::LlcProtocol(Stream *parent) + : AbstractProtocol(parent) +{ + if (configForm == NULL) + configForm = new LlcConfigForm; +} + +LlcProtocol::~LlcProtocol() +{ +} + +void LlcProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::llc)->CopyFrom(data); +} + +void LlcProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::llc)) + data.MergeFrom(stream.GetExtension(OstProto::llc)); +} + +QString LlcProtocol::name() const +{ + return QString("802.3 Logical Link Control"); +} + +QString LlcProtocol::shortName() const +{ + return QString("LLC"); +} + +int LlcProtocol::fieldCount() const +{ + return llc_fieldCount; +} + +QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case llc_dsap: + switch(attrib) + { + case FieldName: + return QString("DSAP"); + case FieldValue: + return data.dsap(); + case FieldTextValue: + return QString("%1").arg(data.dsap(), BASE_HEX); + case FieldFrameValue: + return QByteArray(1, (char)(data.dsap())); + default: + break; + } + break; + case llc_ssap: + switch(attrib) + { + case FieldName: + return QString("DSAP"); + case FieldValue: + return data.ssap(); + case FieldTextValue: + return QString("%1").arg(data.ssap(), BASE_HEX); + case FieldFrameValue: + return QByteArray(1, (char)(data.ssap())); + default: + break; + } + break; + case llc_ctl: + switch(attrib) + { + case FieldName: + return QString("DSAP"); + case FieldValue: + return data.ctl(); + case FieldTextValue: + return QString("%1").arg(data.ctl(), BASE_HEX); + case FieldFrameValue: + return QByteArray(1, (char)(data.ctl())); + default: + break; + } + break; + + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool LlcProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* LlcProtocol::configWidget() +{ + return configForm; +} + +void LlcProtocol::loadConfigWidget() +{ + configForm->leDsap->setText(QString("%1").arg(data.dsap(), 2, BASE_HEX, QChar('0'))); + configForm->leSsap->setText(QString("%1").arg(data.ssap(), 2, BASE_HEX, QChar('0'))); + configForm->leControl->setText(QString("%1").arg(data.ctl(), 2, BASE_HEX, QChar('0'))); +} + +void LlcProtocol::storeConfigWidget() +{ + bool isOk; + + data.set_dsap(configForm->leDsap->text().toULong(&isOk, BASE_HEX)); + data.set_ssap(configForm->leSsap->text().toULong(&isOk, BASE_HEX)); + data.set_ctl(configForm->leControl->text().toULong(&isOk, BASE_HEX)); +} + diff --git a/common/llc.h b/common/llc.h new file mode 100644 index 0000000..18e1181 --- /dev/null +++ b/common/llc.h @@ -0,0 +1,55 @@ +#ifndef _LLC_H +#define _LLC_H + +#include +#include + +#include "abstractprotocol.h" + +#include "llc.pb.h" +#include "ui_llc.h" + +class LlcConfigForm : public QWidget, public Ui::llc +{ + Q_OBJECT +public: + LlcConfigForm(QWidget *parent = 0); +}; + +class LlcProtocol : public AbstractProtocol +{ +private: + OstProto::Llc data; + static LlcConfigForm *configForm; + enum llcfield + { + llc_dsap = 0, + llc_ssap, + llc_ctl, + + llc_fieldCount + }; + +public: + LlcProtocol(Stream *parent = 0); + virtual ~LlcProtocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/llc.proto b/common/llc.proto new file mode 100644 index 0000000..c57cdbe --- /dev/null +++ b/common/llc.proto @@ -0,0 +1,13 @@ +import "protocol.proto"; + +package OstProto; + +message Llc { + optional uint32 dsap = 1; + optional uint32 ssap = 2; + optional uint32 ctl = 3; +} + +extend Stream { + optional Llc llc = 123; +} diff --git a/common/llc.ui b/common/llc.ui new file mode 100644 index 0000000..4518b3d --- /dev/null +++ b/common/llc.ui @@ -0,0 +1,108 @@ + + llc + + + + 0 + 0 + 304 + 72 + + + + + 0 + 0 + + + + Form + + + + + + LLC + + + + + + DSAP + + + leDsap + + + + + + + true + + + HH; + + + + + + + SSAP + + + leSsap + + + + + + + true + + + HH; + + + + + + + Control + + + leControl + + + + + + + true + + + HH; + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + diff --git a/common/mac.cpp b/common/mac.cpp new file mode 100644 index 0000000..59b2607 --- /dev/null +++ b/common/mac.cpp @@ -0,0 +1,207 @@ +#include +#include + +#include "mac.h" + +MacConfigForm *MacProtocol::configForm = NULL; + +MacConfigForm::MacConfigForm(QWidget *parent) + : QWidget(parent) +{ + QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); + + setupUi(this); + leDstMac->setValidator(new QRegExpValidator(reMac, this)); + leSrcMac->setValidator(new QRegExpValidator(reMac, this)); + leDstMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); + leSrcMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); +} + +void MacConfigForm::on_cmbDstMacMode_currentIndexChanged(int index) +{ + if (index == OstProto::Mac::e_mm_fixed) + { + leDstMacCount->setEnabled(false); + leDstMacStep->setEnabled(false); + } + else + { + leDstMacCount->setEnabled(true); + leDstMacStep->setEnabled(true); + } +} + +void MacConfigForm::on_cmbSrcMacMode_currentIndexChanged(int index) +{ + if (index == OstProto::Mac::e_mm_fixed) + { + leSrcMacCount->setEnabled(false); + leSrcMacStep->setEnabled(false); + } + else + { + leSrcMacCount->setEnabled(true); + leSrcMacStep->setEnabled(true); + } +} + + +MacProtocol::MacProtocol(Stream *parent) + : AbstractProtocol(parent) +{ + if (configForm == NULL) + configForm = new MacConfigForm; +} + +MacProtocol::~MacProtocol() +{ +} + +void MacProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::mac)->CopyFrom(data); +} + +void MacProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::mac)) + data.MergeFrom(stream.GetExtension(OstProto::mac)); +} + +QString MacProtocol::name() const +{ + return QString("Media Access Protocol"); +} + +QString MacProtocol::shortName() const +{ + return QString("MAC"); +} + +int MacProtocol::fieldCount() const +{ + return mac_fieldCount; +} + +QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case mac_dstAddr: + switch(attrib) + { + case FieldName: + return QString("Desination"); + case FieldValue: + return data.dst_mac(); + case FieldTextValue: + return QString("%1").arg(data.dst_mac(), 12, BASE_HEX, + QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(8); + qToBigEndian((quint64) data.dst_mac(), (uchar*) fv.data()); + fv.remove(0, 2); + return fv; + } + default: + break; + } + break; + + case mac_srcAddr: + switch(attrib) + { + case FieldName: + return QString("Source"); + case FieldValue: + return data.src_mac(); + case FieldTextValue: + return QString("%1").arg(data.src_mac(), 12, BASE_HEX, + QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(8); + qToBigEndian((quint64) data.src_mac(), (uchar*) fv.data()); + fv.remove(0, 2); + return fv; + } + default: + break; + } + break; + + // Meta fields + case mac_dstMacMode: + case mac_dstMacCount: + case mac_dstMacStep: + case mac_srcMacMode: + case mac_srcMacCount: + case mac_srcMacStep: + switch(attrib) + { + case FieldIsMeta: + return true; + default: + break; + } + break; + + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool MacProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* MacProtocol::configWidget() +{ + return configForm; +} + +void MacProtocol::loadConfigWidget() +{ +#define uintToHexStr(num, str, size) QString().setNum(num, 16) + configForm->leDstMac->setText(uintToHexStr(data.dst_mac(), str, 6)); + configForm->cmbDstMacMode->setCurrentIndex(data.dst_mac_mode()); + configForm->leDstMacCount->setText(QString().setNum(data.dst_mac_count())); + configForm->leDstMacStep->setText(QString().setNum(data.dst_mac_step())); + + configForm->leSrcMac->setText(uintToHexStr(data.src_mac(), QString(), 6)); + configForm->cmbSrcMacMode->setCurrentIndex(data.src_mac_mode()); + configForm->leSrcMacCount->setText(QString().setNum(data.src_mac_count())); + configForm->leSrcMacStep->setText(QString().setNum(data.src_mac_step())); +} + +void MacProtocol::storeConfigWidget() +{ + bool isOk; + + data.set_dst_mac(configForm->leDstMac->text().remove(QChar(' ')). + toULongLong(&isOk, 16)); + data.set_dst_mac_mode((OstProto::Mac::MacAddrMode) configForm-> + cmbDstMacMode->currentIndex()); + data.set_dst_mac_count(configForm->leDstMacCount->text().toULong(&isOk)); + data.set_dst_mac_step(configForm->leDstMacStep->text().toULong(&isOk)); + + data.set_src_mac(configForm->leSrcMac->text().remove(QChar(' ')). + toULongLong(&isOk, 16)); + data.set_src_mac_mode((OstProto::Mac::MacAddrMode) configForm-> + cmbSrcMacMode->currentIndex()); + data.set_src_mac_count(configForm->leSrcMacCount->text().toULong(&isOk)); + data.set_src_mac_step(configForm->leSrcMacStep->text().toULong(&isOk)); +} + diff --git a/common/mac.h b/common/mac.h new file mode 100644 index 0000000..2842475 --- /dev/null +++ b/common/mac.h @@ -0,0 +1,63 @@ +#ifndef _MAC_H +#define _MAC_H + +#include "abstractprotocol.h" + +#include "mac.pb.h" +#include "ui_mac.h" + +#define MAX_MAC_ITER_COUNT 256 + +class MacConfigForm : public QWidget, public Ui::mac +{ + Q_OBJECT +public: + MacConfigForm(QWidget *parent = 0); +private slots: + void on_cmbDstMacMode_currentIndexChanged(int index); + void on_cmbSrcMacMode_currentIndexChanged(int index); +}; + +class MacProtocol : public AbstractProtocol +{ +private: + OstProto::Mac data; + static MacConfigForm *configForm; + enum macfield + { + mac_dstAddr = 0, + mac_srcAddr, + + mac_dstMacMode, + mac_dstMacCount, + mac_dstMacStep, + mac_srcMacMode, + mac_srcMacCount, + mac_srcMacStep, + + mac_fieldCount + }; + +public: + MacProtocol(Stream *parent = 0); + virtual ~MacProtocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/mac.proto b/common/mac.proto new file mode 100644 index 0000000..c4c5253 --- /dev/null +++ b/common/mac.proto @@ -0,0 +1,29 @@ +import "protocol.proto"; + +package OstProto; + +// Ethernet +message Mac { + + enum MacAddrMode { + e_mm_fixed = 0; + e_mm_inc = 1; + e_mm_dec = 2; + } + + // Dst Mac + optional uint64 dst_mac = 1; + optional MacAddrMode dst_mac_mode = 2 [default = e_mm_fixed]; + optional uint32 dst_mac_count = 3 [default = 16]; + optional uint32 dst_mac_step = 4 [default = 1]; + + // Src Mac + optional uint32 src_mac = 5; + optional MacAddrMode src_mac_mode = 6 [default = e_mm_fixed]; + optional uint32 src_mac_count = 7 [default = 16]; + optional uint32 src_mac_step = 8 [default = 1]; +} + +extend Stream { + optional Mac mac = 51; +} diff --git a/common/mac.ui b/common/mac.ui new file mode 100644 index 0000000..9095f29 --- /dev/null +++ b/common/mac.ui @@ -0,0 +1,190 @@ + + mac + + + + 0 + 0 + 423 + 144 + + + + Form + + + + + + MAC + + + + + + Mode + + + + + + + Step + + + + + + + Destination + + + + + + + + 120 + 0 + + + + HH HH HH HH HH HH; + + + + + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + + + + false + + + 1 + + + 1 + + + + + + + false + + + 1 + + + 1 + + + + + + + Source + + + + + + + HH HH HH HH HH HH; + + + + + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + + + + false + + + 1 + + + + + + + false + + + 1 + + + 1 + + + + + + + Count + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + diff --git a/common/ostproto.pro b/common/ostproto.pro new file mode 100644 index 0000000..3bd8e9c --- /dev/null +++ b/common/ostproto.pro @@ -0,0 +1,63 @@ +TEMPLATE = lib +CONFIG += qt staticlib +QT += network +LIBS += \ + -lprotobuf +FORMS += \ + mac.ui \ + payload.ui \ + eth2.ui \ + dot3.ui \ + llc.ui \ + snap.ui \ + ip4.ui \ + tcp.ui \ + udp.ui +PROTOS += \ + protocol.proto \ + mac.proto \ + payload.proto \ + eth2.proto \ + dot3.proto \ + llc.proto \ + snap.proto \ + ip4.proto \ + tcp.proto \ + udp.proto +HEADERS += \ + abstractprotocol.h \ + mac.h \ + payload.h \ + eth2.h \ + dot3.h \ + llc.h \ + snap.h \ + ip4.h \ + tcp.h \ + udp.h +SOURCES += \ + abstractprotocol.cpp \ + mac.cpp \ + payload.cpp \ + eth2.cpp \ + dot3.cpp \ + llc.cpp \ + snap.cpp \ + ip4.cpp \ + tcp.cpp \ + udp.cpp + +protobuf_decl.name = protobuf header +protobuf_decl.input = PROTOS +protobuf_decl.output = ${QMAKE_FILE_BASE}.pb.h +protobuf_decl.commands = protoc --cpp_out="." ${QMAKE_FILE_NAME} +protobuf_decl.variable_out = GENERATED_FILES +QMAKE_EXTRA_COMPILERS += protobuf_decl + +protobuf_impl.name = protobuf implementation +protobuf_impl.input = PROTOS +protobuf_impl.output = ${QMAKE_FILE_BASE}.pb.cc +protobuf_impl.depends = ${QMAKE_FILE_BASE}.pb.h +protobuf_impl.commands = $$escape_expand(\n) +protobuf_impl.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += protobuf_impl diff --git a/common/payload.cpp b/common/payload.cpp new file mode 100644 index 0000000..8feecf9 --- /dev/null +++ b/common/payload.cpp @@ -0,0 +1,176 @@ +#include +#include + +#include "../client/stream.h" +#include "payload.h" + +PayloadConfigForm *PayloadProtocol::configForm = NULL; + +PayloadConfigForm::PayloadConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +void PayloadConfigForm::on_cmbPatternMode_currentIndexChanged(int index) +{ + switch(index) + { + case OstProto::Payload::e_dp_fixed_word: + lePattern->setEnabled(true); + break; + case OstProto::Payload::e_dp_inc_byte: + case OstProto::Payload::e_dp_dec_byte: + case OstProto::Payload::e_dp_random: + lePattern->setDisabled(true); + break; + default: + qWarning("Unhandled/Unknown PatternMode = %d",index); + } +} + +PayloadProtocol::PayloadProtocol(Stream *parent) + : AbstractProtocol(parent) +{ + if (configForm == NULL) + configForm = new PayloadConfigForm; +} + +PayloadProtocol::~PayloadProtocol() +{ +} + +void PayloadProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::payload)->CopyFrom(data); +} + +void PayloadProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::payload)) + data.MergeFrom(stream.GetExtension(OstProto::payload)); +} + +QString PayloadProtocol::name() const +{ + return QString("Payload Data"); +} + +QString PayloadProtocol::shortName() const +{ + return QString("DATA"); +} + +int PayloadProtocol::fieldCount() const +{ + return payload_fieldCount; +} + +QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case payload_dataPattern: + switch(attrib) + { + case FieldName: + return QString("Data"); + case FieldValue: + return data.pattern(); + case FieldTextValue: + return QString(fieldData(index, FieldFrameValue, + streamIndex).toByteArray().toHex()); + case FieldFrameValue: + { + QByteArray fv; + int dataLen; + + // FIXME: cannot use stream since it is only on client not + // on server + //dataLen = stream->frameLen() - stream->protocolHeaderSize(); + dataLen = 64; + fv.resize(dataLen+4); + switch(data.pattern_mode()) + { + case OstProto::Payload::e_dp_fixed_word: + for (int i = 0; i < (dataLen/4)+1; i++) + qToBigEndian((quint32) data.pattern(), + (uchar*)(fv.data()+(i*4)) ); + break; + case OstProto::Payload::e_dp_inc_byte: + for (int i = 0; i < dataLen; i++) + fv[i] = i % (0xFF + 1); + break; + case OstProto::Payload::e_dp_dec_byte: + for (int i = 0; i < dataLen; i++) + fv[i] = 0xFF - (i % (0xFF + 1)); + break; + case OstProto::Payload::e_dp_random: + for (int i = 0; i < dataLen; i++) + fv[i] = qrand() % (0xFF + 1); + break; + default: + qWarning("Unhandled data pattern %d", + data.pattern_mode()); + } + fv.resize(dataLen); + return fv; + } + default: + break; + } + break; + + // Meta fields + + case payload_dataPatternMode: + switch(attrib) + { + case FieldIsMeta: + return true; + default: + break; + } + break; + + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool PayloadProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* PayloadProtocol::configWidget() +{ + return configForm; + //return new PayloadConfigForm; +} + +void PayloadProtocol::loadConfigWidget() +{ +#define uintToHexStr(num, str, size) QString().setNum(num, 16) + + configForm->cmbPatternMode->setCurrentIndex(data.pattern_mode()); + configForm->lePattern->setText(uintToHexStr(data.pattern(), QString(), 4)); +} + +void PayloadProtocol::storeConfigWidget() +{ + bool isOk; + + data.set_pattern_mode((OstProto::Payload::DataPatternMode) + configForm->cmbPatternMode->currentIndex()); + data.set_pattern(configForm->lePattern->text().remove(QChar(' ')).toULong(&isOk, 16)); +} + diff --git a/common/payload.h b/common/payload.h new file mode 100644 index 0000000..aa66f5d --- /dev/null +++ b/common/payload.h @@ -0,0 +1,55 @@ +#ifndef _PAYLOAD_H +#define _PAYLOAD_H + +#include "abstractprotocol.h" + +#include "payload.pb.h" +#include "ui_payload.h" + +class PayloadConfigForm : public QWidget, public Ui::payload +{ + Q_OBJECT +public: + PayloadConfigForm(QWidget *parent = 0); +private slots: + void on_cmbPatternMode_currentIndexChanged(int index); +}; + +class PayloadProtocol : public AbstractProtocol +{ +private: + OstProto::Payload data; + static PayloadConfigForm *configForm; + enum payloadfield + { + payload_dataPattern, + + // Meta fields + payload_dataPatternMode, + + payload_fieldCount + }; + +public: + PayloadProtocol(Stream *parent = 0); + virtual ~PayloadProtocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/payload.proto b/common/payload.proto new file mode 100644 index 0000000..e97f33c --- /dev/null +++ b/common/payload.proto @@ -0,0 +1,22 @@ +import "protocol.proto"; + +package OstProto; + +message Payload { + enum DataPatternMode { + e_dp_fixed_word = 0; + e_dp_inc_byte = 1; + e_dp_dec_byte = 2; + e_dp_random = 3; + } + + // Data Pattern + optional DataPatternMode pattern_mode = 1; + optional uint32 pattern = 2; + + //optional uint32 data_start_ofs = 13; +} + +extend Stream { + optional Payload payload = 52; +} diff --git a/common/payload.ui b/common/payload.ui new file mode 100644 index 0000000..9de7ce1 --- /dev/null +++ b/common/payload.ui @@ -0,0 +1,69 @@ + + payload + + + + 0 + 0 + 142 + 98 + + + + Form + + + + + + Data Pattern + + + + + + + Fixed Word + + + + + Increment Byte + + + + + Decrement Byte + + + + + Random + + + + + + + + HH HH HH HH; + + + + + + 11 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + diff --git a/common/protocol.h b/common/protocol.h deleted file mode 100644 index 01f35f6..0000000 --- a/common/protocol.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef _PROTOCOL_H -#define _PROTOCOL_H - -#define UINT8 unsigned char -#define UINT16 unsigned short -#define UINT32 unsigned int - -#define BYTESWAP4(x) \ - (((x & 0xFF000000) >> 24) | \ - ((x & 0x00FF0000) >> 8) | \ - ((x & 0x0000FF00) << 8) | \ - ((x & 0x000000FF) << 24)) - -#define BYTESWAP2(x) \ - (((x & 0xFF00) >> 8) | \ - ((x & 0x00FF) << 8)) - -// TODO: portability -#define HTONL(x) BYTESWAP4(x) -#define NTOHL(x) BYTESWAP4(x) -#define HTONS(x) BYTESWAP2(x) -#define NTOHS(x) BYTESWAP2(x) - - -typedef struct { - UINT8 ver; - UINT8 resv1; - UINT16 resv2; - UINT16 msgType; - UINT16 msgLen; -} tCommHdr; - -typedef enum { - e_MT_GetCapability=1, // C-->S - e_MT_CapabilityInfo, // C<--S - - e_MT_ChangePortConfig, // C-->S - e_MT_GetPortConfig, // C-->S - e_MT_PortInfo, // C<--S - - e_MT_StartTx, // C-->S - e_MT_StopTx, // C-->S - e_MT_StartCapture, // C-->S - e_MT_StopCapture, // C-->S - e_MT_GetCaptureBuffer, // C-->S - e_MT_CaptureBufferInfo, // C-->S - - e_MT_GetStats, // C-->S - e_MT_StatsInfo, // C<--S - e_MT_ClearStats, // C-->S - -} eMsgType; - -typedef enum { - e_TT_PortCapability=0x0000, - - e_TT_StreamOper = 0x0100, - e_TT_StreamName, - e_TT_StreamStatus, - e_TT_StreamFrameLength, - e_TT_StreamDataPattern, - e_TT_StreamHeaderData, -} eTlvType; - -typedef struct { - UINT16 tlvType; - UINT16 tlvLen; -} tTlv; - -typedef struct { - UINT16 tlvType; - UINT16 tlvLen; - UINT32 portId; - UINT32 portSpeed; -#define TLV_MAX_PORT_NAME 64 -#define TLV_MAX_PORT_DESC 64 - char portName[TLV_MAX_PORT_NAME]; - char portDesc[TLV_MAX_PORT_DESC]; -} tTlvPortCapability; - -typedef struct { - UINT16 tlvType; - UINT16 tlvLen; - UINT32 portId; - UINT32 streamId; -} tTlvStream; - -typedef struct { - UINT16 tlvType; - UINT16 tlvLen; - UINT32 portId; - UINT32 streamId; - UINT16 rsvd; - UINT16 streamOper; -#define TLV_STREAM_OPER_INSERT_HEAD 0x0001 -#define TLV_STREAM_OPER_INSERT_TAIL 0x0002 -#define TLV_STREAM_OPER_INSERT_BEFORE 0x0003 -#define TLV_STREAM_OPER_DELETE 0x0010 - UINT32 StreamId; -} tTlvStreamOper; - -typedef struct { - UINT16 tlvType; - UINT16 tlvLen; - UINT32 portId; - UINT32 streamId; - char streamName[0]; -} tTlvStreamName; - -typedef struct { - UINT16 tlvType; - UINT16 tlvLen; - UINT32 portId; - UINT32 streamId; - UINT32 streamStatus; -#define TLV_STREAM_STATUS_DISABLED 0 -#define TLV_STREAM_STATUS_ENABLED 1 -} tTlvStreamStatus; - -typedef struct { - UINT16 tlvType; - UINT16 tlvLen; - UINT32 portId; - UINT32 streamId; - UINT16 frameLenMode; -#define TLV_STREAM_FRAME_LEN_MODE_FIXED 0x0000 -#define TLV_STREAM_FRAME_LEN_MODE_RANDOM 0x0001 -#define TLV_STREAM_FRAME_LEN_MODE_INCREMENT 0x0002 -#define TLV_STREAM_FRAME_LEN_MODE_DECREMENT 0x0003 - UINT16 frameLen; - UINT16 frameLenMin; - UINT16 frameLenMax; -} tTlvStreamFrameLength; - -typedef struct { - UINT16 tlvType; - UINT16 tlvLen; - UINT32 portId; - UINT32 streamId; - UINT16 dataPatternMode; -#define TLV_STREAM_DATA_PATTERN_MODE_FIXED 0x0000 -#define TLV_STREAM_DATA_PATTERN_MODE_RANDOM 0x0001 -#define TLV_STREAM_DATA_PATTERN_MODE_INCREMENT 0x0002 -#define TLV_STREAM_DATA_PATTERN_MODE_DECREMENT 0x0003 - UINT16 rsvd; - UINT32 dataPattern; -} tTlvStreamDataPattern; - -typedef struct { - UINT16 tlvType; - UINT16 tlvLen; - UINT32 portId; - UINT32 streamId; - UINT16 rsvd; - UINT16 headerLen; - UINT8 header[0]; -} tTlvStreamHeaderData; - -typedef union { - tTlvStream tlv; - tTlvStreamOper oper; - tTlvStreamName name; - tTlvStreamStatus status; - tTlvStreamFrameLength frameLen; - tTlvStreamDataPattern dataPattern; - tTlvStreamHeaderData headerData; -} uTlvStream; - -#endif diff --git a/common/protocol.proto b/common/protocol.proto index 7038517..a809795 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -4,177 +4,11 @@ package OstProto; -// Ethernet -message Mac { - - enum MacAddrMode { - e_mm_fixed = 0; - e_mm_inc = 1; - e_mm_dec = 2; - } - - // Dst Mac - optional uint64 dst_mac = 1; - optional MacAddrMode dst_mac_mode = 2 [default = e_mm_fixed]; - optional uint32 dst_mac_count = 3 [default = 16]; - optional uint32 dst_mac_step = 4 [default = 1]; - - // Src Mac - optional uint32 src_mac = 5; - optional MacAddrMode src_mac_mode = 6 [default = e_mm_fixed]; - optional uint32 src_mac_count = 7 [default = 16]; - optional uint32 src_mac_step = 8 [default = 1]; -} - -message Llc { - optional uint32 dsap = 1; - optional uint32 ssap = 2; - optional uint32 ctl = 3; -} - -message Snap { - optional uint32 oui = 1; - //optional uint32 type = 2; -} - -message Eth2 { - optional uint32 type = 1; -} - -message Vlan { - // VLAN presence/absence - optional bool is_cvlan_tagged = 9; - optional bool is_ctpid_override = 10; - optional bool is_svlan_tagged = 11; - optional bool is_stpid_override = 12; - - // VLAN values - optional uint32 ctpid = 13; - optional uint32 cvlan_tag = 14; // includes prio, cfi and cvlanid - optional uint32 stpid = 15; - optional uint32 svlan_tag = 16; // includes pcp, de and svlanid -} - -// IP -message Ip { - - enum IpAddrMode { - e_im_fixed = 0; - e_im_inc_host = 1; - e_im_dec_host = 2; - e_im_random_host = 3; - } - - optional bool is_override_ver = 1; - optional bool is_override_hdrlen = 2; - optional bool is_override_totlen = 3; - optional bool is_override_cksum = 4; - - optional uint32 ver_hdrlen = 5 [default = 0x45]; - optional uint32 tos = 6; - optional uint32 tot_len = 7; - optional uint32 id = 8 [default = 1234]; - // TODO: rename flags to frag_flags - optional uint32 flags = 9; - optional uint32 frag_ofs = 10; - optional uint32 ttl = 11 [default = 127]; - optional uint32 proto = 12; - optional uint32 cksum = 13; - - // Source IP - optional fixed32 src_ip = 14; - optional IpAddrMode src_ip_mode = 15 [default = e_im_fixed]; - optional uint32 src_ip_count = 16 [default = 16]; - optional fixed32 src_ip_mask = 17 [default = 0xFFFFFFFF]; - - // Destination IP - optional fixed32 dst_ip = 18; - optional IpAddrMode dst_ip_mode = 19 [default = e_im_fixed]; - optional uint32 dst_ip_count = 20 [default = 16]; - optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFFFF]; - - // TODO: Options -} - -message Arp { -// TODO: ARP -} - -message Tcp { - - optional bool is_override_hdrlen = 1; - optional bool is_override_cksum = 2; - - optional uint32 src_port = 3 [default = 8902]; - optional uint32 dst_port = 4 [default = 80]; - - optional uint32 seq_num = 5 [default = 129018]; - optional uint32 ack_num = 6; - - optional uint32 hdrlen_rsvd = 7 [default = 0x50]; - optional uint32 flags = 8; - - optional uint32 window = 9 [default = 1024]; - optional uint32 cksum = 10; - optional uint32 urg_ptr = 11; -} - -// UDP -message Udp { - optional bool is_override_totlen = 1; - optional bool is_override_cksum = 2; - - optional uint32 src_port = 3 [default = 8902]; - optional uint32 dst_port = 4 [default = 80]; - optional uint32 totlen = 5; - optional uint32 cksum = 6; -} - -// TODO: ICMP -message Icmp { -} - -// TODO: IGMP -message Igmp { -} - message StreamId { required uint32 id = 1; } message StreamCore { - - enum FrameType { - e_ft_none = 0; - e_ft_eth_2 = 1; - e_ft_802_3_raw = 2; - e_ft_802_3_llc = 3; - e_ft_snap = 4; - } - - enum L3Proto { - e_l3_none = 0; - e_l3_ip = 1; - e_l3_arp = 2; - //e_l3_other = 3; - } - - enum L4Proto { - e_l4_none = 0; - e_l4_tcp = 1; - e_l4_udp = 2; - e_l4_icmp = 3; - e_l4_igmp = 4; - //e_l4_other = 5; - } - - enum DataPatternMode { - e_dp_fixed_word = 0; - e_dp_inc_byte = 1; - e_dp_dec_byte = 2; - e_dp_random = 3; - } - enum FrameLengthMode { e_fl_fixed = 0; e_fl_inc = 1; @@ -187,11 +21,6 @@ message StreamCore { optional bool is_enabled = 2; optional uint32 ordinal = 3; - // Data Pattern - optional DataPatternMode pattern_mode = 11; - optional uint32 pattern = 12; - optional uint32 data_start_ofs = 13; - // Frame Length (includes CRC) optional FrameLengthMode len_mode = 14 [default = e_fl_fixed]; optional uint32 frame_len = 15 [default = 64]; @@ -199,9 +28,7 @@ message StreamCore { optional uint32 frame_len_max = 17 [default = 1518]; // Currently Selected Protocols - optional FrameType ft = 21 [default = e_ft_none]; - optional L3Proto l3_proto = 22; - optional L4Proto l4_proto = 23; + repeated uint32 frame_proto = 20; } message StreamControl { @@ -240,24 +67,8 @@ message Stream { optional StreamCore core = 2; optional StreamControl control = 3; - // Protocol data - L2 - optional Mac mac = 51; - - optional Llc llc = 52; - optional Snap snap = 53; - optional Eth2 eth2 = 54; - optional Vlan vlan = 55; - - // Protocol data - L3 - optional Ip ip = 61; - optional Arp arp = 62; - - // Protocol data - L4 - optional Tcp tcp = 71; - optional Udp udp = 72; - optional Icmp icmp = 73; - optional Igmp igmp = 74; - + extensions 51 to 100; // Reserved for Ostinato Use + extensions 101 to 200; // Available for use by protocols } message Void { @@ -281,7 +92,6 @@ message StreamIdList { repeated StreamId stream_id = 2; } - message Port { required PortId port_id = 1; optional string name = 2; diff --git a/common/snap.cpp b/common/snap.cpp new file mode 100644 index 0000000..33f841e --- /dev/null +++ b/common/snap.cpp @@ -0,0 +1,112 @@ +#include +#include + +#include "snap.h" + +SnapConfigForm *SnapProtocol::configForm = NULL; + +SnapConfigForm::SnapConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +SnapProtocol::SnapProtocol(Stream *parent) + : AbstractProtocol(parent) +{ + if (configForm == NULL) + configForm = new SnapConfigForm; +} + +SnapProtocol::~SnapProtocol() +{ +} + +void SnapProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::snap)->CopyFrom(data); +} + +void SnapProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::snap)) + data.MergeFrom(stream.GetExtension(OstProto::snap)); +} + +QString SnapProtocol::name() const +{ + return QString("SubNetwork Access Protocol"); +} + +QString SnapProtocol::shortName() const +{ + return QString("SNAP"); +} + +int SnapProtocol::fieldCount() const +{ + return snap_fieldCount; +} + +QVariant SnapProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case snap_oui: + switch(attrib) + { + case FieldName: + return QString("OUI"); + case FieldValue: + return data.oui(); + case FieldTextValue: + return QString("%1").arg(data.oui(), 6, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.oui(), (uchar*) fv.data()); + fv.remove(0, 1); + return fv; + } + default: + break; + } + break; + + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool SnapProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* SnapProtocol::configWidget() +{ + return configForm; +} + +void SnapProtocol::loadConfigWidget() +{ +#define uintToHexStr(num, str, size) QString().setNum(num, 16) + configForm->leOui->setText(uintToHexStr(data.oui(), str, 3)); +} + +void SnapProtocol::storeConfigWidget() +{ + bool isOk; + + data.set_oui(configForm->leOui->text().remove(QChar(' ')).toULong(&isOk, 16)); +} + diff --git a/common/snap.h b/common/snap.h new file mode 100644 index 0000000..9913b0f --- /dev/null +++ b/common/snap.h @@ -0,0 +1,50 @@ +#ifndef _SNAP_H +#define _SNAP_H + +#include "abstractprotocol.h" + +#include "snap.pb.h" +#include "ui_snap.h" + +class SnapConfigForm : public QWidget, public Ui::snap +{ + Q_OBJECT +public: + SnapConfigForm(QWidget *parent = 0); +}; + +class SnapProtocol : public AbstractProtocol +{ +private: + OstProto::Snap data; + static SnapConfigForm *configForm; + enum snapfield + { + snap_oui = 0, + + snap_fieldCount + }; + +public: + SnapProtocol(Stream *parent = 0); + virtual ~SnapProtocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/snap.proto b/common/snap.proto new file mode 100644 index 0000000..b6c310c --- /dev/null +++ b/common/snap.proto @@ -0,0 +1,12 @@ +import "protocol.proto"; + +package OstProto; + +message Snap { + optional uint32 oui = 1; + //optional uint32 type = 2; +} + +extend Stream { + optional Snap snap = 124; +} diff --git a/common/snap.ui b/common/snap.ui new file mode 100644 index 0000000..1f2b789 --- /dev/null +++ b/common/snap.ui @@ -0,0 +1,89 @@ + + snap + + + + 0 + 0 + 293 + 98 + + + + Form + + + + + + SNAP + + + + + + OUI + + + + + + + true + + + HH HH HH; + + + + + + + Type + + + + + + + true + + + HH HH; + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/common/tcp.cpp b/common/tcp.cpp new file mode 100644 index 0000000..4c81c1c --- /dev/null +++ b/common/tcp.cpp @@ -0,0 +1,360 @@ +#include +#include + +#include "tcp.h" + +TcpConfigForm *TcpProtocol::configForm = NULL; + +TcpConfigForm::TcpConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +TcpProtocol::TcpProtocol(Stream *parent) + : AbstractProtocol(parent) +{ + if (configForm == NULL) + configForm = new TcpConfigForm; +} + +TcpProtocol::~TcpProtocol() +{ +} + +void TcpProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::tcp)->CopyFrom(data); +} + +void TcpProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::tcp)) + data.MergeFrom(stream.GetExtension(OstProto::tcp)); +} + +QString TcpProtocol::name() const +{ + return QString("Transmission Control Protocol"); +} + +QString TcpProtocol::shortName() const +{ + return QString("TCP"); +} + +int TcpProtocol::fieldCount() const +{ + return tcp_fieldCount; +} + +QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case tcp_src_port: + switch(attrib) + { + case FieldName: + return QString("Source Port"); + case FieldValue: + return data.src_port(); + case FieldTextValue: + return QString("%1").arg(data.src_port()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.src_port(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + case tcp_dst_port: + switch(attrib) + { + case FieldName: + return QString("Destination Port"); + case FieldValue: + return data.dst_port(); + case FieldTextValue: + return QString("%1").arg(data.dst_port()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + case tcp_seq_num: + switch(attrib) + { + case FieldName: + return QString("Sequence Number"); + case FieldValue: + return data.seq_num(); + case FieldTextValue: + return QString("%1").arg(data.seq_num()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.seq_num(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + case tcp_ack_num: + switch(attrib) + { + case FieldName: + return QString("Sequence Number"); + case FieldValue: + return data.ack_num(); + case FieldTextValue: + return QString("%1").arg(data.ack_num()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.ack_num(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + case tcp_hdrlen: + switch(attrib) + { + case FieldName: + return QString("Header Length"); + case FieldValue: + return ((data.hdrlen_rsvd() >> 4) & 0x0F); + case FieldTextValue: + return QString("%1").arg((data.hdrlen_rsvd() >> 4) & 0x0F); + case FieldFrameValue: + return QByteArray(1, (char)((data.hdrlen_rsvd() >> 4) & 0x0F)); + case FieldBitSize: + return 4; + default: + break; + } + break; + + case tcp_rsvd: + switch(attrib) + { + case FieldName: + return QString("Reserved"); + case FieldValue: + return (data.hdrlen_rsvd() & 0x0F); + case FieldTextValue: + return QString("%1").arg(data.hdrlen_rsvd() & 0x0F); + case FieldFrameValue: + return QByteArray(1, (char)(data.hdrlen_rsvd() & 0x0F)); + case FieldBitSize: + return 4; + default: + break; + } + break; + + case tcp_flags: + switch(attrib) + { + case FieldName: + return QString("Flags"); + case FieldValue: + return (data.flags()); + case FieldTextValue: + { + QString s; + s.append("URG: "); + s.append(data.flags() & TCP_FLAG_URG ? "1" : "0"); + s.append(" ACK: "); + s.append(data.flags() & TCP_FLAG_ACK ? "1" : "0"); + s.append(" PSH: "); + s.append(data.flags() & TCP_FLAG_PSH ? "1" : "0"); + s.append(" RST: "); + s.append(data.flags() & TCP_FLAG_RST ? "1" : "0"); + s.append(" SYN: "); + s.append(data.flags() & TCP_FLAG_SYN ? "1" : "0"); + s.append(" FIN: "); + s.append(data.flags() & TCP_FLAG_FIN ? "1" : "0"); + return s; + } + case FieldFrameValue: + return QByteArray(1, (char)(data.flags() & 0x3F)); + default: + break; + } + break; + + case tcp_window: + switch(attrib) + { + case FieldName: + return QString("Window Size"); + case FieldValue: + return data.window(); + case FieldTextValue: + return QString("%1").arg(data.window()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.window(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + case tcp_cksum: + switch(attrib) + { + case FieldName: + return QString("Checksum"); + case FieldValue: + return data.cksum(); + case FieldTextValue: + return QString("%1").arg(data.cksum()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.cksum(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + case tcp_urg_ptr: + switch(attrib) + { + case FieldName: + return QString("Urgent Pointer"); + case FieldValue: + return data.urg_ptr(); + case FieldTextValue: + return QString("%1").arg(data.urg_ptr()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.urg_ptr(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + // Meta fields + case tcp_is_override_hdrlen: + case tcp_is_override_cksum: + switch(attrib) + { + case FieldIsMeta: + return true; + default: + break; + } + break; + + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool TcpProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* TcpProtocol::configWidget() +{ + return configForm; +} + +void TcpProtocol::loadConfigWidget() +{ +#define uintToHexStr(num, str, size) QString().setNum(num, 16) + configForm->leTcpSrcPort->setText(QString().setNum(data.src_port())); + configForm->leTcpDstPort->setText(QString().setNum(data.dst_port())); + + configForm->leTcpSeqNum->setText(QString().setNum(data.seq_num())); + configForm->leTcpAckNum->setText(QString().setNum(data.ack_num())); + + configForm->leTcpHdrLen->setText(QString().setNum((data.hdrlen_rsvd() >> 4) & 0x0F)); + configForm->cbTcpHdrLenOverride->setChecked(data.is_override_hdrlen()); + + configForm->leTcpWindow->setText(QString().setNum(data.window())); + + configForm->leTcpCksum->setText(QString().setNum(data.cksum())); + configForm->cbTcpCksumOverride->setChecked(data.is_override_cksum()); + + configForm->leTcpUrgentPointer->setText(QString().setNum(data.urg_ptr())); + + configForm->cbTcpFlagsUrg->setChecked((data.flags() & TCP_FLAG_URG) > 0); + configForm->cbTcpFlagsAck->setChecked((data.flags() & TCP_FLAG_ACK) > 0); + configForm->cbTcpFlagsPsh->setChecked((data.flags() & TCP_FLAG_PSH) > 0); + configForm->cbTcpFlagsRst->setChecked((data.flags() & TCP_FLAG_RST) > 0); + configForm->cbTcpFlagsSyn->setChecked((data.flags() & TCP_FLAG_SYN) > 0); + configForm->cbTcpFlagsFin->setChecked((data.flags() & TCP_FLAG_FIN) > 0); +} + +void TcpProtocol::storeConfigWidget() +{ + bool isOk; + int ff = 0; + + data.set_src_port(configForm->leTcpSrcPort->text().toULong(&isOk)); + data.set_dst_port(configForm->leTcpDstPort->text().toULong(&isOk)); + + data.set_seq_num(configForm->leTcpSeqNum->text().toULong(&isOk)); + data.set_ack_num(configForm->leTcpAckNum->text().toULong(&isOk)); + + data.set_hdrlen_rsvd((configForm->leTcpHdrLen->text().toULong(&isOk) << 4) & 0xF0); + data.set_is_override_hdrlen(configForm->cbTcpHdrLenOverride->isChecked()); + + data.set_window(configForm->leTcpWindow->text().toULong(&isOk)); + + data.set_cksum(configForm->leTcpCksum->text().remove(QChar(' ')).toULong(&isOk)); + data.set_is_override_cksum(configForm->cbTcpCksumOverride->isChecked()); + + data.set_urg_ptr(configForm->leTcpUrgentPointer->text().toULong(&isOk)); + + if (configForm->cbTcpFlagsUrg->isChecked()) ff |= TCP_FLAG_URG; + if (configForm->cbTcpFlagsAck->isChecked()) ff |= TCP_FLAG_ACK; + if (configForm->cbTcpFlagsPsh->isChecked()) ff |= TCP_FLAG_PSH; + if (configForm->cbTcpFlagsRst->isChecked()) ff |= TCP_FLAG_RST; + if (configForm->cbTcpFlagsSyn->isChecked()) ff |= TCP_FLAG_SYN; + if (configForm->cbTcpFlagsFin->isChecked()) ff |= TCP_FLAG_FIN; + data.set_flags(ff); +} + diff --git a/common/tcp.h b/common/tcp.h new file mode 100644 index 0000000..9fc2367 --- /dev/null +++ b/common/tcp.h @@ -0,0 +1,69 @@ +#ifndef _TCP_H +#define _TCP_H + +#include "abstractprotocol.h" + +#include "tcp.pb.h" +#include "ui_tcp.h" + +#define TCP_FLAG_URG 0x01 +#define TCP_FLAG_ACK 0x02 +#define TCP_FLAG_PSH 0x04 +#define TCP_FLAG_RST 0x08 +#define TCP_FLAG_SYN 0x10 +#define TCP_FLAG_FIN 0x20 + +class TcpConfigForm : public QWidget, public Ui::tcp +{ + Q_OBJECT +public: + TcpConfigForm(QWidget *parent = 0); +}; + +class TcpProtocol : public AbstractProtocol +{ +private: + OstProto::Tcp data; + static TcpConfigForm *configForm; + enum tcpfield + { + tcp_src_port = 0, + tcp_dst_port, + tcp_seq_num, + tcp_ack_num, + tcp_hdrlen, + tcp_rsvd, + tcp_flags, + tcp_window, + tcp_cksum, + tcp_urg_ptr, + + tcp_is_override_hdrlen, + tcp_is_override_cksum, + + tcp_fieldCount + }; + +public: + TcpProtocol(Stream *parent = 0); + virtual ~TcpProtocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/tcp.proto b/common/tcp.proto new file mode 100644 index 0000000..8144bad --- /dev/null +++ b/common/tcp.proto @@ -0,0 +1,27 @@ +import "protocol.proto"; + +package OstProto; +// Tcp +message Tcp { + + optional bool is_override_hdrlen = 1; + optional bool is_override_cksum = 2; + + optional uint32 src_port = 3 [default = 8902]; + optional uint32 dst_port = 4 [default = 80]; + + optional uint32 seq_num = 5 [default = 129018]; + optional uint32 ack_num = 6; + + optional uint32 hdrlen_rsvd = 7 [default = 0x50]; + optional uint32 flags = 8; + + optional uint32 window = 9 [default = 1024]; + optional uint32 cksum = 10; + optional uint32 urg_ptr = 11; +} + +extend Stream { + optional Tcp tcp = 140; +} + diff --git a/common/tcp.ui b/common/tcp.ui new file mode 100644 index 0000000..4a333be --- /dev/null +++ b/common/tcp.ui @@ -0,0 +1,228 @@ + + tcp + + + + 0 + 0 + 447 + 194 + + + + Form + + + + + + Source Port + + + + + + + + + + Qt::Vertical + + + + + + + Override Checksum + + + + + + + false + + + HH HH; + + + + + + + Destination Port + + + + + + + + + + Urgent Pointer + + + + + + + + + + Sequence Number + + + + + + + + + + Flags + + + + + + URG + + + + + + + ACK + + + + + + + PSH + + + + + + + RST + + + + + + + SYN + + + + + + + FIN + + + + + + + + + + Qt::Horizontal + + + + 21 + 20 + + + + + + + + Acknowledgement Number + + + + + + + + + + Override Header Length (x4) + + + + + + + false + + + + + + + Window + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + cbTcpHdrLenOverride + toggled(bool) + leTcpHdrLen + setEnabled(bool) + + + 141 + 123 + + + 187 + 123 + + + + + cbTcpCksumOverride + toggled(bool) + leTcpCksum + setEnabled(bool) + + + 316 + 14 + + + 384 + 17 + + + + + diff --git a/common/udp.cpp b/common/udp.cpp new file mode 100644 index 0000000..c2e1bfe --- /dev/null +++ b/common/udp.cpp @@ -0,0 +1,200 @@ +#include +#include + +#include "udp.h" + +UdpConfigForm *UdpProtocol::configForm = NULL; + +UdpConfigForm::UdpConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +UdpProtocol::UdpProtocol(Stream *parent) + : AbstractProtocol(parent) +{ + if (configForm == NULL) + configForm = new UdpConfigForm; +} + +UdpProtocol::~UdpProtocol() +{ +} + +void UdpProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::udp)->CopyFrom(data); +} + +void UdpProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::udp)) + data.MergeFrom(stream.GetExtension(OstProto::udp)); +} + +QString UdpProtocol::name() const +{ + return QString("User Datagram Protocol"); +} + +QString UdpProtocol::shortName() const +{ + return QString("UDP"); +} + +int UdpProtocol::fieldCount() const +{ + return udp_fieldCount; +} + +QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case udp_srcPort: + switch(attrib) + { + case FieldName: + return QString("Source Port"); + case FieldValue: + return data.src_port(); + case FieldTextValue: + return QString("%1").arg(data.src_port()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.src_port(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + case udp_dstPort: + switch(attrib) + { + case FieldName: + return QString("Destination Port"); + case FieldValue: + return data.dst_port(); + case FieldTextValue: + return QString("%1").arg(data.dst_port()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + case udp_totLen: + switch(attrib) + { + case FieldName: + return QString("Datagram Length"); + case FieldValue: + return data.totlen(); + case FieldTextValue: + return QString("%1").arg(data.totlen()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.totlen(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + case udp_cksum: + switch(attrib) + { + case FieldName: + return QString("Checksum"); + case FieldValue: + return data.cksum(); + case FieldTextValue: + return QString("%1").arg(data.cksum()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.cksum(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + + // Meta fields + case udp_isOverrideTotLen: + case udp_isOverrideCksum: + switch(attrib) + { + case FieldIsMeta: + return true; + default: + break; + } + break; + + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool UdpProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* UdpProtocol::configWidget() +{ + return configForm; +} + +void UdpProtocol::loadConfigWidget() +{ +#define uintToHexStr(num, str, size) QString().setNum(num, 16) + configForm->leUdpSrcPort->setText(QString().setNum(data.src_port())); + configForm->leUdpDstPort->setText(QString().setNum(data.dst_port())); + + configForm->leUdpLength->setText(QString().setNum(data.totlen())); + configForm->cbUdpLengthOverride->setChecked(data.is_override_totlen()); + + configForm->leUdpCksum->setText(QString().setNum(data.cksum())); + configForm->cbUdpCksumOverride->setChecked(data.is_override_cksum()); +} + +void UdpProtocol::storeConfigWidget() +{ + bool isOk; + + data.set_src_port(configForm->leUdpSrcPort->text().toULong(&isOk)); + data.set_dst_port(configForm->leUdpDstPort->text().toULong(&isOk)); + + data.set_totlen(configForm->leUdpLength->text().toULong(&isOk)); + data.set_is_override_totlen(configForm->cbUdpLengthOverride->isChecked()); + + data.set_cksum(configForm->leUdpCksum->text().remove(QChar(' ')).toULong(&isOk)); + data.set_is_override_cksum(configForm->cbUdpCksumOverride->isChecked()); +} + diff --git a/common/udp.h b/common/udp.h new file mode 100644 index 0000000..4fe5147 --- /dev/null +++ b/common/udp.h @@ -0,0 +1,56 @@ +#ifndef _UDP_H +#define _UDP_H + +#include "abstractprotocol.h" + +#include "udp.pb.h" +#include "ui_udp.h" + +class UdpConfigForm : public QWidget, public Ui::udp +{ + Q_OBJECT +public: + UdpConfigForm(QWidget *parent = 0); +}; + +class UdpProtocol : public AbstractProtocol +{ +private: + OstProto::Udp data; + static UdpConfigForm *configForm; + enum udpfield + { + udp_srcPort = 0, + udp_dstPort, + udp_totLen, + udp_cksum, + + udp_isOverrideTotLen, + udp_isOverrideCksum, + + udp_fieldCount + }; + +public: + UdpProtocol(Stream *parent = 0); + virtual ~UdpProtocol(); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/udp.proto b/common/udp.proto new file mode 100644 index 0000000..5f9680d --- /dev/null +++ b/common/udp.proto @@ -0,0 +1,18 @@ +import "protocol.proto"; + +package OstProto; + +// UDP +message Udp { + optional bool is_override_totlen = 1; + optional bool is_override_cksum = 2; + + optional uint32 src_port = 3 [default = 8902]; + optional uint32 dst_port = 4 [default = 80]; + optional uint32 totlen = 5; + optional uint32 cksum = 6; +} + +extend Stream { + optional Udp udp = 141; +} diff --git a/common/udp.ui b/common/udp.ui new file mode 100644 index 0000000..e8e29d3 --- /dev/null +++ b/common/udp.ui @@ -0,0 +1,101 @@ + + udp + + + + 0 + 0 + 217 + 144 + + + + Form + + + + + + + + Source Port + + + + + + + + + + Destination Port + + + + + + + + + + Override Length + + + + + + + false + + + + + + + Override Checksum + + + + + + + false + + + HH HH; + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/common/vlan.proto b/common/vlan.proto new file mode 100644 index 0000000..d5ac773 --- /dev/null +++ b/common/vlan.proto @@ -0,0 +1,17 @@ +import "protocol.proto"; + +package OstProto; +message Vlan { + // VLAN presence/absence + optional bool is_tpid_override = 10; + + // VLAN values + optional uint32 ctpid = 13; + optional uint32 cvlan_tag = 14; // includes prio, cfi and cvlanid + optional uint32 stpid = 15; + optional uint32 svlan_tag = 16; // includes pcp, de and svlanid +} + +extend Stream { + optional Vlan vlan = 126; +} diff --git a/common/vlan.ui b/common/vlan.ui new file mode 100644 index 0000000..0ae3be6 --- /dev/null +++ b/common/vlan.ui @@ -0,0 +1,168 @@ + + Form + + + + 0 + 0 + 271 + 90 + + + + Form + + + + + + + + Priority + + + + + + + CFI + + + + + + + VLAN + + + + + + + true + + + Override TPID + + + + + + + true + + + + 0 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + + + + true + + + + 0 + + + + + 1 + + + + + + + + true + + + 0 + + + + + + + true + + + HH HH; + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/rpc/pbrpc.pro b/rpc/pbrpc.pro index 79c0e08..3465da3 100644 --- a/rpc/pbrpc.pro +++ b/rpc/pbrpc.pro @@ -1,13 +1,8 @@ TEMPLATE = lib -CONFIG += qt +CONFIG += qt staticlib QT += network DEFINES += HAVE_REMOTE INCLUDEPATH += "c:\msys\1.0\local\include" LIBS += -L"C:\msys\1.0\local\lib" -lprotobuf HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h SOURCES += rpcserver.cpp pbrpcchannel.cpp -client.path = ..\client\debug -client.files = debug\libpbrpc.a debug\pbrpc.dll -server.path = ..\server\debug -server.files = debug\libpbrpc.a debug\pbrpc.dll -INSTALLS += client server diff --git a/server/drone.pro b/server/drone.pro index 15d69b1..c42d9a4 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -3,15 +3,17 @@ CONFIG += qt debug QT += network DEFINES += HAVE_REMOTE WPCAP INCLUDEPATH += "../rpc" +LIBS += -lprotobuf win32:LIBS += -lwpcap -lpacket unix:LIBS += -lpcap +win32:LIBS += -L"../common/debug" -lostproto +unix:LIBS += -L"../common" -lostproto win32:LIBS += -L"../rpc/debug" -lpbrpc unix:LIBS += -L"../rpc" -lpbrpc +POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" HEADERS += drone.h FORMS += drone.ui SOURCES += drone_main.cpp drone.cpp SOURCES += myservice.cpp - SOURCES += pcapextra.cpp -SOURCES += "..\common\protocol.pb.cc" diff --git a/server/myservice.cpp b/server/myservice.cpp index 085f6f5..20bbda0 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -4,6 +4,17 @@ #include #include +#include "../common/mac.h" +#include "../common/payload.h" + +#include "../common/eth2.h" // FIXME: proto DB +#include "../common/dot3.h" // FIXME: proto DB +#include "../common/llc.h" // FIXME: proto DB +#include "../common/snap.h" // FIXME: proto DB +#include "../common/ip4.h" // FIXME: proto DB +#include "../common/tcp.h" // FIXME: proto DB +#include "../common/udp.h" // FIXME: proto DB + #if 0 #include #include @@ -12,6 +23,64 @@ #define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} #define MB (1024*1024) +StreamInfo::StreamInfo() +{ + PbHelper pbh; + + pbh.ForceSetSingularDefault(&mCore); + pbh.ForceSetSingularDefault(&mControl); + + mProtocolList.append(new MacProtocol); + mProtocolList.append(new PayloadProtocol()); + + // FIXME: proto DB + mProtocolList.append(new Eth2Protocol); + mProtocolList.append(new Dot3Protocol); + mProtocolList.append(new LlcProtocol); + mProtocolList.append(new SnapProtocol); + mProtocolList.append(new Ip4Protocol); + mProtocolList.append(new TcpProtocol); + mProtocolList.append(new UdpProtocol); +} + +StreamInfo::~StreamInfo() +{ + for (int i = 0; i < mProtocolList.size(); i++) + delete mProtocolList.at(i); +} + +AbstractProtocol* StreamInfo::protocolById(int id) +{ + // FIXME BAD BAD VERY BAD! + switch(id) { + case 51: + return mProtocolList.at(0); + case 52: + return mProtocolList.at(1); + case 121: + return mProtocolList.at(2); + case 122: + return mProtocolList.at(3); + case 123: + return mProtocolList.at(4); + case 124: + return mProtocolList.at(5); + // case 125 (unused) +#if 0 // todo VLAN + case 126: + return mProtocolList.at(x); +#endif + case 130: + return mProtocolList.at(6); + case 140: + return mProtocolList.at(7); + case 141: + return mProtocolList.at(8); + default: + return NULL; + } +} + quint32 StreamInfo::pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp, quint8 protocol, quint16 len) { @@ -76,33 +145,29 @@ quint16 StreamInfo::ipv4Cksum(uchar *buf, int len, quint32 partialSum) int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) { - int u, pktLen, dataLen, len = 0; - quint32 srcIp, dstIp; // need it later for TCP/UDP cksum calculation - quint32 cumCksum = 0; // cumulative cksum used to combine partial cksums - int tcpOfs, udpOfs; // needed to fill in cksum later - uchar scratch[8]; + int pktLen, len = 0; // Decide a frame length based on length mode - switch(d.core().len_mode()) + switch(mCore.len_mode()) { case OstProto::StreamCore::e_fl_fixed: - pktLen = d.core().frame_len(); + pktLen = mCore.frame_len(); break; case OstProto::StreamCore::e_fl_inc: - pktLen = d.core().frame_len_min() + (n % - (d.core().frame_len_max() - d.core().frame_len_min() + 1)); + pktLen = mCore.frame_len_min() + (n % + (mCore.frame_len_max() - mCore.frame_len_min() + 1)); break; case OstProto::StreamCore::e_fl_dec: - pktLen = d.core().frame_len_max() - (n % - (d.core().frame_len_max() - d.core().frame_len_min() + 1)); + pktLen = mCore.frame_len_max() - (n % + (mCore.frame_len_max() - mCore.frame_len_min() + 1)); break; case OstProto::StreamCore::e_fl_random: - pktLen = d.core().frame_len_min() + (qrand() % - (d.core().frame_len_max() - d.core().frame_len_min() + 1)); + pktLen = mCore.frame_len_min() + (qrand() % + (mCore.frame_len_max() - mCore.frame_len_min() + 1)); break; default: qWarning("Unhandled len mode %d. Using default 64", - d.core().len_mode()); + mCore.len_mode()); pktLen = 64; break; } @@ -113,6 +178,31 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) if ((pktLen < 0) || (pktLen > bufMaxSize)) return 0; + // FIXME: Calculated pktLen is an input to Payload Protocol + + // FIXME: checksums!!! + + for (int i = 0; i < mCore.frame_proto_size(); i++) + { + QByteArray ba; + + ba = protocolById(mCore.frame_proto(i))->protocolFrameValue(n); + if (len + ba.size() < bufMaxSize) + { + memcpy(buf+len, ba.constData(), ba.size()); + } + len += ba.size(); + } + + return pktLen; + +#if 0 // Proto FW + int u, pktLen, dataLen, len = 0; + quint32 srcIp, dstIp; // need it later for TCP/UDP cksum calculation + quint32 cumCksum = 0; // cumulative cksum used to combine partial cksums + int tcpOfs, udpOfs; // needed to fill in cksum later + uchar scratch[8]; + // We always have a Mac Header! switch (d.mac().dst_mac_mode()) { @@ -449,7 +539,9 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) default: qWarning("Unhandled data pattern %d", d.core().pattern_mode()); } +#endif +#if 0 // Proto FW // Calculate TCP/UDP checksum over the data pattern/payload and fill in switch (d.core().l4_proto()) { @@ -473,8 +565,9 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) // No cksum processing required break; } - return pktLen; +#endif + } @@ -597,28 +690,28 @@ void PortInfo::update() for (int i = 0; i < streamList.size(); i++) { //_restart: - if (streamList[i].d.core().is_enabled()) + if (streamList[i]->mCore.is_enabled()) { long numPackets, numBursts; long ibg, ipg; - switch (streamList[i].d.control().unit()) + switch (streamList[i]->mControl.unit()) { case OstProto::StreamControl::e_su_bursts: - numBursts = streamList[i].d.control().num_bursts(); - numPackets = streamList[i].d.control().packets_per_burst(); - ibg = 1000000/streamList[i].d.control().bursts_per_sec(); + numBursts = streamList[i]->mControl.num_bursts(); + numPackets = streamList[i]->mControl.packets_per_burst(); + ibg = 1000000/streamList[i]->mControl.bursts_per_sec(); ipg = 0; break; case OstProto::StreamControl::e_su_packets: numBursts = 1; - numPackets = streamList[i].d.control().num_packets(); + numPackets = streamList[i]->mControl.num_packets(); ibg = 0; - ipg = 1000000/streamList[i].d.control().packets_per_sec(); + ipg = 1000000/streamList[i]->mControl.packets_per_sec(); break; default: qWarning("Unhandled stream control unit %d", - streamList[i].d.control().unit()); + streamList[i]->mControl.unit()); continue; } qDebug("numBursts = %ld, numPackets = %ld\n", @@ -631,7 +724,7 @@ void PortInfo::update() { int len; - len = streamList[i].makePacket(pktBuf, sizeof(pktBuf), + len = streamList[i]->makePacket(pktBuf, sizeof(pktBuf), j * numPackets + k); if (len > 0) { @@ -680,7 +773,7 @@ void PortInfo::update() } } // for (numBursts) - switch(streamList[i].d.control().next()) + switch(streamList[i]->mControl.next()) { case ::OstProto::StreamControl::e_nw_stop: goto _stop_no_more_pkts; @@ -705,7 +798,7 @@ void PortInfo::update() default: qFatal("---------- %s: Unhandled case (%d) -----------", - __FUNCTION__, streamList[i].d.control().next() ); + __FUNCTION__, streamList[i]->mControl.next() ); break; } @@ -1124,7 +1217,7 @@ int MyService::getStreamIndex(unsigned int portIdx, for (i = 0; i < portInfo[portIdx]->streamList.size(); i++) { - if (streamId == portInfo[portIdx]->streamList.at(i).d.stream_id().id()) + if (streamId == portInfo[portIdx]->streamList.at(i)->mStreamId.id()) goto _found; } @@ -1247,12 +1340,10 @@ const ::OstProto::PortId* request, response->mutable_port_id()->set_id(portIdx); for (int j = 0; j < portInfo[portIdx]->streamList.size(); j++) { - OstProto::StreamId *s, *q; - - q = portInfo[portIdx]->streamList[j].d.mutable_stream_id(); + OstProto::StreamId *s; s = response->add_stream_id(); - s->CopyFrom(*q); + s->CopyFrom(portInfo[portIdx]->streamList[j]->mStreamId); } _exit: @@ -1286,7 +1377,19 @@ const ::OstProto::StreamIdList* request, continue; // TODO(LOW): Partial status of RPC s = response->add_stream(); - s->CopyFrom(portInfo[portIdx]->streamList[streamIndex].d); + + s->mutable_stream_id()->CopyFrom( + portInfo[portIdx]->streamList[streamIndex]->mStreamId); + s->mutable_core()->CopyFrom( + portInfo[portIdx]->streamList[streamIndex]->mCore); + s->mutable_control()->CopyFrom( + portInfo[portIdx]->streamList[streamIndex]->mControl); + for (int j=0; j < portInfo[portIdx]->streamList[streamIndex]-> + mProtocolList.size(); j++) + { + portInfo[portIdx]->streamList[streamIndex]-> + mProtocolList[j]->protoDataCopyInto(*s); + } } _exit: @@ -1312,7 +1415,7 @@ const ::OstProto::StreamIdList* request, for (int i = 0; i < request->stream_id_size(); i++) { int streamIndex; - StreamInfo s; + StreamInfo *s = new StreamInfo; // If stream with same id as in request exists already ==> error!! streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); @@ -1322,7 +1425,7 @@ const ::OstProto::StreamIdList* request, // Append a new "default" stream - actual contents of the new stream is // expected in a subsequent "modifyStream" request - set the stream id // now itself however!!! - s.d.mutable_stream_id()->CopyFrom(request->stream_id(i)); + s->mStreamId.CopyFrom(request->stream_id(i)); portInfo[portIdx]->streamList.append(s); // TODO(LOW): fill-in response "Ack"???? @@ -1357,7 +1460,7 @@ const ::OstProto::StreamIdList* request, if (streamIndex < 0) continue; // TODO(LOW): Partial status of RPC - portInfo[portIdx]->streamList.removeAt(streamIndex); + delete portInfo[portIdx]->streamList.takeAt(streamIndex); // TODO(LOW): fill-in response "Ack"???? } @@ -1391,8 +1494,17 @@ const ::OstProto::StreamConfigList* request, if (streamIndex < 0) continue; // TODO(LOW): Partial status of RPC - portInfo[portIdx]->streamList[streamIndex].d.MergeFrom( - request->stream(i)); + portInfo[portIdx]->streamList[streamIndex]->mCore.clear_frame_proto(); + portInfo[portIdx]->streamList[streamIndex]->mCore.MergeFrom( + request->stream(i).core()); + portInfo[portIdx]->streamList[streamIndex]->mControl.MergeFrom( + request->stream(i).control()); + for (int j=0; j < portInfo[portIdx]->streamList[streamIndex]-> + mProtocolList.size(); j++) + { + portInfo[portIdx]->streamList[streamIndex]-> + mProtocolList[j]->protoDataCopyFrom(request->stream(i)); + } // TODO(LOW): fill-in response "Ack"???? } diff --git a/server/myservice.h b/server/myservice.h index bbf019c..6a662fd 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -8,6 +8,7 @@ #endif #include "../common/protocol.pb.h" +#include "../common/abstractprotocol.h" #include "abstracthost.h" #include #include @@ -34,10 +35,18 @@ class StreamInfo friend class MyService; friend class PortInfo; - OstProto::Stream d; - - StreamInfo() { PbHelper pbh; pbh.ForceSetSingularDefault(&d); } + OstProto::StreamId mStreamId; + OstProto::StreamCore mCore; + OstProto::StreamControl mControl; + QList mProtocolList; +public: + StreamInfo(); + ~StreamInfo(); + +private: + AbstractProtocol* protocolById(int id); + quint32 pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp, quint8 protocol, quint16 len); quint32 ipv4CksumPartial(uchar *buf, int len); @@ -45,7 +54,7 @@ class StreamInfo int makePacket(uchar *buf, int bufMaxSize, int n); public: bool operator < (const StreamInfo &s) const - { return(d.core().ordinal() < s.d.core().ordinal()); } + { return(mCore.ordinal() < s.mCore.ordinal()); } }; @@ -146,7 +155,7 @@ class PortInfo struct timeval lastTsTx; //! used for Rate Stats calculations /*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */ - QList streamList; + QList streamList; public: PortInfo(uint id, pcap_if_t *dev); From 2ec7fb30c2b19956871edd2138a8b7124b9bb02e Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 10 May 2009 06:27:17 +0000 Subject: [PATCH 21/98] Protocol Framework basic code in place now. Cleanup pending. - New Classes: o ProtocolManager - singleton with which all protocols register o ProtocolCollection - Aggregates all registered protocols; exports methods to work on all protocols o StreamBase - aggregates ProtocolCollection with Stream Core and Control; the client/server side stream classes now derive from StreamBase leading to major reduction in their code (more cleanup pending) - AbstractProtocol now supports the additional methods o createInstance() o protocolFrameSize() o protocolFrameOffset(), protocolFramePayloadSize() o protocolId(), payloadProtocolId() o protocolFrameCksum(), protocolFramePayloadCksum() 0 constructor takes an extra param - frameProtoList - Specific protocols - eth2, llc, snap, ip4, udp, tcp now return length, protocol id and cksums correctly (tcp/udp cksum pending) - StreamConfigDialog - protocol controls for length, cksum and protocolid are automatically updated (not fully working yet) --- Makefile | 6 + client/port.cpp | 4 +- client/stream.cpp | 162 +---------------- client/stream.h | 76 +------- client/streamconfigdialog.cpp | 328 ++++++---------------------------- client/streamconfigdialog.h | 18 +- client/streamconfigdialog.ui | 200 +++++---------------- common/abstractprotocol.cpp | 148 ++++++++++++++- common/abstractprotocol.h | 36 +++- common/dot3.cpp | 37 +++- common/dot3.h | 7 +- common/eth2.cpp | 34 ++-- common/eth2.h | 7 +- common/eth2.ui | 4 +- common/ip4.cpp | 124 +++++++++++-- common/ip4.h | 9 +- common/ip4.ui | 22 ++- common/llc.cpp | 56 ++++-- common/llc.h | 7 +- common/llc.ui | 12 +- common/mac.cpp | 18 +- common/mac.h | 7 +- common/mac.ui | 4 +- common/ostproto.pro | 6 + common/payload.cpp | 27 +-- common/payload.h | 7 +- common/payload.ui | 2 +- common/protocolcollection.cpp | 106 +++++++++++ common/protocolcollection.h | 30 ++++ common/protocolmanager.cpp | 38 ++++ common/protocolmanager.h | 18 ++ common/snap.cpp | 59 +++++- common/snap.h | 9 +- common/snap.proto | 2 +- common/snap.ui | 8 +- common/streambase.cpp | 69 +++++++ common/streambase.h | 36 ++++ common/tcp.cpp | 27 ++- common/tcp.h | 8 +- common/tcp.ui | 2 +- common/udp.cpp | 56 +++++- common/udp.h | 8 +- common/udp.ui | 37 +++- common/vlan.ui | 2 +- server/myservice.cpp | 181 ++++--------------- server/myservice.h | 16 +- 46 files changed, 1127 insertions(+), 953 deletions(-) create mode 100644 common/protocolcollection.cpp create mode 100644 common/protocolcollection.h create mode 100644 common/protocolmanager.cpp create mode 100644 common/protocolmanager.h create mode 100644 common/streambase.cpp create mode 100644 common/streambase.h diff --git a/Makefile b/Makefile index c285580..574c0a1 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,12 @@ clean: $(MAKE) -C server $@ $(MAKE) -C client $@ +distclean: + $(MAKE) -C rpc $@ + $(MAKE) -C common $@ + $(MAKE) -C server $@ + $(MAKE) -C client $@ + qmake: cd rpc && qmake && cd .. cd common && qmake && cd .. diff --git a/client/port.cpp b/client/port.cpp index 64c7865..291b1b5 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -98,7 +98,7 @@ bool Port::updateStream(uint streamId, OstProto::Stream *stream) _found: streamIndex = i; - mStreams[streamIndex]->update(stream); + mStreams[streamIndex]->protoDataCopyFrom(*stream); reorderStreamsByOrdinals(); return true; @@ -167,7 +167,7 @@ void Port::getModifiedStreamsSinceLastSync( OstProto::Stream *s; s = streamConfigList.add_stream(); - mStreams[i]->getConfig(mPortId, *s); + mStreams[i]->protoDataCopyInto(*s); } qDebug("Done %s", __FUNCTION__); } diff --git a/client/stream.cpp b/client/stream.cpp index 3af3509..b978913 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -3,173 +3,27 @@ #include "stream.h" -#include "../common/mac.h" -#include "../common/payload.h" - -#include "../common/eth2.h" // FIXME: proto DB -#include "../common/dot3.h" // FIXME: proto DB -#include "../common/llc.h" // FIXME: proto DB -#include "../common/snap.h" // FIXME: proto DB -#include "../common/ip4.h" // FIXME: proto DB -#include "../common/tcp.h" // FIXME: proto DB -#include "../common/udp.h" // FIXME: proto DB - - -//----------------------------------------------------- -// Stream Class Methods -//----------------------------------------------------- Stream::Stream() { - mId = 0xFFFFFFFF; - - mCore = new OstProto::StreamCore; - mControl = new OstProto::StreamControl; - -// mCore->set_port_id(0xFFFFFFFF); -// mCore->set_stream_id(mId); - - mProtocolList.append(new MacProtocol); - mProtocolList.append(new PayloadProtocol(this)); - - // FIXME: proto DB - mProtocolList.append(new Eth2Protocol); - mProtocolList.append(new Dot3Protocol); - mProtocolList.append(new LlcProtocol); - mProtocolList.append(new SnapProtocol); - mProtocolList.append(new Ip4Protocol); - mProtocolList.append(new TcpProtocol); - mProtocolList.append(new UdpProtocol); - + //mId = 0xFFFFFFFF; mCore->set_is_enabled(true); - mCore->add_frame_proto(51); // MAC (FIXME: hardcoding) - mCore->add_frame_proto(52); // Payload (FIXME: hardcoding) + + QList protoList; + protoList.append(51); + protoList.append(52); + setFrameProtocol(protoList); } Stream::~Stream() { - for (int i = 0; i < mProtocolList.size(); i++) - delete mProtocolList.at(i); - - delete mControl; - delete mCore; -} - -void Stream::protoDataCopyFrom(Stream& stream) -{ - OstProto::Stream data; - - stream.getConfig(0, data); - update(&data); } void Stream::loadProtocolWidgets() { - for (int i=0; i < mProtocolList.size(); i++) - mProtocolList[i]->loadConfigWidget(); + protocols.loadConfigWidgets(); } void Stream::storeProtocolWidgets() { - for (int i=0; i < mProtocolList.size(); i++) - mProtocolList[i]->storeConfigWidget(); -} - -/*! Copy current client side config into the OstProto::Stream */ -// FIXME - remove portId unused param! -void Stream::getConfig(uint portId, OstProto::Stream &s) -{ - s.mutable_stream_id()->set_id(mId); - - s.mutable_core()->CopyFrom(*mCore); - s.mutable_control()->CopyFrom(*mControl); - - // FIXME - this doesn't take care of multiple headers of same proto - // e.g. IPinIP or double VLAN Tagged - // FIXME: change s from pointer to reference? - for (int i = 0; i < mProtocolList.size(); i++) - { - qDebug("%s: protocol %d", __FUNCTION__, i); - mProtocolList[i]->protoDataCopyInto(s); - } - - qDebug("%s: Done", __FUNCTION__); -} - -bool Stream::update(OstProto::Stream *stream) -{ - mCore->clear_frame_proto(); - mCore->MergeFrom(stream->core()); - mControl->MergeFrom(stream->control()); - - // FIXME - this doesn't take care of multiple headers of same proto - // e.g. IPinIP or double VLAN Tagged - // FIXME: change s from pointer to reference? - for (int i = 0; i < mProtocolList.size(); i++) - { - mProtocolList[i]->protoDataCopyFrom(*stream); - } - - // FIXME(MED): Re-eval why not store complete OstProto::Stream - // instead of components - return true; -} - -QList Stream::frameProtocol() -{ - QList protocolList; - - for (int i = 0; i < mCore->frame_proto_size(); i++) - protocolList.append(mCore->frame_proto(i)); - - return protocolList; -} - -void Stream::setFrameProtocol(QList protocolList) -{ - mCore->clear_frame_proto(); - for (int i = 0; i < protocolList.size(); i++) - mCore->add_frame_proto(protocolList.at(i)); -} - -int Stream::protocolHeaderSize() -{ - int size = 0; - - for (int i = 0; i < mCore->frame_proto_size(); i++) - size += protocolById(mCore->frame_proto(i))-> - protocolFrameValue().size(); - - return size; -} - -AbstractProtocol* Stream::protocolById(int id) -{ - // FIXME BAD BAD VERY BAD! - switch(id) { - case 51: - return mProtocolList.at(0); - case 52: - return mProtocolList.at(1); - case 121: - return mProtocolList.at(2); - case 122: - return mProtocolList.at(3); - case 123: - return mProtocolList.at(4); - case 124: - return mProtocolList.at(5); - // case 125 (unused) -#if 0 // todo VLAN - case 126: - return mProtocolList.at(x); -#endif - case 130: - return mProtocolList.at(6); - case 140: - return mProtocolList.at(7); - case 141: - return mProtocolList.at(8); - default: - return NULL; - } + protocols.storeConfigWidgets(); } diff --git a/client/stream.h b/client/stream.h index c4884d4..1c19b19 100644 --- a/client/stream.h +++ b/client/stream.h @@ -2,48 +2,21 @@ #define _STREAM_H #include - #include #include + #include "../common/protocol.pb.h" -#include "../common/abstractprotocol.h" +#include "../common/streambase.h" -// Convenience Defines FIXME -#define IP_PROTO_ICMP 0x01 -#define IP_PROTO_IGMP 0x02 -#define IP_PROTO_TCP 0x06 -#define IP_PROTO_UDP 0x11 +class Stream : public StreamBase { -class Stream { - - quint32 mId; - OstProto::StreamCore *mCore; - OstProto::StreamControl *mControl; - - QList mProtocolList; + //quint32 mId; public: - - void* core() { return mCore; } // FIXME(HI): Debug ONLY void loadProtocolWidgets(); void storeProtocolWidgets(); public: - enum FrameType { - e_ft_none, - e_ft_eth_2, - e_ft_802_3_raw, - e_ft_802_3_llc, - e_ft_snap - }; - - enum DataPatternMode { - e_dp_fixed_word, - e_dp_inc_byte, - e_dp_dec_byte, - e_dp_random - }; - enum FrameLengthMode { e_fl_fixed, e_fl_inc, @@ -51,20 +24,6 @@ public: e_fl_random }; - enum L3Proto { - e_l3_none, - e_l3_ip, - e_l3_arp, - }; - - enum L4Proto { - e_l4_none, - e_l4_tcp, - e_l4_udp, - e_l4_icmp, - e_l4_igmp, - }; - enum SendUnit { e_su_packets, e_su_bursts @@ -87,19 +46,15 @@ public: Stream(); ~Stream(); - void protoDataCopyFrom(Stream& stream); + // TODO: Below methods move to StreamBase??? bool operator < (const Stream &s) const { return(mCore->ordinal() < s.mCore->ordinal()); } - - void getConfig(uint portId, OstProto::Stream &s); - bool update(OstProto::Stream *stream); - quint32 id() - { return mId;} + { return mStreamId->id();} bool setId(quint32 id) - { mId = id; return true;} + { mStreamId->set_id(id); return true;} #if 0 // FIXME(HI): needed? quint32 portId() @@ -123,12 +78,7 @@ public: bool setName(QString name) { mCore->set_name(name.toStdString()); return true; } -// TODO(HI) : ????? -#if 0 - quint16 dataStartOfs; -#endif - - // Frame Length (includes CRC) + // Frame Length (includes FCS) FrameLengthMode lenMode() { return (FrameLengthMode) mCore->len_mode(); } bool setLenMode(FrameLengthMode lenMode) @@ -192,16 +142,6 @@ public: { return (quint32) mControl->bursts_per_sec(); } bool setBurstRate(quint32 burstsPerSec) { mControl->set_bursts_per_sec(burstsPerSec); return true; } - - //--------------------------------------------------------------- - // Methods for use by Packet Model - //--------------------------------------------------------------- - QList frameProtocol(); - void setFrameProtocol(QList protocolList); - - //! Includes ALL protocol headers excluding payload data - int protocolHeaderSize(); - AbstractProtocol* protocolById(int id); }; #endif diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 0079240..b69ef67 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -7,71 +7,38 @@ int StreamConfigDialog::lastTopLevelTabIndex = 0; int StreamConfigDialog::lastProtoTabIndex = 0; -// TODO(HI): Write HexLineEdit::setNum() and num() and use it in -// Load/Store stream methods - StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent) : QDialog (parent), mPort(port) { + OstProto::Stream s; mCurrentStreamIndex = streamIndex; - mpStream = new Stream; - mpStream->protoDataCopyFrom(*(mPort.streamByIndex(mCurrentStreamIndex))); + mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyInto(s); + mpStream->protoDataCopyFrom(s); setupUi(this); setupUiExtra(); - // setupUi + connect(bgFrameType, SIGNAL(buttonClicked(int)), + this, SLOT(updateSelectedProtocols())); + connect(bgL3Proto, SIGNAL(buttonClicked(int)), + this, SLOT(updateSelectedProtocols())); + connect(bgL4Proto, SIGNAL(buttonClicked(int)), + this, SLOT(updateSelectedProtocols())); // Time to play match the signals and slots! connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); - // Show/Hide FrameType related inputs for FT None - connect(rbFtNone, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), lblSsap, SLOT(setHidden(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), leSsap, SLOT(setHidden(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), lblControl, SLOT(setHidden(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), leControl, SLOT(setHidden(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool))); - // Enable/Disable L3 Protocol Choices for FT None connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool))); connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); - // Show/Hide FrameType related inputs for FT Ethernet2 - connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblSsap, SLOT(setHidden(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), leSsap, SLOT(setHidden(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblControl, SLOT(setHidden(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), leControl, SLOT(setHidden(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool))); - // Enable/Disable L3 Protocol Choices for FT Ethernet2 connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); - // Show/Hide FrameType related inputs for FT 802.3 Raw - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblSsap, SLOT(setHidden(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leSsap, SLOT(setHidden(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblControl, SLOT(setHidden(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leControl, SLOT(setHidden(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool))); - // Force L3 = None if FT = 802.3 Raw connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); @@ -80,18 +47,6 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool))); connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); - // Show/Hide FrameType related inputs for FT 802.3 LLC - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblDsap, SLOT(setVisible(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leDsap, SLOT(setVisible(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblSsap, SLOT(setVisible(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leSsap, SLOT(setVisible(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblControl, SLOT(setVisible(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leControl, SLOT(setVisible(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool))); - // Force L3 = None if FT = 802.3 LLC (to ensure a valid L3 is selected) connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); @@ -100,31 +55,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); - // Show/Hide FrameType related inputs for FT 802.3 LLC SNAP - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblDsap, SLOT(setVisible(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leDsap, SLOT(setVisible(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblSsap, SLOT(setVisible(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leSsap, SLOT(setVisible(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblControl, SLOT(setVisible(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leControl, SLOT(setVisible(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblOui, SLOT(setVisible(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leOui, SLOT(setVisible(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool))); - // Enable/Disable L3 Protocol Choices for FT 802.3 LLC SNAP connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); - // Enable/Disable FrameType related inputs for FT 802.3 LLC SNAP - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblDsap, SLOT(setDisabled(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leDsap, SLOT(setDisabled(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblSsap, SLOT(setDisabled(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leSsap, SLOT(setDisabled(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblControl, SLOT(setDisabled(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leControl, SLOT(setDisabled(bool))); - // Enable/Disable L4 Protocol Choices for L3 Protocol None connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); connect(rbL3None, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool))); @@ -152,18 +87,6 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // Force L4 Protocol = None if L3 Protocol is set to ARP connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool))); - //TODO: remove if not needed -#if 0 - // This set of 'clicks' is a hack to trigger signals at dialog creation - // time so that a coherent 'set' is initialized - // Actual stream values will be initialized by LoadCurrentStream() - rbL3Ipv4->click(); - rbL3None->click(); - rbFtEthernet2->click(); - rbFtNone->click(); -#endif - - //mmpStreamList = streamList; LoadCurrentStream(); mpPacketModel = new PacketModel(QList(), this); tvPacketTree->setModel(mpPacketModel); @@ -173,6 +96,10 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); // TODO(MED): + //! \todo Implement then enable these protocols + rbL3Arp->setHidden(true); + rbL4Icmp->setHidden(true); + rbL4Igmp->setHidden(true); //! \todo Enable navigation of streams pbPrev->setDisabled(true); pbNext->setDisabled(true); @@ -181,6 +108,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool))); //! \todo Support Continuous Mode rbModeContinuous->setDisabled(true); + // Finally, restore the saved last selected tab for the various tab widgets twTopLevel->setCurrentIndex(lastTopLevelTabIndex); if (twProto->isTabEnabled(lastProtoTabIndex)) @@ -199,27 +127,25 @@ void StreamConfigDialog::setupUiExtra() layout = static_cast(twTopLevel->widget(0)->layout()); - layout->addWidget(mpStream->protocolById(52)->configWidget(), 0, 1); - qDebug("setupUi wgt = %p", mpStream->protocolById(52)->configWidget()); + layout->addWidget(mpStream->protocol(52)->configWidget(), 0, 1); + qDebug("setupUi wgt = %p", mpStream->protocol(52)->configWidget()); } // ---- Setup default stuff that cannot be done in designer ---- + bgFrameType = new QButtonGroup(); + foreach(QRadioButton *btn, gbFrameType->findChildren()) + bgFrameType->addButton(btn); - // Since the dialog defaults are FT = None, L3 = None, L4 = None; - // hide associated input fields since it can't be done in Designer - lblDsap->setHidden(true); - leDsap->setHidden(true); - lblSsap->setHidden(true); - leSsap->setHidden(true); - lblControl->setHidden(true); - leControl->setHidden(true); - lblOui->setHidden(true); - leOui->setHidden(true); - lblType->setHidden(true); - leType->setHidden(true); + bgL3Proto = new QButtonGroup(); + foreach(QRadioButton *btn, gbL3Proto->findChildren()) + bgL3Proto->addButton(btn); - twProto->setTabEnabled(2, FALSE); - twProto->setTabEnabled(3, FALSE); + bgL4Proto = new QButtonGroup(); + foreach(QRadioButton *btn, gbL4Proto->findChildren()) + bgL4Proto->addButton(btn); + + //twProto->setTabEnabled(2, FALSE); + //twProto->setTabEnabled(3, FALSE); /* ** Setup Validators @@ -263,18 +189,8 @@ StreamConfigDialog::~StreamConfigDialog() QLayout *layout = twTopLevel->widget(0)->layout(); if (layout) { - qDebug("dstrct wgt = %p", mpStream->protocolById(52)->configWidget()); -#if 0 - int i = layout->indexOf(mpStream->protocolById(52)->configWidget()); - if (i >= 0) - { - layout->takeAt(i); - mpStream->protocolById(52)->configWidget()->setParent(0); - } -#endif - layout->removeWidget(mpStream->protocolById(52)->configWidget()); - mpStream->protocolById(52)->configWidget()->setParent(0); - + layout->removeWidget(mpStream->protocol(52)->configWidget()); + mpStream->protocol(52)->configWidget()->setParent(0); } } @@ -296,6 +212,10 @@ StreamConfigDialog::~StreamConfigDialog() } } + delete bgFrameType; + delete bgL3Proto; + delete bgL4Proto; + delete mpStream; } @@ -340,6 +260,10 @@ void StreamConfigDialog::updateSelectedProtocols() // Payload mSelectedProtocols.append(52); + + mpStream->setFrameProtocol(mSelectedProtocols); + mpStream->storeProtocolWidgets(); + mpStream->loadProtocolWidgets(); } @@ -399,146 +323,6 @@ void StreamConfigDialog::on_pbNext_clicked() #endif } -void StreamConfigDialog::on_rbFtNone_toggled(bool checked) -{ -} - -void StreamConfigDialog::on_rbFtEthernet2_toggled(bool checked) -{ -} - -void StreamConfigDialog::on_rbFt802Dot3Raw_toggled(bool checked) -{ -} - -void StreamConfigDialog::on_rbFt802Dot3Llc_toggled(bool checked) -{ -} - -void StreamConfigDialog::on_rbFtLlcSnap_toggled(bool checked) -{ - if (checked) - { - leDsap->setText("AA"); - leSsap->setText("AA"); - leControl->setText("03"); - } -} - -void StreamConfigDialog::on_rbL3Ipv4_toggled(bool checked) -{ - if (checked) - { - twProto->setTabEnabled(2, TRUE); - twProto->setTabText(2, "L3 (IPv4)"); - leType->setText("08 00"); - - // FIXME: Hardcoding - mpStream->protocolById(121)->setFieldData(0 /* type */, 0x800); - mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param - } - else - { - twProto->setTabEnabled(2, FALSE); - twProto->setTabText(2, "L3"); - } -} - -void StreamConfigDialog::on_rbL3Arp_toggled(bool checked) -{ - if (checked) - { - twProto->setTabEnabled(2, TRUE); - twProto->setTabText(2, "L3 (ARP)"); - leType->setText("08 06"); - - // FIXME: Hardcoding - mpStream->protocolById(121)->setFieldData(0 /* type */, 0x806); - mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param - } - else - { - twProto->setTabEnabled(2, FALSE); - twProto->setTabText(2, "L3"); - } -} - -void StreamConfigDialog::on_rbL4Icmp_toggled(bool checked) -{ - QString str; - - if (checked) - { - twProto->setTabEnabled(3, TRUE); - twProto->setTabText(3, "L4 (ICMP)"); - // FIXME: Hardcoding - mpStream->protocolById(130)->setFieldData(8 /* proto */, IP_PROTO_ICMP); - mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param - } - else - { - twProto->setTabEnabled(3, FALSE); - twProto->setTabText(3, "L4"); - } -} - -void StreamConfigDialog::on_rbL4Igmp_toggled(bool checked) -{ - QString str; - - if (checked) - { - twProto->setTabEnabled(3, TRUE); - twProto->setTabText(3, "L4 (IGMP)"); - // FIXME: Hardcoding - mpStream->protocolById(130)->setFieldData(8 /* proto */, IP_PROTO_IGMP); - mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param - } - else - { - twProto->setTabEnabled(3, FALSE); - twProto->setTabText(3, "L4"); - } -} - -void StreamConfigDialog::on_rbL4Tcp_toggled(bool checked) -{ - QString str; - - if (checked) - { - twProto->setTabEnabled(3, TRUE); - twProto->setTabText(3, "L4 (TCP)"); - // FIXME: Hardcoding - mpStream->protocolById(130)->setFieldData(8 /* proto */, IP_PROTO_TCP); - mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param - } - else - { - twProto->setTabEnabled(3, FALSE); - twProto->setTabText(3, "L4"); - } -} - -void StreamConfigDialog::on_rbL4Udp_toggled(bool checked) -{ - QString str; - - if (checked) - { - twProto->setTabEnabled(3, TRUE); - twProto->setTabText(3, "L4 (UDP)"); - // FIXME: Hardcoding - mpStream->protocolById(130)->setFieldData(8 /* proto */, IP_PROTO_UDP); - mpStream->loadProtocolWidgets(); // FIXME: pass protocol as param - } - else - { - twProto->setTabEnabled(3, FALSE); - twProto->setTabText(3, "L4"); - } -} - void StreamConfigDialog::on_twTopLevel_currentChanged(int index) { QList protoList; @@ -549,8 +333,8 @@ void StreamConfigDialog::on_twTopLevel_currentChanged(int index) updateSelectedProtocols(); foreach(int i, mSelectedProtocols) - if (mpStream->protocolById(i)) - protoList.append(mpStream->protocolById(i)); + if (mpStream->protocol(i)) + protoList.append(mpStream->protocol(i)); mpPacketModel->setSelectedProtocols(protoList); StoreCurrentStream(mpStream); @@ -583,42 +367,44 @@ void StreamConfigDialog::on_twProto_currentChanged(int index) switch(index) { case 1: // L2 - wl.append(mpStream->protocolById(51)->configWidget()); + wl.append(mpStream->protocol("mac")->configWidget()); if (rbFtEthernet2->isChecked()) - wl.append(mpStream->protocolById(121)->configWidget()); + wl.append(mpStream->protocol("eth2")->configWidget()); else if (rbFt802Dot3Raw->isChecked()) - wl.append(mpStream->protocolById(122)->configWidget()); + wl.append(mpStream->protocol("dot3")->configWidget()); else if (rbFt802Dot3Llc->isChecked()) { - wl.append(mpStream->protocolById(122)->configWidget()); - wl.append(mpStream->protocolById(123)->configWidget()); + wl.append(mpStream->protocol("dot3")->configWidget()); + wl.append(mpStream->protocol("llc")->configWidget()); } else if (rbFtLlcSnap->isChecked()) { - wl.append(mpStream->protocolById(122)->configWidget()); - wl.append(mpStream->protocolById(123)->configWidget()); - wl.append(mpStream->protocolById(124)->configWidget()); + wl.append(mpStream->protocol("dot3")->configWidget()); + wl.append(mpStream->protocol("llc")->configWidget()); + wl.append(mpStream->protocol("snap")->configWidget()); } break; case 2: // L3 if (rbL3Ipv4->isChecked()) - wl.append(mpStream->protocolById(130)->configWidget()); + wl.append(mpStream->protocol("ip4")->configWidget()); break; case 3: // L4 if (rbL4Tcp->isChecked()) - wl.append(mpStream->protocolById(140)->configWidget()); + wl.append(mpStream->protocol("tcp")->configWidget()); else if (rbL4Udp->isChecked()) - wl.append(mpStream->protocolById(141)->configWidget()); + wl.append(mpStream->protocol("udp")->configWidget()); break; } - if (wl.size()) + if (wl.size()) + { layout = new QVBoxLayout; - for (int i=0; i < wl.size(); i++) - layout->addWidget(wl.at(i)); + for (int i=0; i < wl.size(); i++) + layout->addWidget(wl.at(i)); - twProto->widget(index)->setLayout(layout); + twProto->widget(index)->setLayout(layout); + } } void StreamConfigDialog::update_NumPacketsAndNumBursts() diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index f6c5a41..75cae99 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -29,6 +29,10 @@ public: private: //QList *mpStreamList; + QButtonGroup *bgFrameType; + QButtonGroup *bgL3Proto; + QButtonGroup *bgL4Proto; + Port& mPort; uint mCurrentStreamIndex; Stream *mpStream; @@ -45,7 +49,6 @@ private: static int lastProtoTabIndex; void setupUiExtra(); - void updateSelectedProtocols(); void LoadCurrentStream(); void StoreCurrentStream(Stream *pStream); @@ -54,18 +57,7 @@ private slots: void on_pbPrev_clicked(); void on_pbNext_clicked(); - void on_rbFtNone_toggled(bool checked); - void on_rbFtEthernet2_toggled(bool checked); - void on_rbFt802Dot3Raw_toggled(bool checked); - void on_rbFt802Dot3Llc_toggled(bool checked); - void on_rbFtLlcSnap_toggled(bool checked); - void on_rbL3Ipv4_toggled(bool checked); - void on_rbL3Arp_toggled(bool checked); - void on_rbL4Icmp_toggled(bool checked); - void on_rbL4Igmp_toggled(bool checked); - void on_rbL4Tcp_toggled(bool checked); - void on_rbL4Udp_toggled(bool checked); - + void updateSelectedProtocols(); void on_twTopLevel_currentChanged(int index); void on_twProto_currentChanged(int index); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index e410c81..9eba69a 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -59,7 +59,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - Frame Length (including CRC) + Frame Length (including FCS) @@ -159,164 +159,60 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + Frame Type - + - - - - - - - None - - - true - - - - - - - Ethernet II - - - false - - - - - - - 802.3 Raw - - - - - - - 802.3 LLC - - - false - - - - - - - LLC SNAP - - - - - - - - - Qt::Vertical - - - - - - - - - DSAP - - - - - - - true - - - HH; - - - - - - - SSAP - - - - - - - true - - - HH; - - - - - - - Control - - - - - - - true - - - HH; - - - - - - - OUI - - - - - - - true - - - HH HH HH; - - - - - - - Type - - - - - - - true - - - HH HH; - - - - - - + + + None + + + true + + + + + + + Ethernet II + + + false + + + + + + + 802.3 Raw + + + + + + + 802.3 LLC + + + false + + + + + + + LLC SNAP + + - + L3 @@ -358,7 +254,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + L4 @@ -416,7 +312,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + Qt::Vertical diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 429c6a3..04d0d67 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -1,3 +1,4 @@ +#include #include "abstractprotocol.h" /*! @@ -18,19 +19,30 @@ - metaFieldCount() - isMetaField() */ -AbstractProtocol::AbstractProtocol(Stream *parent) +AbstractProtocol::AbstractProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : frameProtocols(frameProtoList) { + qDebug("%s: &frameproto = %p/%p (sz:%d)", __FUNCTION__, &frameProtocols, &frameProtoList, frameProtocols.size()); stream = parent; metaCount = -1; + protoSize = -1; } AbstractProtocol::~AbstractProtocol() { } +AbstractProtocol* AbstractProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return NULL; +} /*! - \fn virtual void protoDataCopyInto(OstProto::Stream &stream) = 0; + \fn virtual void protoDataCopyInto(OstProto::OstProto::StreamCore &stream) = 0; Copy the protocol's protobuf into the passed in stream \n In the base class this is a pure virtual function. Subclasses should @@ -38,7 +50,7 @@ AbstractProtocol::~AbstractProtocol() stream.AddExtension()->CopyFrom() */ /* - \fn virtual void protoDataCopyFrom(const OstProto::Stream &stream) = 0; + \fn virtual void protoDataCopyFrom(const OstProto::OstProto::StreamCore &stream) = 0; FIXME */ /*! Returns the full name of the protocol \n @@ -114,6 +126,11 @@ int AbstractProtocol::frameFieldCount() const the field's value e.g. a checksum field may include "(correct)" or "(incorrect)" alongwith the actual checksum value. \n The default implementation returns FIXME + + \note If a subclass uses any of the below functions to derive + FieldFrameValue, the subclass should handle and return a value for + FieldBitSize to prevent endless recrusion - + - protocolFrameCksum() */ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const @@ -151,6 +168,81 @@ bool AbstractProtocol::setFieldData(int index, const QVariant &value, return false; } +quint32 AbstractProtocol::protocolId(ProtocolIdType type) const +{ + return 0; +} + +quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const +{ + quint32 id = 0xFFFFFFFF; + QLinkedListIterator iter(frameProtocols); + + if (iter.findNext(this)) + { + if (iter.hasNext()) + id = iter.next()->protocolId(type); + } + + qDebug("%s: payloadProtocolId = %u", __FUNCTION__, id); + return id; +} + +int AbstractProtocol::protocolFrameSize() const +{ + if (protoSize < 0) + { + int bitsize = 0; + + for (int i = 0; i < fieldCount(); i++) + { + if (!fieldData(i, FieldIsMeta).toBool()) + bitsize += fieldData(i, FieldBitSize).toUInt(); + } + protoSize = (bitsize+7)/8; + } + + qDebug("%s: protoSize = %d", __FUNCTION__, protoSize); + return protoSize; +} + +int AbstractProtocol::protocolFrameOffset() const +{ + int size = 0; + QLinkedListIterator iter(frameProtocols); + + if (iter.findNext(this)) + { + iter.previous(); + while (iter.hasPrevious()) + size += iter.previous()->protocolFrameSize(); + } + else + return -1; + + qDebug("%s: ofs = %d", __FUNCTION__, size); + return size; +} + +int AbstractProtocol::protocolFramePayloadSize() const +{ + int size = 0; + + QLinkedListIterator iter(frameProtocols); + + if (iter.findNext(this)) + { + while (iter.hasNext()) + size += iter.next()->protocolFrameSize(); + } + else + return -1; + + qDebug("%s: payloadSize = %d", __FUNCTION__, size); + return size; +} + + /*! Returns a byte array encoding the protocol (and its fields) which can be inserted into the stream's frame The default implementation forms and returns an ordered concatenation of @@ -223,3 +315,53 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex) const return proto; } +QVariant AbstractProtocol::protocolFrameCksum() const +{ + QByteArray fv; + quint16 *ip; + quint32 len, sum = 0; + + fv = protocolFrameValue(-1); + ip = (quint16*) fv.constData(); + len = fv.size(); + + while(len > 1) + { + sum += *ip; + if(sum & 0x80000000) + sum = (sum & 0xFFFF) + (sum >> 16); + ip++; + len -= 2; + } + + if (len) + sum += (unsigned short) *(unsigned char *)ip; + + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); + + return qFromBigEndian((quint16) ~sum); +} + +QVariant AbstractProtocol::protocolFramePayloadCksum() const +{ + int cksum = 0; + QLinkedListIterator iter(frameProtocols); + + if (iter.findNext(this)) + { + while (iter.hasNext()) + cksum += iter.next()->protocolFrameCksum().toUInt(); // TODO: chg to partial + } + else + return -1; +#if 0 + while(cksum>>16) + cksum = (cksum & 0xFFFF) + (cksum >> 16); + + return (quint16) ~cksum; +#endif + + return cksum; +} + diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index 7c7255e..ec0584b 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -5,7 +5,9 @@ #include #include #include +#include +//#include "../rpc/pbhelper.h" #include "../common/protocol.pb.h" #define BASE_BIN (2) @@ -13,16 +15,24 @@ #define BASE_DEC (10) #define BASE_HEX (16) -class Stream; +#define uintToHexStr(num, bytes) \ + QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) + +class OstProto::StreamCore; +class AbstractProtocol; + +typedef QLinkedList ProtocolList; class AbstractProtocol { private: mutable int metaCount; + mutable int protoSize; mutable QString protoAbbr; protected: - Stream *stream; + OstProto::StreamCore *stream; + ProtocolList &frameProtocols; public: enum FieldAttrib { @@ -34,15 +44,29 @@ public: FieldIsMeta //! bool indicating if field is meta }; - AbstractProtocol(Stream *parent = 0); + enum ProtocolIdType { + ProtocolIdLlc, + ProtocolIdEth, + ProtocolIdIp, + }; + + AbstractProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~AbstractProtocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream) = 0; virtual void protoDataCopyFrom(const OstProto::Stream &stream) = 0; virtual QString name() const; virtual QString shortName() const; + virtual quint32 protocolId(ProtocolIdType type) const; + quint32 payloadProtocolId(ProtocolIdType type) const; + virtual int fieldCount() const; virtual int metaFieldCount() const; int frameFieldCount() const; @@ -53,6 +77,12 @@ public: FieldAttrib attrib = FieldValue); QByteArray protocolFrameValue(int streamIndex = 0) const; + int protocolFrameSize() const; + int protocolFrameOffset() const; + int protocolFramePayloadSize() const; + + virtual QVariant protocolFrameCksum() const; + QVariant protocolFramePayloadCksum() const; virtual QWidget* configWidget() = 0; virtual void loadConfigWidget() = 0; diff --git a/common/dot3.cpp b/common/dot3.cpp index 67b70d9..448c0c5 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -3,6 +3,8 @@ #include "Dot3.h" +#define SZ_FCS 4 + Dot3ConfigForm *Dot3Protocol::configForm = NULL; Dot3ConfigForm::Dot3ConfigForm(QWidget *parent) @@ -11,8 +13,10 @@ Dot3ConfigForm::Dot3ConfigForm(QWidget *parent) setupUi(this); } -Dot3Protocol::Dot3Protocol(Stream *parent) - : AbstractProtocol(parent) +Dot3Protocol::Dot3Protocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) { if (configForm == NULL) configForm = new Dot3ConfigForm; @@ -22,6 +26,13 @@ Dot3Protocol::~Dot3Protocol() { } +AbstractProtocol* Dot3Protocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new Dot3Protocol(frameProtoList, streamCore); +} + void Dot3Protocol::protoDataCopyInto(OstProto::Stream &stream) { // FIXME: multiple headers @@ -61,14 +72,27 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString("Length"); case FieldValue: - return data.length(); + { + quint16 len; + + len = stream->frame_len() - SZ_FCS; + return len; + } case FieldTextValue: - return QString("%1").arg(data.length()); + { + quint16 len; + + len = stream->frame_len() - SZ_FCS; + return QString("%1").arg(len); + } case FieldFrameValue: { + quint16 len; QByteArray fv; + + len = stream->frame_len() - SZ_FCS; fv.resize(2); - qToBigEndian((quint16) data.length(), (uchar*) fv.data()); + qToBigEndian(len, (uchar*) fv.data()); return fv; } default: @@ -98,7 +122,8 @@ QWidget* Dot3Protocol::configWidget() void Dot3Protocol::loadConfigWidget() { - configForm->leLength->setText(QString().setNum(data.length())); + configForm->leLength->setText( + fieldData(dot3_length, FieldValue).toString()); } void Dot3Protocol::storeConfigWidget() diff --git a/common/dot3.h b/common/dot3.h index e49f312..3b98b24 100644 --- a/common/dot3.h +++ b/common/dot3.h @@ -26,9 +26,14 @@ private: }; public: - Dot3Protocol(Stream *parent = 0); + Dot3Protocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~Dot3Protocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream); virtual void protoDataCopyFrom(const OstProto::Stream &stream); diff --git a/common/eth2.cpp b/common/eth2.cpp index caaf75b..9fbfda6 100644 --- a/common/eth2.cpp +++ b/common/eth2.cpp @@ -11,8 +11,10 @@ Eth2ConfigForm::Eth2ConfigForm(QWidget *parent) setupUi(this); } -Eth2Protocol::Eth2Protocol(Stream *parent) - : AbstractProtocol(parent) +Eth2Protocol::Eth2Protocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) { if (configForm == NULL) configForm = new Eth2ConfigForm; @@ -22,6 +24,13 @@ Eth2Protocol::~Eth2Protocol() { } +AbstractProtocol* Eth2Protocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new Eth2Protocol(frameProtoList, streamCore); +} + void Eth2Protocol::protoDataCopyInto(OstProto::Stream &stream) { // FIXME: multiple headers @@ -56,26 +65,31 @@ QVariant Eth2Protocol::fieldData(int index, FieldAttrib attrib, switch (index) { case eth2_type: + { + quint16 type; switch(attrib) { case FieldName: return QString("Type"); case FieldValue: - return data.type(); + type = payloadProtocolId(ProtocolIdEth); + return type; case FieldTextValue: - return QString("%1").arg(data.type(), 16); + type = payloadProtocolId(ProtocolIdEth); + return QString("0x%1").arg(type, 4, BASE_HEX, QChar('0')); case FieldFrameValue: { QByteArray fv; + type = payloadProtocolId(ProtocolIdEth); fv.resize(2); - qToBigEndian((quint16) data.type(), (uchar*) fv.data()); + qToBigEndian((quint16) type, (uchar*) fv.data()); return fv; } default: break; } break; - + } default: break; } @@ -112,12 +126,8 @@ QWidget* Eth2Protocol::configWidget() void Eth2Protocol::loadConfigWidget() { -#define uintToHexStr(num, bytesize) \ - QString("%1").arg((num), (bytesize)*2 , 16, QChar('0')) - - configForm->leType->setText(uintToHexStr(data.type(), 2)); - -#undef uintToHexStr + configForm->leType->setText(uintToHexStr( + fieldData(eth2_type, FieldValue).toUInt(), 2)); } void Eth2Protocol::storeConfigWidget() diff --git a/common/eth2.h b/common/eth2.h index 580b712..e71659d 100644 --- a/common/eth2.h +++ b/common/eth2.h @@ -26,9 +26,14 @@ private: }; public: - Eth2Protocol(Stream *parent = 0); + Eth2Protocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~Eth2Protocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream); virtual void protoDataCopyFrom(const OstProto::Stream &stream); diff --git a/common/eth2.ui b/common/eth2.ui index 9099dbb..a79068c 100644 --- a/common/eth2.ui +++ b/common/eth2.ui @@ -32,10 +32,10 @@ - true + false - HH HH; + >HH HH; diff --git a/common/ip4.cpp b/common/ip4.cpp index 625d3c7..260c720 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -44,9 +44,16 @@ void Ip4ConfigForm::on_cmbIpDstAddrMode_currentIndexChanged(int index) } } -Ip4Protocol::Ip4Protocol(Stream *parent) - : AbstractProtocol(parent) +Ip4Protocol::Ip4Protocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) { +#if 0 + PbHelper pbh; + + pbh.ForceSetSingularDefault(&data); +#endif if (configForm == NULL) configForm = new Ip4ConfigForm; } @@ -55,6 +62,13 @@ Ip4Protocol::~Ip4Protocol() { } +AbstractProtocol* Ip4Protocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new Ip4Protocol(frameProtoList, streamCore); +} + void Ip4Protocol::protoDataCopyInto(OstProto::Stream &stream) { // FIXME: multiple headers @@ -78,6 +92,19 @@ QString Ip4Protocol::shortName() const return QString("IPv4"); } +quint32 Ip4Protocol::protocolId(ProtocolIdType type) const +{ + switch(type) + { + case ProtocolIdLlc: return 0x060603; + case ProtocolIdEth: return 0x0800; + case ProtocolIdIp: return 0x04; + default:break; + } + + return AbstractProtocol::protocolId(type); +} + int Ip4Protocol::fieldCount() const { return ip4_fieldCount; @@ -139,25 +166,42 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, } break; case ip4_totLen: + { switch(attrib) { case FieldName: return QString("Total Length"); case FieldValue: - return data.totlen(); + { + int totlen; + totlen = data.is_override_totlen() ? data.totlen() : + (protocolFramePayloadSize() + 20); + return totlen; + } case FieldFrameValue: { QByteArray fv; + int totlen; + totlen = data.is_override_totlen() ? data.totlen() : + (protocolFramePayloadSize() + 20); fv.resize(2); - qToBigEndian((quint16) data.totlen(), (uchar*) fv.data()); + qToBigEndian((quint16) totlen, (uchar*) fv.data()); return fv; } case FieldTextValue: - return QString("%1").arg(data.totlen()); + { + int totlen; + totlen = data.is_override_totlen() ? data.totlen() : + (protocolFramePayloadSize() + 20); + return QString("%1").arg(totlen); + } + case FieldBitSize: + return 16; default: break; } break; + } case ip4_id: switch(attrib) { @@ -244,42 +288,86 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, } break; case ip4_proto: + { switch(attrib) { case FieldName: return QString("Protocol"); case FieldValue: - return data.proto(); + { + unsigned char id = payloadProtocolId(ProtocolIdIp); + return id; + } case FieldFrameValue: - return QByteArray(1, (char)data.proto()); + { + unsigned char id = payloadProtocolId(ProtocolIdIp); + return QByteArray(1, (char) id); + } case FieldTextValue: + { + unsigned char id = payloadProtocolId(ProtocolIdIp); return QString("0x%1"). - arg(data.proto(), 2, BASE_HEX, QChar('0')); + arg(id, 2, BASE_HEX, QChar('0')); + } default: break; } break; + } case ip4_cksum: + { + switch(attrib) { case FieldName: return QString("Header Checksum"); case FieldValue: - return data.cksum(); + { + quint16 cksum; + + if (streamIndex < 0) + cksum = 0; + else if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum().toUInt(); + return cksum; + } case FieldFrameValue: { QByteArray fv; + quint16 cksum; + + if (streamIndex < 0) + cksum = 0; + else if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum().toUInt(); fv.resize(2); - qToBigEndian((quint16) data.cksum(), (uchar*) fv.data()); + qToBigEndian((quint16) cksum, (uchar*) fv.data()); return fv; } case FieldTextValue: + { + quint16 cksum; + + if (streamIndex < 0) + cksum = 0; + else if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum().toUInt(); return QString("0x%1"). - arg(data.cksum(), 4, BASE_HEX, QChar('0'));; + arg(cksum, 4, BASE_HEX, QChar('0'));; + } + case FieldBitSize: + return 16; default: break; } break; + } case ip4_srcAddr: switch(attrib) { @@ -381,27 +469,27 @@ QWidget* Ip4Protocol::configWidget() void Ip4Protocol::loadConfigWidget() { -#define uintToHexStr(num, str, size) QString().setNum(num, 16) configForm->leIpVersion->setText(QString().setNum(data.ver_hdrlen() >> 4)); configForm->cbIpVersionOverride->setChecked(data.is_override_ver()); configForm->leIpHdrLen->setText(QString().setNum(data.ver_hdrlen() & 0x0F)); configForm->cbIpHdrLenOverride->setChecked(data.is_override_hdrlen()); - configForm->leIpTos->setText(uintToHexStr(data.tos(), QString(), 1)); - - configForm->leIpLength->setText(QString().setNum(data.totlen())); + configForm->leIpTos->setText(uintToHexStr(data.tos(), 1)); + configForm->leIpLength->setText(fieldData(ip4_totLen, FieldValue).toString()); configForm->cbIpLengthOverride->setChecked(data.is_override_totlen()); - configForm->leIpId->setText(uintToHexStr(data.id(), QString(), 2)); + configForm->leIpId->setText(uintToHexStr(data.id(), 2)); configForm->leIpFragOfs->setText(QString().setNum(data.frag_ofs())); configForm->cbIpFlagsDf->setChecked((data.flags() & IP_FLAG_DF) > 0); configForm->cbIpFlagsMf->setChecked((data.flags() & IP_FLAG_MF) > 0); configForm->leIpTtl->setText(QString().setNum(data.ttl())); - configForm->leIpProto->setText(uintToHexStr(data.proto(), QString(), 1)); + configForm->leIpProto->setText(uintToHexStr( + fieldData(ip4_proto, FieldValue).toUInt(), 1)); - configForm->leIpCksum->setText(uintToHexStr(data.cksum(), QString(), 2)); + configForm->leIpCksum->setText(uintToHexStr( + fieldData(ip4_cksum, FieldValue).toUInt(), 2)); configForm->cbIpCksumOverride->setChecked(data.is_override_cksum()); configForm->leIpSrcAddr->setText(QHostAddress(data.src_ip()).toString()); diff --git a/common/ip4.h b/common/ip4.h index 73d3004..1bf8ccc 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -58,15 +58,20 @@ private: }; public: - Ip4Protocol(Stream *parent = 0); + Ip4Protocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~Ip4Protocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream); virtual void protoDataCopyFrom(const OstProto::Stream &stream); virtual QString name() const; virtual QString shortName() const; - + virtual quint32 protocolId(ProtocolIdType type) const; virtual int fieldCount() const; virtual QVariant fieldData(int index, FieldAttrib attrib, diff --git a/common/ip4.ui b/common/ip4.ui index 35a85bf..785e7e3 100644 --- a/common/ip4.ui +++ b/common/ip4.ui @@ -28,7 +28,7 @@ false - 4 +
@@ -45,7 +45,7 @@ false - 5 + @@ -59,7 +59,7 @@ - HH; + >HH; @@ -100,7 +100,7 @@ - HH HH; + >HH HH; @@ -149,7 +149,7 @@ - 64 + @@ -183,7 +183,7 @@ false - HH HH; + >HH HH; @@ -291,8 +291,11 @@ false + + 009.009.009.009; + - 255.255.255.255 + ... @@ -355,8 +358,11 @@ false + + 009.009.009.009; + - 255.255.255.255 + ... diff --git a/common/llc.cpp b/common/llc.cpp index 394ca2c..c0183ca 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -11,8 +11,10 @@ LlcConfigForm::LlcConfigForm(QWidget *parent) setupUi(this); } -LlcProtocol::LlcProtocol(Stream *parent) - : AbstractProtocol(parent) +LlcProtocol::LlcProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) { if (configForm == NULL) configForm = new LlcConfigForm; @@ -22,6 +24,13 @@ LlcProtocol::~LlcProtocol() { } +AbstractProtocol* LlcProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new LlcProtocol(frameProtoList, streamCore); +} + void LlcProtocol::protoDataCopyInto(OstProto::Stream &stream) { // FIXME: multiple headers @@ -53,6 +62,14 @@ int LlcProtocol::fieldCount() const QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { + quint32 id; + quint8 dsap, ssap, ctl; + + id = payloadProtocolId(ProtocolIdLlc); + dsap = (id >> 16) & 0xFF; + ssap = (id >> 8) & 0xFF; + ctl = (id >> 0) & 0xFF; + switch (index) { case llc_dsap: @@ -61,11 +78,11 @@ QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString("DSAP"); case FieldValue: - return data.dsap(); + return dsap; case FieldTextValue: - return QString("%1").arg(data.dsap(), BASE_HEX); + return QString("%1").arg(dsap, 2, BASE_HEX, QChar('0')); case FieldFrameValue: - return QByteArray(1, (char)(data.dsap())); + return QByteArray(1, (char)(dsap)); default: break; } @@ -74,13 +91,13 @@ QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib, switch(attrib) { case FieldName: - return QString("DSAP"); + return QString("SSAP"); case FieldValue: - return data.ssap(); + return ssap; case FieldTextValue: - return QString("%1").arg(data.ssap(), BASE_HEX); + return QString("%1").arg(ssap, 2, BASE_HEX, QChar('0')); case FieldFrameValue: - return QByteArray(1, (char)(data.ssap())); + return QByteArray(1, (char)(ssap)); default: break; } @@ -89,13 +106,13 @@ QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib, switch(attrib) { case FieldName: - return QString("DSAP"); + return QString("Control"); case FieldValue: - return data.ctl(); + return ctl; case FieldTextValue: - return QString("%1").arg(data.ctl(), BASE_HEX); + return QString("%1").arg(ctl, 2, BASE_HEX, QChar('0')); case FieldFrameValue: - return QByteArray(1, (char)(data.ctl())); + return QByteArray(1, (char)(ctl)); default: break; } @@ -123,9 +140,16 @@ QWidget* LlcProtocol::configWidget() void LlcProtocol::loadConfigWidget() { - configForm->leDsap->setText(QString("%1").arg(data.dsap(), 2, BASE_HEX, QChar('0'))); - configForm->leSsap->setText(QString("%1").arg(data.ssap(), 2, BASE_HEX, QChar('0'))); - configForm->leControl->setText(QString("%1").arg(data.ctl(), 2, BASE_HEX, QChar('0'))); +#define uintToHexStr(num, bytes) \ + QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) + + configForm->leDsap->setText(uintToHexStr( + fieldData(llc_dsap, FieldValue).toUInt(), 1)); + configForm->leSsap->setText(uintToHexStr( + fieldData(llc_ssap, FieldValue).toUInt(), 1)); + configForm->leControl->setText(uintToHexStr( + fieldData(llc_ctl, FieldValue).toUInt(), 1)); +#undef uintToHexStr } void LlcProtocol::storeConfigWidget() diff --git a/common/llc.h b/common/llc.h index 18e1181..8403fab 100644 --- a/common/llc.h +++ b/common/llc.h @@ -31,9 +31,14 @@ private: }; public: - LlcProtocol(Stream *parent = 0); + LlcProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~LlcProtocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream); virtual void protoDataCopyFrom(const OstProto::Stream &stream); diff --git a/common/llc.ui b/common/llc.ui index 4518b3d..5f305a0 100644 --- a/common/llc.ui +++ b/common/llc.ui @@ -38,10 +38,10 @@ - true + false - HH; + >HH; @@ -58,10 +58,10 @@ - true + false - HH; + >HH; @@ -78,10 +78,10 @@ - true + false - HH; + >HH; diff --git a/common/mac.cpp b/common/mac.cpp index 59b2607..53defa7 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -46,8 +46,10 @@ void MacConfigForm::on_cmbSrcMacMode_currentIndexChanged(int index) } -MacProtocol::MacProtocol(Stream *parent) - : AbstractProtocol(parent) +MacProtocol::MacProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) { if (configForm == NULL) configForm = new MacConfigForm; @@ -57,6 +59,13 @@ MacProtocol::~MacProtocol() { } +AbstractProtocol* MacProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new MacProtocol(frameProtoList, streamCore); +} + void MacProtocol::protoDataCopyInto(OstProto::Stream &stream) { // FIXME: multiple headers @@ -174,13 +183,12 @@ QWidget* MacProtocol::configWidget() void MacProtocol::loadConfigWidget() { -#define uintToHexStr(num, str, size) QString().setNum(num, 16) - configForm->leDstMac->setText(uintToHexStr(data.dst_mac(), str, 6)); + configForm->leDstMac->setText(uintToHexStr(data.dst_mac(), 6)); configForm->cmbDstMacMode->setCurrentIndex(data.dst_mac_mode()); configForm->leDstMacCount->setText(QString().setNum(data.dst_mac_count())); configForm->leDstMacStep->setText(QString().setNum(data.dst_mac_step())); - configForm->leSrcMac->setText(uintToHexStr(data.src_mac(), QString(), 6)); + configForm->leSrcMac->setText(uintToHexStr(data.src_mac(), 6)); configForm->cmbSrcMacMode->setCurrentIndex(data.src_mac_mode()); configForm->leSrcMacCount->setText(QString().setNum(data.src_mac_count())); configForm->leSrcMacStep->setText(QString().setNum(data.src_mac_step())); diff --git a/common/mac.h b/common/mac.h index 2842475..575b9b1 100644 --- a/common/mac.h +++ b/common/mac.h @@ -39,9 +39,14 @@ private: }; public: - MacProtocol(Stream *parent = 0); + MacProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~MacProtocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream); virtual void protoDataCopyFrom(const OstProto::Stream &stream); diff --git a/common/mac.ui b/common/mac.ui index 9095f29..9afb006 100644 --- a/common/mac.ui +++ b/common/mac.ui @@ -49,7 +49,7 @@ - HH HH HH HH HH HH; + >HH HH HH HH HH HH; @@ -111,7 +111,7 @@ - HH HH HH HH HH HH; + >HH HH HH HH HH HH; diff --git a/common/ostproto.pro b/common/ostproto.pro index 3bd8e9c..59b2453 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -26,6 +26,9 @@ PROTOS += \ udp.proto HEADERS += \ abstractprotocol.h \ + protocolmanager.h \ + protocolcollection.h \ + streambase.h \ mac.h \ payload.h \ eth2.h \ @@ -37,6 +40,9 @@ HEADERS += \ udp.h SOURCES += \ abstractprotocol.cpp \ + protocolmanager.cpp \ + protocolcollection.cpp \ + streambase.cpp \ mac.cpp \ payload.cpp \ eth2.cpp \ diff --git a/common/payload.cpp b/common/payload.cpp index 8feecf9..8e79c7d 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -1,9 +1,11 @@ #include #include -#include "../client/stream.h" +//#include "../client/stream.h" #include "payload.h" +#define SZ_FCS 4 + PayloadConfigForm *PayloadProtocol::configForm = NULL; PayloadConfigForm::PayloadConfigForm(QWidget *parent) @@ -29,8 +31,10 @@ void PayloadConfigForm::on_cmbPatternMode_currentIndexChanged(int index) } } -PayloadProtocol::PayloadProtocol(Stream *parent) - : AbstractProtocol(parent) +PayloadProtocol::PayloadProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) { if (configForm == NULL) configForm = new PayloadConfigForm; @@ -40,6 +44,13 @@ PayloadProtocol::~PayloadProtocol() { } +AbstractProtocol* PayloadProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new PayloadProtocol(frameProtoList, streamCore); +} + void PayloadProtocol::protoDataCopyInto(OstProto::Stream &stream) { // FIXME: multiple headers @@ -88,10 +99,8 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, QByteArray fv; int dataLen; - // FIXME: cannot use stream since it is only on client not - // on server - //dataLen = stream->frameLen() - stream->protocolHeaderSize(); - dataLen = 64; + dataLen = stream->frame_len() - protocolFrameOffset(); + dataLen -= SZ_FCS; fv.resize(dataLen+4); switch(data.pattern_mode()) { @@ -159,10 +168,8 @@ QWidget* PayloadProtocol::configWidget() void PayloadProtocol::loadConfigWidget() { -#define uintToHexStr(num, str, size) QString().setNum(num, 16) - configForm->cmbPatternMode->setCurrentIndex(data.pattern_mode()); - configForm->lePattern->setText(uintToHexStr(data.pattern(), QString(), 4)); + configForm->lePattern->setText(uintToHexStr(data.pattern(), 4)); } void PayloadProtocol::storeConfigWidget() diff --git a/common/payload.h b/common/payload.h index aa66f5d..4a1dc03 100644 --- a/common/payload.h +++ b/common/payload.h @@ -31,9 +31,14 @@ private: }; public: - PayloadProtocol(Stream *parent = 0); + PayloadProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~PayloadProtocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream); virtual void protoDataCopyFrom(const OstProto::Stream &stream); diff --git a/common/payload.ui b/common/payload.ui index 9de7ce1..c0a1b31 100644 --- a/common/payload.ui +++ b/common/payload.ui @@ -46,7 +46,7 @@ - HH HH HH HH; + >HH HH HH HH; diff --git a/common/protocolcollection.cpp b/common/protocolcollection.cpp new file mode 100644 index 0000000..60e6d21 --- /dev/null +++ b/common/protocolcollection.cpp @@ -0,0 +1,106 @@ +#include "protocolcollection.h" + +extern ProtocolManager OstProtocolManager; + +ProtocolCollection::ProtocolCollection(ProtocolList &streamProtocols, + OstProto::StreamCore *streamCore) + : protoManager(OstProtocolManager) +{ + // Create an instance of each registered protocol + + QMapIterator iter(protoManager.factory); + + while (iter.hasNext()) + { + AbstractProtocol* (*p)(ProtocolList&, OstProto::StreamCore*); + AbstractProtocol* q; + + iter.next(); + p = (AbstractProtocol* (*)(ProtocolList&, OstProto::StreamCore*)) + iter.value(); + q = (*p)(streamProtocols, streamCore); + + protocols.insert(iter.key(), q); + } +} + +ProtocolCollection::~ProtocolCollection() +{ + QMutableMapIterator iter(protocols); + + while (iter.hasNext()) + { + iter.next(); + if (iter.value()) + { + delete iter.value(); + iter.remove(); + } + } +} + +void ProtocolCollection::protoDataCopyFrom(const OstProto::Stream &stream) const +{ + QMapIterator iter(protocols); + + while (iter.hasNext()) + { + iter.next(); + if (iter.value()) + { + iter.value()->protoDataCopyFrom(stream); + } + } +} + +void ProtocolCollection::protoDataCopyInto(OstProto::Stream &stream) const +{ + QMapIterator iter(protocols); + + while (iter.hasNext()) + { + iter.next(); + if (iter.value()) + { + iter.value()->protoDataCopyInto(stream); + } + } +} + +void ProtocolCollection::loadConfigWidgets() const +{ + QMapIterator iter(protocols); + + while (iter.hasNext()) + { + iter.next(); + if (iter.value()) + { + iter.value()->loadConfigWidget(); + } + } +} + +void ProtocolCollection::storeConfigWidgets() const +{ + QMapIterator iter(protocols); + + while (iter.hasNext()) + { + iter.next(); + if (iter.value()) + { + iter.value()->storeConfigWidget(); + } + } +} + +AbstractProtocol* ProtocolCollection::protocol(int protoNum) +{ + return protocols.value(protoNum); +} + +AbstractProtocol* ProtocolCollection::protocol(QString protoName) +{ + return protocols.value(protoManager.nameToNumberMap.value(protoName)); +} diff --git a/common/protocolcollection.h b/common/protocolcollection.h new file mode 100644 index 0000000..61ca418 --- /dev/null +++ b/common/protocolcollection.h @@ -0,0 +1,30 @@ +#ifndef _PROTOCOL_COLLECTION_H +#define _PROTOCOL_COLLECTION_H + +#include +#include + +#include "abstractprotocol.h" +#include "protocolmanager.h" + +class ProtocolCollection { + + ProtocolManager &protoManager; + QMap protocols; + +public: + ProtocolCollection(ProtocolList &streamProtocols, + OstProto::StreamCore *streamCore); + ProtocolCollection::~ProtocolCollection(); + + void protoDataCopyFrom(const OstProto::Stream &stream) const; + void protoDataCopyInto(OstProto::Stream &stream) const; + + void loadConfigWidgets() const; + void storeConfigWidgets() const; + + AbstractProtocol* protocol(int protoNum); + AbstractProtocol* protocol(QString protoName); +}; + +#endif diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp new file mode 100644 index 0000000..7b49e33 --- /dev/null +++ b/common/protocolmanager.cpp @@ -0,0 +1,38 @@ +#include "protocolmanager.h" + +#include "mac.h" +#include "payload.h" + +#include "eth2.h" +#include "dot3.h" +#include "llc.h" +#include "snap.h" +#include "ip4.h" +#include "tcp.h" +#include "udp.h" + +QMap ProtocolManager::factory; +QMap ProtocolManager::nameToNumberMap; + +ProtocolManager OstProtocolManager; + +ProtocolManager::ProtocolManager() +{ + registerProtocol(51, QString("mac"), (void*) MacProtocol::createInstance); + registerProtocol(52, QString("payload"), (void*) PayloadProtocol::createInstance); + registerProtocol(121, QString("eth2"), (void*) Eth2Protocol::createInstance); + registerProtocol(122, QString("dot3"), (void*) Dot3Protocol::createInstance); + registerProtocol(123, QString("llc"), (void*) LlcProtocol::createInstance); + registerProtocol(124, QString("snap"), (void*) SnapProtocol::createInstance); + registerProtocol(130, QString("ip4"), (void*) Ip4Protocol::createInstance); + registerProtocol(140, QString("tcp"), (void*) TcpProtocol::createInstance); + registerProtocol(141, QString("udp"), (void*) UdpProtocol::createInstance); +} + +void ProtocolManager::registerProtocol(int protoNumber, QString protoName, + void *protoInstanceCreator) +{ + // TODO: validate incoming params for duplicates with existing + nameToNumberMap.insert(protoName, protoNumber); + factory.insert(protoNumber, protoInstanceCreator); +} diff --git a/common/protocolmanager.h b/common/protocolmanager.h new file mode 100644 index 0000000..5d8e1ca --- /dev/null +++ b/common/protocolmanager.h @@ -0,0 +1,18 @@ +#ifndef _PROTOCOL_MANAGER_H +#define _PROTOCOL_MANAGER_H + +#include + +class ProtocolManager +{ +public: + static QMap nameToNumberMap; + static QMap factory; + +public: + ProtocolManager(); + void registerProtocol(int protoNumber, QString protoName, + void *protoCreator); +}; + +#endif diff --git a/common/snap.cpp b/common/snap.cpp index 33f841e..46cca1e 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -11,8 +11,10 @@ SnapConfigForm::SnapConfigForm(QWidget *parent) setupUi(this); } -SnapProtocol::SnapProtocol(Stream *parent) - : AbstractProtocol(parent) +SnapProtocol::SnapProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) { if (configForm == NULL) configForm = new SnapConfigForm; @@ -22,6 +24,13 @@ SnapProtocol::~SnapProtocol() { } +AbstractProtocol* SnapProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new SnapProtocol(frameProtoList, streamCore); +} + void SnapProtocol::protoDataCopyInto(OstProto::Stream &stream) { // FIXME: multiple headers @@ -45,6 +54,17 @@ QString SnapProtocol::shortName() const return QString("SNAP"); } +quint32 SnapProtocol::protocolId(ProtocolIdType type) const +{ + switch(type) + { + case ProtocolIdLlc: return 0xAAAA03; + default: break; + } + + return AbstractProtocol::protocolId(type); +} + int SnapProtocol::fieldCount() const { return snap_fieldCount; @@ -76,7 +96,33 @@ QVariant SnapProtocol::fieldData(int index, FieldAttrib attrib, break; } break; + case snap_type: + { + quint16 type; + switch(attrib) + { + case FieldName: + return QString("Type"); + case FieldValue: + type = payloadProtocolId(ProtocolIdEth); + return type; + case FieldTextValue: + type = payloadProtocolId(ProtocolIdEth); + return QString("%1").arg(type, 4, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + type = payloadProtocolId(ProtocolIdEth); + qToBigEndian(type, (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } default: break; } @@ -99,14 +145,17 @@ QWidget* SnapProtocol::configWidget() void SnapProtocol::loadConfigWidget() { -#define uintToHexStr(num, str, size) QString().setNum(num, 16) - configForm->leOui->setText(uintToHexStr(data.oui(), str, 3)); + configForm->leOui->setText(uintToHexStr( + fieldData(snap_oui, FieldValue).toUInt(), 3)); + configForm->leType->setText(uintToHexStr( + fieldData(snap_type, FieldValue).toUInt(), 2)); } void SnapProtocol::storeConfigWidget() { bool isOk; - data.set_oui(configForm->leOui->text().remove(QChar(' ')).toULong(&isOk, 16)); + data.set_oui(configForm->leOui->text().toULong(&isOk, BASE_HEX)); + data.set_type(configForm->leType->text().toULong(&isOk, BASE_HEX)); } diff --git a/common/snap.h b/common/snap.h index 9913b0f..ba0a3b6 100644 --- a/common/snap.h +++ b/common/snap.h @@ -21,19 +21,26 @@ private: enum snapfield { snap_oui = 0, + snap_type, snap_fieldCount }; public: - SnapProtocol(Stream *parent = 0); + SnapProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~SnapProtocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream); virtual void protoDataCopyFrom(const OstProto::Stream &stream); virtual QString name() const; virtual QString shortName() const; + virtual quint32 protocolId(ProtocolIdType type) const; virtual int fieldCount() const; diff --git a/common/snap.proto b/common/snap.proto index b6c310c..c5ea432 100644 --- a/common/snap.proto +++ b/common/snap.proto @@ -4,7 +4,7 @@ package OstProto; message Snap { optional uint32 oui = 1; - //optional uint32 type = 2; + optional uint32 type = 2; } extend Stream { diff --git a/common/snap.ui b/common/snap.ui index 1f2b789..9d0e4a5 100644 --- a/common/snap.ui +++ b/common/snap.ui @@ -29,10 +29,10 @@ - true + false - HH HH HH; + >HH HH HH; @@ -46,10 +46,10 @@ - true + false - HH HH; + >HH HH; diff --git a/common/streambase.cpp b/common/streambase.cpp new file mode 100644 index 0000000..4bd4faf --- /dev/null +++ b/common/streambase.cpp @@ -0,0 +1,69 @@ +#include "streambase.h" + +StreamBase::StreamBase() : + mStreamId(new OstProto::StreamId), + mCore(new OstProto::StreamCore), + mControl(new OstProto::StreamControl), + protocols(currentFrameProtocols, mCore) +{ + mStreamId->set_id(0xFFFFFFFF); +} + +StreamBase::~StreamBase() +{ + delete mStreamId; + delete mCore; + delete mControl; +} + +void StreamBase::protoDataCopyFrom(const OstProto::Stream &stream) +{ + mStreamId->CopyFrom(stream.stream_id()); + mCore->CopyFrom(stream.core()); + mControl->CopyFrom(stream.control()); + + protocols.protoDataCopyFrom(stream); + setFrameProtocol(frameProtocol()); +} + +void StreamBase::protoDataCopyInto(OstProto::Stream &stream) const +{ + stream.mutable_stream_id()->CopyFrom(*mStreamId); + stream.mutable_core()->CopyFrom(*mCore); + stream.mutable_control()->CopyFrom(*mControl); + + protocols.protoDataCopyInto(stream); +} + +QList StreamBase::frameProtocol() +{ + QList protocolList; + + for (int i = 0; i < mCore->frame_proto_size(); i++) + protocolList.append(mCore->frame_proto(i)); + + return protocolList; +} + +void StreamBase::setFrameProtocol(QList protocolList) +{ + mCore->clear_frame_proto(); + currentFrameProtocols.clear(); + + for (int i = 0; i < protocolList.size(); i++) + { + mCore->add_frame_proto(protocolList.at(i)); + currentFrameProtocols.append(protocols.protocol(protocolList.at(i))); + } +} + +AbstractProtocol* StreamBase::protocol(int protoNum) +{ + return protocols.protocol(protoNum); +} + +AbstractProtocol* StreamBase::protocol(QString protoName) +{ + return protocols.protocol(protoName); +} + diff --git a/common/streambase.h b/common/streambase.h new file mode 100644 index 0000000..c8eb2c8 --- /dev/null +++ b/common/streambase.h @@ -0,0 +1,36 @@ +#ifndef _STREAM_BASE_H +#define _STREAM_BASE_H + +#include + +#include "protocolcollection.h" + +class StreamBase +{ +protected: // TODO: temp - make private + OstProto::StreamId *mStreamId; + OstProto::StreamCore *mCore; + OstProto::StreamControl *mControl; + +private: + ProtocolList currentFrameProtocols; +protected: + ProtocolCollection protocols; + +public: + StreamBase(); + ~StreamBase(); + + void protoDataCopyFrom(const OstProto::Stream &stream); + void protoDataCopyInto(OstProto::Stream &stream) const; + + QList frameProtocol(); + void setFrameProtocol(QList protocolList); + + AbstractProtocol* protocol(int protoNum); + AbstractProtocol* protocol(QString protoName); + + // TODO: make a copy constructor +}; + +#endif diff --git a/common/tcp.cpp b/common/tcp.cpp index 4c81c1c..26b14c0 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -11,8 +11,10 @@ TcpConfigForm::TcpConfigForm(QWidget *parent) setupUi(this); } -TcpProtocol::TcpProtocol(Stream *parent) - : AbstractProtocol(parent) +TcpProtocol::TcpProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) { if (configForm == NULL) configForm = new TcpConfigForm; @@ -22,6 +24,13 @@ TcpProtocol::~TcpProtocol() { } +AbstractProtocol* TcpProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new TcpProtocol(frameProtoList, streamCore); +} + void TcpProtocol::protoDataCopyInto(OstProto::Stream &stream) { // FIXME: multiple headers @@ -45,6 +54,17 @@ QString TcpProtocol::shortName() const return QString("TCP"); } +quint32 TcpProtocol::protocolId(ProtocolIdType type) const +{ + switch(type) + { + case ProtocolIdIp: return 0x06; + default: break; + } + + return AbstractProtocol::protocolId(type); +} + int TcpProtocol::fieldCount() const { return tcp_fieldCount; @@ -149,7 +169,7 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, case FieldTextValue: return QString("%1").arg((data.hdrlen_rsvd() >> 4) & 0x0F); case FieldFrameValue: - return QByteArray(1, (char)((data.hdrlen_rsvd() >> 4) & 0x0F)); + return QByteArray(1, (char)(data.hdrlen_rsvd() & 0xF0)); case FieldBitSize: return 4; default: @@ -303,7 +323,6 @@ QWidget* TcpProtocol::configWidget() void TcpProtocol::loadConfigWidget() { -#define uintToHexStr(num, str, size) QString().setNum(num, 16) configForm->leTcpSrcPort->setText(QString().setNum(data.src_port())); configForm->leTcpDstPort->setText(QString().setNum(data.dst_port())); diff --git a/common/tcp.h b/common/tcp.h index 9fc2367..0637fc1 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -45,14 +45,20 @@ private: }; public: - TcpProtocol(Stream *parent = 0); + TcpProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~TcpProtocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream); virtual void protoDataCopyFrom(const OstProto::Stream &stream); virtual QString name() const; virtual QString shortName() const; + virtual quint32 protocolId(ProtocolIdType type) const; virtual int fieldCount() const; diff --git a/common/tcp.ui b/common/tcp.ui index 4a333be..e19e9fb 100644 --- a/common/tcp.ui +++ b/common/tcp.ui @@ -43,7 +43,7 @@ false - HH HH; + >HH HH; diff --git a/common/udp.cpp b/common/udp.cpp index c2e1bfe..4d8585a 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -11,8 +11,10 @@ UdpConfigForm::UdpConfigForm(QWidget *parent) setupUi(this); } -UdpProtocol::UdpProtocol(Stream *parent) - : AbstractProtocol(parent) +UdpProtocol::UdpProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) { if (configForm == NULL) configForm = new UdpConfigForm; @@ -22,6 +24,13 @@ UdpProtocol::~UdpProtocol() { } +AbstractProtocol* UdpProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new UdpProtocol(frameProtoList, streamCore); +} + void UdpProtocol::protoDataCopyInto(OstProto::Stream &stream) { // FIXME: multiple headers @@ -45,6 +54,17 @@ QString UdpProtocol::shortName() const return QString("UDP"); } +quint32 UdpProtocol::protocolId(ProtocolIdType type) const +{ + switch(type) + { + case ProtocolIdIp: return 0x11; + default: break; + } + + return AbstractProtocol::protocolId(type); +} + int UdpProtocol::fieldCount() const { return udp_fieldCount; @@ -98,26 +118,47 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, break; case udp_totLen: + { + switch(attrib) { case FieldName: return QString("Datagram Length"); case FieldValue: - return data.totlen(); - case FieldTextValue: - return QString("%1").arg(data.totlen()); + { + int totlen; + + totlen = data.is_override_totlen() ? + data.totlen() : + (protocolFramePayloadSize() + 8); + return totlen; + } case FieldFrameValue: { QByteArray fv; + int totlen; + totlen = data.is_override_totlen() ? + data.totlen() : + (protocolFramePayloadSize() + 8); fv.resize(2); - qToBigEndian((quint16) data.totlen(), (uchar*) fv.data()); + qToBigEndian((quint16) totlen, (uchar*) fv.data()); return fv; } + case FieldTextValue: + { + int totlen; + totlen = data.is_override_totlen() ? + data.totlen() : + (protocolFramePayloadSize() + 8); + return QString("%1").arg(totlen); + } + case FieldBitSize: + return 16; default: break; } break; - + } case udp_cksum: switch(attrib) { @@ -173,7 +214,6 @@ QWidget* UdpProtocol::configWidget() void UdpProtocol::loadConfigWidget() { -#define uintToHexStr(num, str, size) QString().setNum(num, 16) configForm->leUdpSrcPort->setText(QString().setNum(data.src_port())); configForm->leUdpDstPort->setText(QString().setNum(data.dst_port())); diff --git a/common/udp.h b/common/udp.h index 4fe5147..5c40330 100644 --- a/common/udp.h +++ b/common/udp.h @@ -32,14 +32,20 @@ private: }; public: - UdpProtocol(Stream *parent = 0); + UdpProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); virtual ~UdpProtocol(); + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + virtual void protoDataCopyInto(OstProto::Stream &stream); virtual void protoDataCopyFrom(const OstProto::Stream &stream); virtual QString name() const; virtual QString shortName() const; + virtual quint32 protocolId(ProtocolIdType type) const; virtual int fieldCount() const; diff --git a/common/udp.ui b/common/udp.ui index e8e29d3..c5c9862 100644 --- a/common/udp.ui +++ b/common/udp.ui @@ -62,7 +62,7 @@ false - HH HH; + >HH HH; @@ -97,5 +97,38 @@ - + + + cbUdpLengthOverride + toggled(bool) + leUdpLength + setEnabled(bool) + + + 59 + 63 + + + 149 + 63 + + + + + cbUdpCksumOverride + toggled(bool) + leUdpCksum + setEnabled(bool) + + + 55 + 106 + + + 158 + 106 + + + +
diff --git a/common/vlan.ui b/common/vlan.ui index 0ae3be6..c35dc89 100644 --- a/common/vlan.ui +++ b/common/vlan.ui @@ -126,7 +126,7 @@ true - HH HH; + >HH HH; diff --git a/server/myservice.cpp b/server/myservice.cpp index 20bbda0..546fda5 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -4,17 +4,6 @@ #include #include -#include "../common/mac.h" -#include "../common/payload.h" - -#include "../common/eth2.h" // FIXME: proto DB -#include "../common/dot3.h" // FIXME: proto DB -#include "../common/llc.h" // FIXME: proto DB -#include "../common/snap.h" // FIXME: proto DB -#include "../common/ip4.h" // FIXME: proto DB -#include "../common/tcp.h" // FIXME: proto DB -#include "../common/udp.h" // FIXME: proto DB - #if 0 #include #include @@ -25,62 +14,19 @@ StreamInfo::StreamInfo() { +#if 0 PbHelper pbh; - pbh.ForceSetSingularDefault(&mCore); - pbh.ForceSetSingularDefault(&mControl); - - mProtocolList.append(new MacProtocol); - mProtocolList.append(new PayloadProtocol()); - - // FIXME: proto DB - mProtocolList.append(new Eth2Protocol); - mProtocolList.append(new Dot3Protocol); - mProtocolList.append(new LlcProtocol); - mProtocolList.append(new SnapProtocol); - mProtocolList.append(new Ip4Protocol); - mProtocolList.append(new TcpProtocol); - mProtocolList.append(new UdpProtocol); + pbh.ForceSetSingularDefault(mCore); + pbh.ForceSetSingularDefault(mControl); +#endif } StreamInfo::~StreamInfo() { - for (int i = 0; i < mProtocolList.size(); i++) - delete mProtocolList.at(i); -} - -AbstractProtocol* StreamInfo::protocolById(int id) -{ - // FIXME BAD BAD VERY BAD! - switch(id) { - case 51: - return mProtocolList.at(0); - case 52: - return mProtocolList.at(1); - case 121: - return mProtocolList.at(2); - case 122: - return mProtocolList.at(3); - case 123: - return mProtocolList.at(4); - case 124: - return mProtocolList.at(5); - // case 125 (unused) -#if 0 // todo VLAN - case 126: - return mProtocolList.at(x); -#endif - case 130: - return mProtocolList.at(6); - case 140: - return mProtocolList.at(7); - case 141: - return mProtocolList.at(8); - default: - return NULL; - } } +#if 0 quint32 StreamInfo::pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp, quint8 protocol, quint16 len) { @@ -96,78 +42,34 @@ quint32 StreamInfo::pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp, // Above calculation done assuming 'big endian' - so convert to host order return qFromBigEndian(sum); } +#endif -quint32 StreamInfo::ipv4CksumPartial(uchar *buf, int len) -{ - quint32 sum = 0; - quint16 *ip = (quint16*) buf; - - if (len & 0x0001) - { - qFatal("Cannot calculate partial checksum on non multiple of 2 length"); - return 0; - } - - while(len) - { - sum += *ip; - if(sum & 0x80000000) - sum = (sum & 0xFFFF) + (sum >> 16); - ip++; - len -= 2; - } - - return sum; -} - -quint16 StreamInfo::ipv4Cksum(uchar *buf, int len, quint32 partialSum) -{ - quint32 sum = partialSum; - quint16 *ip = (quint16*) buf; - - while(len > 1) - { - sum += *ip; - if(sum & 0x80000000) - sum = (sum & 0xFFFF) + (sum >> 16); - ip++; - len -= 2; - } - - if (len) - sum += (unsigned short) *(unsigned char *)ip; - - while(sum>>16) - sum = (sum & 0xFFFF) + (sum >> 16); - - return (quint16) ~sum; -} int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) { int pktLen, len = 0; // Decide a frame length based on length mode - switch(mCore.len_mode()) + switch(mCore->len_mode()) { case OstProto::StreamCore::e_fl_fixed: - pktLen = mCore.frame_len(); + pktLen = mCore->frame_len(); break; case OstProto::StreamCore::e_fl_inc: - pktLen = mCore.frame_len_min() + (n % - (mCore.frame_len_max() - mCore.frame_len_min() + 1)); + pktLen = mCore->frame_len_min() + (n % + (mCore->frame_len_max() - mCore->frame_len_min() + 1)); break; case OstProto::StreamCore::e_fl_dec: - pktLen = mCore.frame_len_max() - (n % - (mCore.frame_len_max() - mCore.frame_len_min() + 1)); + pktLen = mCore->frame_len_max() - (n % + (mCore->frame_len_max() - mCore->frame_len_min() + 1)); break; case OstProto::StreamCore::e_fl_random: - pktLen = mCore.frame_len_min() + (qrand() % - (mCore.frame_len_max() - mCore.frame_len_min() + 1)); + pktLen = mCore->frame_len_min() + (qrand() % + (mCore->frame_len_max() - mCore->frame_len_min() + 1)); break; default: qWarning("Unhandled len mode %d. Using default 64", - mCore.len_mode()); + mCore->len_mode()); pktLen = 64; break; } @@ -179,14 +81,11 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) return 0; // FIXME: Calculated pktLen is an input to Payload Protocol - - // FIXME: checksums!!! - - for (int i = 0; i < mCore.frame_proto_size(); i++) + for (int i = 0; i < mCore->frame_proto_size(); i++) { QByteArray ba; - ba = protocolById(mCore.frame_proto(i))->protocolFrameValue(n); + ba = protocol(mCore->frame_proto(i))->protocolFrameValue(n); if (len + ba.size() < bufMaxSize) { memcpy(buf+len, ba.constData(), ba.size()); @@ -690,28 +589,28 @@ void PortInfo::update() for (int i = 0; i < streamList.size(); i++) { //_restart: - if (streamList[i]->mCore.is_enabled()) + if (streamList[i]->mCore->is_enabled()) { long numPackets, numBursts; long ibg, ipg; - switch (streamList[i]->mControl.unit()) + switch (streamList[i]->mControl->unit()) { case OstProto::StreamControl::e_su_bursts: - numBursts = streamList[i]->mControl.num_bursts(); - numPackets = streamList[i]->mControl.packets_per_burst(); - ibg = 1000000/streamList[i]->mControl.bursts_per_sec(); + numBursts = streamList[i]->mControl->num_bursts(); + numPackets = streamList[i]->mControl->packets_per_burst(); + ibg = 1000000/streamList[i]->mControl->bursts_per_sec(); ipg = 0; break; case OstProto::StreamControl::e_su_packets: numBursts = 1; - numPackets = streamList[i]->mControl.num_packets(); + numPackets = streamList[i]->mControl->num_packets(); ibg = 0; - ipg = 1000000/streamList[i]->mControl.packets_per_sec(); + ipg = 1000000/streamList[i]->mControl->packets_per_sec(); break; default: qWarning("Unhandled stream control unit %d", - streamList[i]->mControl.unit()); + streamList[i]->mControl->unit()); continue; } qDebug("numBursts = %ld, numPackets = %ld\n", @@ -773,7 +672,7 @@ void PortInfo::update() } } // for (numBursts) - switch(streamList[i]->mControl.next()) + switch(streamList[i]->mControl->next()) { case ::OstProto::StreamControl::e_nw_stop: goto _stop_no_more_pkts; @@ -798,7 +697,7 @@ void PortInfo::update() default: qFatal("---------- %s: Unhandled case (%d) -----------", - __FUNCTION__, streamList[i]->mControl.next() ); + __FUNCTION__, streamList[i]->mControl->next() ); break; } @@ -1378,18 +1277,7 @@ const ::OstProto::StreamIdList* request, s = response->add_stream(); - s->mutable_stream_id()->CopyFrom( - portInfo[portIdx]->streamList[streamIndex]->mStreamId); - s->mutable_core()->CopyFrom( - portInfo[portIdx]->streamList[streamIndex]->mCore); - s->mutable_control()->CopyFrom( - portInfo[portIdx]->streamList[streamIndex]->mControl); - for (int j=0; j < portInfo[portIdx]->streamList[streamIndex]-> - mProtocolList.size(); j++) - { - portInfo[portIdx]->streamList[streamIndex]-> - mProtocolList[j]->protoDataCopyInto(*s); - } + portInfo[portIdx]->streamList[streamIndex]->protoDataCopyInto(*s); } _exit: @@ -1494,17 +1382,8 @@ const ::OstProto::StreamConfigList* request, if (streamIndex < 0) continue; // TODO(LOW): Partial status of RPC - portInfo[portIdx]->streamList[streamIndex]->mCore.clear_frame_proto(); - portInfo[portIdx]->streamList[streamIndex]->mCore.MergeFrom( - request->stream(i).core()); - portInfo[portIdx]->streamList[streamIndex]->mControl.MergeFrom( - request->stream(i).control()); - for (int j=0; j < portInfo[portIdx]->streamList[streamIndex]-> - mProtocolList.size(); j++) - { - portInfo[portIdx]->streamList[streamIndex]-> - mProtocolList[j]->protoDataCopyFrom(request->stream(i)); - } + portInfo[portIdx]->streamList[streamIndex]->protoDataCopyFrom( + request->stream(i)); // TODO(LOW): fill-in response "Ack"???? } diff --git a/server/myservice.h b/server/myservice.h index 6a662fd..7a4f331 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -8,7 +8,7 @@ #endif #include "../common/protocol.pb.h" -#include "../common/abstractprotocol.h" +#include "../common/streambase.h" #include "abstracthost.h" #include #include @@ -30,31 +30,19 @@ class MyService; -class StreamInfo +class StreamInfo : public StreamBase { friend class MyService; friend class PortInfo; OstProto::StreamId mStreamId; - OstProto::StreamCore mCore; - OstProto::StreamControl mControl; - QList mProtocolList; public: StreamInfo(); ~StreamInfo(); private: - AbstractProtocol* protocolById(int id); - - quint32 pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp, - quint8 protocol, quint16 len); - quint32 ipv4CksumPartial(uchar *buf, int len); - quint16 ipv4Cksum(uchar *buf, int len, quint32 partialSum = 0); int makePacket(uchar *buf, int bufMaxSize, int n); -public: - bool operator < (const StreamInfo &s) const - { return(mCore.ordinal() < s.mCore.ordinal()); } }; From 010369601604bdb7d921eabcb3cca6a9b8e26e22 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 24 May 2009 14:54:11 +0000 Subject: [PATCH 22/98] - AbstractProtocol - new method: fieldFlags() - isCksum, isMeta; Note: isMeta is a flag now not a attrib - fieldData() bit fields are now in lsb not msb - protocolFrameValue() and subclasses changed accordingly - protocolFrameValue() now takes an additional bool param indicating whether the frameValue is being requested for a checksum calculation; if so fields which are checksum fields are assumed to be zero and their value is not fetched to prevent infinite recursion - Other Protocols - mac: srcMac/dstMac modes is now working - vlan: implemented VLAN protocol - ip4: src/dst Addr modes is now working - udp/tcp: checksum done - Basic testing done for MAC, VLAN, IPv4, UDP and TCP protocols - sample protocol: .cpp/.h added to repos - need to be made compilable - StreamConfigDialog - Redesigned the protocol selection tab to accomodate "Advanced Protocol Selection" - L2 Tab config widgets are now in 2 columns - Packet Tree View is no longer collapsed if selected protocols don't change --- client/packetmodel.cpp | 7 +- client/portstatswindow.ui | 2 +- client/streamconfigdialog.cpp | 119 +++++-- client/streamconfigdialog.h | 6 +- client/streamconfigdialog.ui | 568 ++++++++++++++++++++++------------ common/abstractprotocol.cpp | 208 +++++++++---- common/abstractprotocol.h | 37 ++- common/dot3.ui | 4 +- common/ip4.cpp | 230 +++++++++++--- common/ip4.h | 7 +- common/ip4.ui | 6 +- common/mac.cpp | 98 ++++-- common/mac.h | 1 + common/mac.ui | 100 +++--- common/ostproto.pro | 4 + common/payload.cpp | 35 ++- common/payload.h | 3 + common/protocolmanager.cpp | 2 + common/protocolmanager.h | 1 + common/sample.cpp | 170 ++++++++++ common/sample.h | 56 ++++ common/snap.ui | 34 +- common/tcp.cpp | 105 +++++-- common/tcp.h | 13 +- common/udp.cpp | 73 ++++- common/udp.h | 1 + common/vlan.cpp | 229 ++++++++++++++ common/vlan.h | 62 ++++ common/vlan.proto | 8 +- common/vlan.ui | 311 ++++++++++--------- 30 files changed, 1862 insertions(+), 638 deletions(-) create mode 100644 common/sample.cpp create mode 100644 common/sample.h create mode 100644 common/vlan.cpp create mode 100644 common/vlan.h diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index f48f713..4dc4a31 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -10,8 +10,11 @@ PacketModel::PacketModel(const QList &selectedProtocols, void PacketModel::setSelectedProtocols( const QList &selectedProtocols) { - mSelectedProtocols = selectedProtocols; - reset(); + if (mSelectedProtocols != selectedProtocols) + { + mSelectedProtocols = selectedProtocols; + reset(); + } } int PacketModel::rowCount(const QModelIndex &parent) const diff --git a/client/portstatswindow.ui b/client/portstatswindow.ui index 07fe1b2..8c6aed4 100644 --- a/client/portstatswindow.ui +++ b/client/portstatswindow.ui @@ -16,7 +16,7 @@ - QFrame::StyledPanel + QFrame::Panel QFrame::Raised diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index b69ef67..eb6f76c 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -19,14 +19,24 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, setupUi(this); setupUiExtra(); - connect(bgFrameType, SIGNAL(buttonClicked(int)), - this, SLOT(updateSelectedProtocols())); + connect(bgFrameType, SIGNAL(buttonClicked(int)), + this, SLOT(updateContents())); connect(bgL3Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateSelectedProtocols())); + this, SLOT(updateContents())); connect(bgL4Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateSelectedProtocols())); + this, SLOT(updateContents())); + //! \todo causes a crash! +#if 0 + connect(lePktLen, SIGNAL(textEdited(QString)), + this, SLOT(updateContents())); +#endif + // Time to play match the signals and slots! + + // Enable VLAN Choices only if FT = Eth2 or SNAP + connect(rbFtNone, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); // Enable/Disable L3 Protocol Choices for FT None @@ -96,8 +106,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); // TODO(MED): - //! \todo Implement then enable these protocols + + //! \todo Implement then enable these protocols - SVLAN, ARP, ICMP, IGMP + cbSVlan->setHidden(true); rbL3Arp->setHidden(true); + rbL3Ipv6->setHidden(true); rbL4Icmp->setHidden(true); rbL4Igmp->setHidden(true); //! \todo Enable navigation of streams @@ -132,6 +145,8 @@ void StreamConfigDialog::setupUiExtra() } // ---- Setup default stuff that cannot be done in designer ---- + gbVlan->setDisabled(true); + bgFrameType = new QButtonGroup(); foreach(QRadioButton *btn, gbFrameType->findChildren()) bgFrameType->addButton(btn); @@ -151,7 +166,8 @@ void StreamConfigDialog::setupUiExtra() ** Setup Validators */ // Meta Data - lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); + //! \todo - doesn't seem to work - range validator needs a spinbox? + //lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); // L2 Ethernet #if 0 // Proto FW @@ -228,6 +244,9 @@ void StreamConfigDialog::updateSelectedProtocols() // Mac mSelectedProtocols.append(51); + if (cbCVlan->isEnabled() && cbCVlan->isChecked()) + mSelectedProtocols.append(126); + if (rbFtEthernet2->isChecked()) mSelectedProtocols.append(121); else if (rbFt802Dot3Raw->isChecked()) @@ -260,12 +279,13 @@ void StreamConfigDialog::updateSelectedProtocols() // Payload mSelectedProtocols.append(52); - - mpStream->setFrameProtocol(mSelectedProtocols); - mpStream->storeProtocolWidgets(); - mpStream->loadProtocolWidgets(); } +void StreamConfigDialog::updateContents() +{ + StoreCurrentStream(); + LoadCurrentStream(); +} void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode) { @@ -331,13 +351,12 @@ void StreamConfigDialog::on_twTopLevel_currentChanged(int index) if (index != 2) return; - updateSelectedProtocols(); + updateContents(); foreach(int i, mSelectedProtocols) if (mpStream->protocol(i)) protoList.append(mpStream->protocol(i)); mpPacketModel->setSelectedProtocols(protoList); - StoreCurrentStream(mpStream); } void StreamConfigDialog::on_twProto_currentChanged(int index) @@ -368,6 +387,8 @@ void StreamConfigDialog::on_twProto_currentChanged(int index) { case 1: // L2 wl.append(mpStream->protocol("mac")->configWidget()); + if (cbCVlan->isEnabled() && cbCVlan->isChecked()) + wl.append(mpStream->protocol("vlan")->configWidget()); if (rbFtEthernet2->isChecked()) wl.append(mpStream->protocol("eth2")->configWidget()); else if (rbFt802Dot3Raw->isChecked()) @@ -383,28 +404,63 @@ void StreamConfigDialog::on_twProto_currentChanged(int index) wl.append(mpStream->protocol("llc")->configWidget()); wl.append(mpStream->protocol("snap")->configWidget()); } + + { + int i, r = 0, c = 0; + QGridLayout *layout = new QGridLayout; + + Q_ASSERT(wl.size() > 0); + + // We use a 2 column layout for the L2 Tab + + layout->addWidget(wl.at(0), r, c, 1, -1); + r++; + for (i=1; i < wl.size(); i++) + { + layout->addWidget(wl.at(i), r, c); + if ((i % 2) == 0) + r++; + c = (c+1) % 2; + + } + if ((i % 2) == 0) + r++; + layout->setRowStretch(r, 10); + + twProto->widget(index)->setLayout(layout); + } break; case 2: // L3 if (rbL3Ipv4->isChecked()) wl.append(mpStream->protocol("ip4")->configWidget()); + + if (wl.size()) + { + QVBoxLayout *layout = new QVBoxLayout; + + for (int i=0; i < wl.size(); i++) + layout->addWidget(wl.at(i)); + + twProto->widget(index)->setLayout(layout); + } break; case 3: // L4 if (rbL4Tcp->isChecked()) wl.append(mpStream->protocol("tcp")->configWidget()); else if (rbL4Udp->isChecked()) wl.append(mpStream->protocol("udp")->configWidget()); + + if (wl.size()) + { + QVBoxLayout *layout = new QVBoxLayout; + + for (int i=0; i < wl.size(); i++) + layout->addWidget(wl.at(i)); + + twProto->widget(index)->setLayout(layout); + } break; } - - if (wl.size()) - { - layout = new QVBoxLayout; - - for (int i=0; i < wl.size(); i++) - layout->addWidget(wl.at(i)); - - twProto->widget(index)->setLayout(layout); - } } void StreamConfigDialog::update_NumPacketsAndNumBursts() @@ -464,6 +520,13 @@ void StreamConfigDialog::LoadCurrentStream() Q_ASSERT(mSelectedProtocols.at(i) == 51); // Mac i++; + // VLAN + if (mSelectedProtocols.at(i) == 126) // VLAN + { + cbCVlan->setChecked(true); + i++; + } + if (mSelectedProtocols.at(i) == 52) // Payload { i++; @@ -500,6 +563,7 @@ void StreamConfigDialog::LoadCurrentStream() else rbFtNone->setChecked(true); + // L3 if (mSelectedProtocols.at(i) == 52) // Payload { @@ -611,10 +675,11 @@ _proto_parse_done: } } -void StreamConfigDialog::StoreCurrentStream(Stream *pStream) +void StreamConfigDialog::StoreCurrentStream() { QString str; bool isOk; + Stream *pStream = mpStream; qDebug("storing pStream %p", pStream); @@ -660,9 +725,15 @@ void StreamConfigDialog::StoreCurrentStream(Stream *pStream) void StreamConfigDialog::on_pbOk_clicked() { + OstProto::Stream s; + // Store dialog contents into stream - StoreCurrentStream(mPort.streamByIndex(mCurrentStreamIndex)); + //updateSelectedProtocols(); + StoreCurrentStream(); + mpStream->protoDataCopyInto(s); + mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyFrom(s);; qDebug("stream stored"); + lastTopLevelTabIndex = twTopLevel->currentIndex(); lastProtoTabIndex = twProto->currentIndex(); } diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 75cae99..fa4aa82 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -49,15 +49,17 @@ private: static int lastProtoTabIndex; void setupUiExtra(); + void updateSelectedProtocols(); void LoadCurrentStream(); - void StoreCurrentStream(Stream *pStream); + void StoreCurrentStream(); private slots: void on_cmbPktLenMode_currentIndexChanged(QString mode); void on_pbPrev_clicked(); void on_pbNext_clicked(); - void updateSelectedProtocols(); + void updateContents(); + void on_twTopLevel_currentChanged(int index); void on_twProto_currentChanged(int index); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 9eba69a..d803e44 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,8 +8,8 @@ 0 0 - 590 - 517 + 636 + 589 @@ -29,8 +29,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff true - - + + @@ -98,11 +98,14 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff false + + 0099; + - 64 + - 32767 + 4 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -111,8 +114,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + - 64 + 32767 @@ -134,11 +140,14 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff false + + 0099; + - 64 + - 32767 + 4 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -157,187 +166,337 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff Protocols - - - - - Frame Type - - - - - - None - - - true - - - - - - - Ethernet II - - - false - - - - - - - 802.3 Raw - - - - - - - 802.3 LLC - - - false - - - - - - - LLC SNAP - - - - - + + + + + + + Frame Type + + + + + + None + + + true + + + + + + + Ethernet II + + + false + + + + + + + 802.3 Raw + + + + + + + 802.3 LLC + + + false + + + + + + + LLC SNAP + + + + + + + + + + true + + + VLAN + + + false + + + false + + + + + + true + + + CVLAN + + + + + + + true + + + SVLAN + + + + + + + + + + L3 + + + + + + None + + + true + + + + + + + false + + + IPv4 + + + false + + + + + + + false + + + IPv6 + + + + + + + false + + + ARP + + + + + + + false + + + Other + + + + + + + + + + L4 + + + + + + None + + + true + + + + + + + false + + + ICMP + + + + + + + false + + + IGMP + + + + + + + false + + + TCP + + + + + + + false + + + UDP + + + + + + + false + + + Other + + + + + + + + + + Qt::Vertical + + + + 182 + 16 + + + + + - - + + - L3 + Advanced Protocol Selection + + + true + + + false - - - None - - - true - - - - - - - false - - - IPv4 - - - false - - - - - - - false - - - ARP - - + + + + + + + Available Protocols + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + > + + + + + + + < + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Selected Protocols + + + + + + + + + - - - - L4 - - - - - - None - - - true - - - - - - - false - - - ICMP - - - - - - - false - - - IGMP - - - - - - - false - - - TCP - - - - - - - false - - - UDP - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -410,8 +569,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + - 1 + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -743,7 +905,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + @@ -820,8 +982,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff accept() - 440 - 466 + 496 + 552 533 @@ -836,8 +998,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff reject() - 523 - 466 + 579 + 552 533 @@ -852,12 +1014,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 281 - 137 + 158 + 149 - 281 - 169 + 158 + 149 @@ -868,12 +1030,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 30 - 66 + 59 + 120 - 30 - 266 + 59 + 149 @@ -884,12 +1046,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 30 - 91 + 59 + 123 - 30 - 312 + 59 + 149 @@ -900,12 +1062,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 30 - 91 + 59 + 123 - 134 - 177 + 145 + 149 diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 04d0d67..b48f5b1 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -92,7 +92,7 @@ int AbstractProtocol::fieldCount() const /*! Returns the number of meta fields \n The default implementation counts and returns the number of fields for which - fieldData(index, FieldIsMeta) return true\n + the FieldIsMeta flag is set\n The default implementation caches the count on its first invocation and subsequently returns the cached count */ int AbstractProtocol::metaFieldCount() const @@ -101,7 +101,7 @@ int AbstractProtocol::metaFieldCount() const { int c = 0; for (int i = 0; i < fieldCount() ; i++) - if (fieldData(i, FieldIsMeta).toBool()) + if (fieldFlags(i).testFlag(FieldIsMeta)) c++; metaCount = c; } @@ -117,6 +117,11 @@ int AbstractProtocol::frameFieldCount() const return (fieldCount() - metaFieldCount()); } +AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int index) const +{ + return FieldIsNormal; +} + /*! Returns the requested field attribute data \n Protocols which have meta fields that vary a frame field across streams may use the streamIndex to return the appropriate field value \n @@ -140,6 +145,9 @@ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString(); case FieldBitSize: + Q_ASSERT_X(!fieldFlags(index).testFlag(FieldIsCksum), + "AbstractProtocol::fieldData()", + "FieldBitSize for checksum fields need to be handled by the subclass"); return fieldData(index, FieldFrameValue, streamIndex). toByteArray().size() * 8; case FieldValue: @@ -148,8 +156,6 @@ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, return QByteArray(); case FieldTextValue: return QString(); - case FieldIsMeta: - return false; default: qFatal("%s:%d: unhandled case %d\n", __FUNCTION__, __LINE__, @@ -196,7 +202,7 @@ int AbstractProtocol::protocolFrameSize() const for (int i = 0; i < fieldCount(); i++) { - if (!fieldData(i, FieldIsMeta).toBool()) + if (!fieldFlags(i).testFlag(FieldIsMeta)) bitsize += fieldData(i, FieldBitSize).toUInt(); } protoSize = (bitsize+7)/8; @@ -248,23 +254,30 @@ int AbstractProtocol::protocolFramePayloadSize() const The default implementation forms and returns an ordered concatenation of the FrameValue of all the 'frame' fields of the protocol taking care of fields which are not an integral number of bytes\n */ -QByteArray AbstractProtocol::protocolFrameValue(int streamIndex) const +QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) const { QByteArray proto, field; - int bits, lastbitpos = 0; + uint bits, lastbitpos = 0; + FieldFlags flags; for (int i=0; i < fieldCount() ; i++) { - if (!fieldData(i, FieldIsMeta).toBool()) + flags = fieldFlags(i); + if (!flags.testFlag(FieldIsMeta)) { - field = fieldData(i, FieldFrameValue, streamIndex).toByteArray(); bits = fieldData(i, FieldBitSize, streamIndex).toUInt(); - if (bits == 0) - continue; + Q_ASSERT(bits > 0); - qDebug("<<< %d, %d >>>>", proto.size(), field.size()); + if (forCksum && flags.testFlag(FieldIsCksum)) + { + field.resize((bits+7)/8); + field.fill('\0'); + } + else + field = fieldData(i, FieldFrameValue, streamIndex).toByteArray(); + qDebug("<<< %d, %d/%d >>>>", proto.size(), bits, field.size()); - if (bits == field.size() * 8) + if (bits == (uint) field.size() * 8) { if (lastbitpos == 0) proto.append(field); @@ -279,28 +292,44 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex) const field.at(j+1) >> lastbitpos); } } - else if (bits < field.size() * 8) + else if (bits < (uint) field.size() * 8) { - int u, v; + uchar c; + uint v; + + v = (field.size()*8) - bits; + + Q_ASSERT(v < 8); - u = bits / 8; - v = bits % 8; if (lastbitpos == 0) { - proto.append(field.left(u+1)); - char c = proto[proto.size() - 1]; - proto[proto.size() - 1] = c & (0xFF << (8 - v)); - lastbitpos = v; + for (int j = 0; j < field.size(); j++) + { + c = field.at(j) << v; + if ((j+1) < field.size()) + c |= ((uchar)field.at(j+1) >> (8-v)); + proto.append(c); + } + + lastbitpos = (lastbitpos + bits) % 8; } else { - char c = proto[proto.size() - 1]; - proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos); - for (int j = 0; j < (u - 1); j++) - proto.append(field.at(j) << lastbitpos | - field.at(j+1) >> lastbitpos); - if (u) - proto.append( field.at(u) & (0xFF << (8 - v)) ); + Q_ASSERT(proto.size() > 0); + + for (int j = 0; j < field.size(); j++) + { + uchar d; + + c = field.at(j) << v; + if ((j+1) < field.size()) + c |= ((uchar) field.at(j+1) >> (8-v)); + d = proto[proto.size() - 1]; + proto[proto.size() - 1] = d | ((uchar) c >> lastbitpos); + if (bits > (8*j + (8 - v))) + proto.append(c << (8-lastbitpos)); + } + lastbitpos = (lastbitpos + bits) % 8; } } @@ -315,53 +344,124 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex) const return proto; } -QVariant AbstractProtocol::protocolFrameCksum() const +/*! + \note If a subclass uses protocolFrameCksum() from within fieldData() to + derive a cksum field, it MUST handle and return the 'FieldBitSize' + attribute also for that particular field instead of using the default + AbstractProtocol implementation for 'FieldBitSize' - this is required + to prevent infinite recursion + */ +quint32 AbstractProtocol::protocolFrameCksum(int streamIndex, + CksumType cksumType) const { - QByteArray fv; - quint16 *ip; - quint32 len, sum = 0; + static int recursionCount = 0; + quint32 cksum = 0; - fv = protocolFrameValue(-1); - ip = (quint16*) fv.constData(); - len = fv.size(); + recursionCount++; + Q_ASSERT_X(recursionCount < 10, "protocolFrameCksum", "potential infinite recursion - does a protocol checksum field not implement FieldBitSize?"); - while(len > 1) + switch(cksumType) { - sum += *ip; - if(sum & 0x80000000) - sum = (sum & 0xFFFF) + (sum >> 16); - ip++; - len -= 2; + case CksumIp: + { + QByteArray fv; + quint16 *ip; + quint32 len, sum = 0; + + fv = protocolFrameValue(streamIndex, true); + ip = (quint16*) fv.constData(); + len = fv.size(); + + while(len > 1) + { + sum += *ip; + if(sum & 0x80000000) + sum = (sum & 0xFFFF) + (sum >> 16); + ip++; + len -= 2; + } + + if (len) + sum += (unsigned short) *(unsigned char *)ip; + + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); + + cksum = qFromBigEndian((quint16) ~sum); + break; + } + + case CksumTcpUdp: + { + quint16 cks; + quint32 sum = 0; + + cks = protocolFrameCksum(streamIndex, CksumIp); + sum += (quint16) ~cks; + cks = protocolFramePayloadCksum(streamIndex, CksumIp); + sum += (quint16) ~cks; + cks = protocolFrameHeaderCksum(streamIndex, CksumIpPseudo); + sum += (quint16) ~cks; + + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); + + cksum = (~sum) & 0xFFFF; + break; + } + default: + break; } - if (len) - sum += (unsigned short) *(unsigned char *)ip; + recursionCount--; + return cksum; +} + +quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, + CksumType cksumType) const +{ + quint32 sum = 0xFFFF; + QLinkedListIterator iter(frameProtocols); + + Q_ASSERT(cksumType == CksumIpPseudo); + + if (iter.findNext(this)) + { + iter.previous(); + if (iter.hasPrevious()) + sum = iter.previous()->protocolFrameCksum(streamIndex, + CksumIpPseudo); + } while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); - return qFromBigEndian((quint16) ~sum); + return (quint16) ~sum; } -QVariant AbstractProtocol::protocolFramePayloadCksum() const +quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, + CksumType cksumType) const { - int cksum = 0; + quint32 sum = 0; + quint16 cksum; QLinkedListIterator iter(frameProtocols); + Q_ASSERT(cksumType == CksumIp); + if (iter.findNext(this)) { while (iter.hasNext()) - cksum += iter.next()->protocolFrameCksum().toUInt(); // TODO: chg to partial + { + cksum = iter.next()->protocolFrameCksum(streamIndex, CksumIp); + sum += (quint16) ~cksum; + } } else - return -1; -#if 0 - while(cksum>>16) - cksum = (cksum & 0xFFFF) + (cksum >> 16); + return 0; - return (quint16) ~cksum; -#endif + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); - return cksum; + return (quint16) ~sum; } diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index ec0584b..bbe8325 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -6,6 +6,7 @@ #include #include #include +#include //#include "../rpc/pbhelper.h" #include "../common/protocol.pb.h" @@ -35,13 +36,19 @@ protected: ProtocolList &frameProtocols; public: + enum FieldFlag { + FieldIsNormal = 0x0, + FieldIsMeta = 0x1, + FieldIsCksum = 0x2 + }; + Q_DECLARE_FLAGS(FieldFlags, FieldFlag); + enum FieldAttrib { FieldName, //! name FieldValue, //! value in host byte order (user editable) FieldTextValue, //! value as text FieldFrameValue, //! frame encoded value in network byte order FieldBitSize, //! size in bits - FieldIsMeta //! bool indicating if field is meta }; enum ProtocolIdType { @@ -50,6 +57,14 @@ public: ProtocolIdIp, }; + enum CksumType { + CksumIp, + CksumIpPseudo, + CksumTcpUdp, + + CksumMax + }; + AbstractProtocol(ProtocolList &frameProtoList, OstProto::StreamCore *parent = 0); virtual ~AbstractProtocol(); @@ -71,22 +86,30 @@ public: virtual int metaFieldCount() const; int frameFieldCount() const; + virtual FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; + int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + FieldAttrib attrib = FieldValue); - QByteArray protocolFrameValue(int streamIndex = 0) const; - int protocolFrameSize() const; + QByteArray protocolFrameValue(int streamIndex = 0, + bool forCksum = false) const; + virtual int protocolFrameSize() const; int protocolFrameOffset() const; int protocolFramePayloadSize() const; - virtual QVariant protocolFrameCksum() const; - QVariant protocolFramePayloadCksum() const; + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFrameHeaderCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFramePayloadCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; virtual QWidget* configWidget() = 0; virtual void loadConfigWidget() = 0; virtual void storeConfigWidget() = 0; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractProtocol::FieldFlags); + #endif diff --git a/common/dot3.ui b/common/dot3.ui index d452bd0..7473ee2 100644 --- a/common/dot3.ui +++ b/common/dot3.ui @@ -46,8 +46,8 @@ - 40 - 20 + 16 + 54 diff --git a/common/ip4.cpp b/common/ip4.cpp index 260c720..59a6773 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -10,10 +10,12 @@ Ip4ConfigForm::Ip4ConfigForm(QWidget *parent) { setupUi(this); + leIpVersion->setValidator(new QIntValidator(0, 15, this)); + connect(cmbIpSrcAddrMode, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_cmbIpSrcAddrMode_currentIndexChanged(int))); + this, SLOT(on_cmbIpSrcAddrMode_currentIndexChanged(int))); connect(cmbIpDstAddrMode, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_cmbIpDstAddrMode_currentIndexChanged(int))); + this, SLOT(on_cmbIpDstAddrMode_currentIndexChanged(int))); } void Ip4ConfigForm::on_cmbIpSrcAddrMode_currentIndexChanged(int index) @@ -110,45 +112,104 @@ int Ip4Protocol::fieldCount() const return ip4_fieldCount; } +AbstractProtocol::FieldFlags Ip4Protocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case ip4_ver: + case ip4_hdrLen: + case ip4_tos: + case ip4_totLen: + case ip4_id: + case ip4_flags: + case ip4_fragOfs: + case ip4_ttl: + case ip4_proto: + break; + + case ip4_cksum: + flags |= FieldIsCksum; + break; + + case ip4_srcAddr: + case ip4_dstAddr: + break; + + case ip4_isOverrideVer: + case ip4_isOverrideHdrLen: + case ip4_isOverrideTotLen: + case ip4_isOverrideCksum: + case ip4_srcAddrMode: + case ip4_srcAddrCount: + case ip4_srcAddrMask: + case ip4_dstAddrMode: + case ip4_dstAddrCount: + case ip4_dstAddrMask: + flags |= FieldIsMeta; + break; + + default: + break; + } + + return flags; +} + QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { switch (index) { case ip4_ver: + { + int ver; + + ver = data.is_override_ver() ? (data.ver_hdrlen() >> 4) & 0x0F : 4; + switch(attrib) { case FieldName: return QString("Version"); case FieldValue: - return (data.ver_hdrlen() >> 4) & 0x0F; + return ver; case FieldTextValue: - return QString("%1").arg((data.ver_hdrlen() >> 4) & 0x0F); + return QString("%1").arg(ver, 1, BASE_HEX, QChar('0')); case FieldFrameValue: - return QByteArray(1, (char)(data.ver_hdrlen() & 0xF0)); + return QByteArray(1, (char) ver); case FieldBitSize: return 4; default: break; } break; + } case ip4_hdrLen: + { + int hdrlen; + + hdrlen = data.is_override_hdrlen() ? data.ver_hdrlen() & 0x0F : 5; + switch(attrib) { case FieldName: return QString("Header Length"); case FieldValue: - return data.ver_hdrlen() & 0x0F; + return hdrlen; case FieldTextValue: - return QString("%1").arg(data.ver_hdrlen() & 0x0F); + return QString("%1").arg(hdrlen, 1, BASE_HEX, QChar('0')); case FieldFrameValue: - return QByteArray(1, (char)(data.ver_hdrlen() << 4)); + return QByteArray(1, (char) hdrlen); case FieldBitSize: return 4; default: break; } break; + } case ip4_tos: switch(attrib) { @@ -261,11 +322,12 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, QByteArray fv; // FIXME need to shift for 13 bits fv.resize(2); - qToBigEndian((quint16) data.frag_ofs(), (uchar*) fv.data()); + qToBigEndian((quint16) (data.frag_ofs()), + (uchar*) fv.data()); return fv; } case FieldTextValue: - return QString("%1").arg(data.frag_ofs()); + return QString("%1").arg(data.frag_ofs()*8); case FieldBitSize: return 13; default: @@ -316,7 +378,6 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, } case ip4_cksum: { - switch(attrib) { case FieldName: @@ -325,12 +386,10 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, { quint16 cksum; - if (streamIndex < 0) - cksum = 0; - else if (data.is_override_cksum()) + if (data.is_override_cksum()) cksum = data.cksum(); else - cksum = protocolFrameCksum().toUInt(); + cksum = protocolFrameCksum(streamIndex, CksumIp); return cksum; } case FieldFrameValue: @@ -338,12 +397,11 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, QByteArray fv; quint16 cksum; - if (streamIndex < 0) - cksum = 0; - else if (data.is_override_cksum()) + if (data.is_override_cksum()) cksum = data.cksum(); else - cksum = protocolFrameCksum().toUInt(); + cksum = protocolFrameCksum(streamIndex, CksumIp); + fv.resize(2); qToBigEndian((quint16) cksum, (uchar*) fv.data()); return fv; @@ -352,12 +410,10 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, { quint16 cksum; - if (streamIndex < 0) - cksum = 0; - else if (data.is_override_cksum()) + if (data.is_override_cksum()) cksum = data.cksum(); else - cksum = protocolFrameCksum().toUInt(); + cksum = protocolFrameCksum(streamIndex, CksumIp); return QString("0x%1"). arg(cksum, 4, BASE_HEX, QChar('0'));; } @@ -369,46 +425,111 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, break; } case ip4_srcAddr: + { + int u; + quint32 subnet, host, srcIp = 0; + + switch(data.src_ip_mode()) + { + case OstProto::Ip4::e_im_fixed: + srcIp = data.src_ip(); + break; + case OstProto::Ip4::e_im_inc_host: + u = streamIndex % data.src_ip_count(); + subnet = data.src_ip() & data.src_ip_mask(); + host = (((data.src_ip() & ~data.src_ip_mask()) + u) & + ~data.src_ip_mask()); + srcIp = subnet | host; + break; + case OstProto::Ip4::e_im_dec_host: + u = streamIndex % data.src_ip_count(); + subnet = data.src_ip() & data.src_ip_mask(); + host = (((data.src_ip() & ~data.src_ip_mask()) - u) & + ~data.src_ip_mask()); + srcIp = subnet | host; + break; + case OstProto::Ip4::e_im_random_host: + subnet = data.src_ip() & data.src_ip_mask(); + host = (qrand() & ~data.src_ip_mask()); + srcIp = subnet | host; + break; + default: + qWarning("Unhandled src_ip_mode = %d", data.src_ip_mode()); + } + switch(attrib) { case FieldName: return QString("Source"); case FieldValue: - return data.src_ip(); + return srcIp; case FieldFrameValue: { QByteArray fv; fv.resize(4); - qToBigEndian((quint32) data.src_ip(), (uchar*) fv.data()); + qToBigEndian(srcIp, (uchar*) fv.data()); return fv; } case FieldTextValue: - return QHostAddress(data.src_ip()).toString(); + return QHostAddress(srcIp).toString(); default: break; } break; + } case ip4_dstAddr: + { + int u; + quint32 subnet, host, dstIp = 0; + + switch(data.dst_ip_mode()) + { + case OstProto::Ip4::e_im_fixed: + dstIp = data.dst_ip(); + break; + case OstProto::Ip4::e_im_inc_host: + u = streamIndex % data.dst_ip_count(); + subnet = data.dst_ip() & data.dst_ip_mask(); + host = (((data.dst_ip() & ~data.dst_ip_mask()) + u) & + ~data.dst_ip_mask()); + dstIp = subnet | host; + break; + case OstProto::Ip4::e_im_dec_host: + u = streamIndex % data.dst_ip_count(); + subnet = data.dst_ip() & data.dst_ip_mask(); + host = (((data.dst_ip() & ~data.dst_ip_mask()) - u) & + ~data.dst_ip_mask()); + dstIp = subnet | host; + break; + case OstProto::Ip4::e_im_random_host: + subnet = data.dst_ip() & data.dst_ip_mask(); + host = (qrand() & ~data.dst_ip_mask()); + dstIp = subnet | host; + break; + default: + qWarning("Unhandled dst_ip_mode = %d", data.dst_ip_mode()); + } + switch(attrib) { case FieldName: return QString("Destination"); case FieldValue: - return data.dst_ip(); + return dstIp; case FieldFrameValue: { QByteArray fv; fv.resize(4); - qToBigEndian((quint32) data.dst_ip(), (uchar*) fv.data()); + qToBigEndian((quint32) dstIp, (uchar*) fv.data()); return fv; } case FieldTextValue: - return QHostAddress(data.dst_ip()).toString(); + return QHostAddress(dstIp).toString(); default: break; } break; - + } // Meta fields case ip4_isOverrideVer: @@ -423,15 +544,6 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, case ip4_dstAddrMode: case ip4_dstAddrCount: case ip4_dstAddrMask: - switch(attrib) - { - case FieldIsMeta: - return true; - default: - break; - } - break; - default: break; } @@ -461,6 +573,34 @@ bool Ip4Protocol::setFieldData(int index, const QVariant &value, return isOk; } +quint32 Ip4Protocol::protocolFrameCksum(int streamIndex, + CksumType cksumType) const +{ + switch (cksumType) + { + case CksumIpPseudo: + { + quint32 sum; + + sum = fieldData(ip4_srcAddr, FieldValue, streamIndex).toUInt() >> 16; + sum += fieldData(ip4_srcAddr, FieldValue, streamIndex).toUInt() & 0xFFFF; + sum += fieldData(ip4_dstAddr, FieldValue, streamIndex).toUInt() >> 16; + sum += fieldData(ip4_dstAddr, FieldValue, streamIndex).toUInt() & 0xFFFF; + + sum += fieldData(ip4_proto, FieldValue, streamIndex).toUInt() & 0x00FF; + sum += (fieldData(ip4_totLen, FieldValue, streamIndex).toUInt() & 0xFFFF) - 20; + + // Above calculation done assuming 'big endian' + // - so convert to host order + //return qFromBigEndian(sum); + return sum; + } + default: + break; + } + + return AbstractProtocol::protocolFrameCksum(streamIndex, cksumType); +} QWidget* Ip4Protocol::configWidget() { @@ -469,15 +609,16 @@ QWidget* Ip4Protocol::configWidget() void Ip4Protocol::loadConfigWidget() { - configForm->leIpVersion->setText(QString().setNum(data.ver_hdrlen() >> 4)); configForm->cbIpVersionOverride->setChecked(data.is_override_ver()); + configForm->leIpVersion->setText(fieldData(ip4_ver, FieldValue).toString()); - configForm->leIpHdrLen->setText(QString().setNum(data.ver_hdrlen() & 0x0F)); configForm->cbIpHdrLenOverride->setChecked(data.is_override_hdrlen()); + configForm->leIpHdrLen->setText(fieldData(ip4_hdrLen, FieldValue).toString()); configForm->leIpTos->setText(uintToHexStr(data.tos(), 1)); - configForm->leIpLength->setText(fieldData(ip4_totLen, FieldValue).toString()); + configForm->cbIpLengthOverride->setChecked(data.is_override_totlen()); + configForm->leIpLength->setText(fieldData(ip4_totLen, FieldValue).toString()); configForm->leIpId->setText(uintToHexStr(data.id(), 2)); configForm->leIpFragOfs->setText(QString().setNum(data.frag_ofs())); @@ -488,9 +629,9 @@ void Ip4Protocol::loadConfigWidget() configForm->leIpProto->setText(uintToHexStr( fieldData(ip4_proto, FieldValue).toUInt(), 1)); + configForm->cbIpCksumOverride->setChecked(data.is_override_cksum()); configForm->leIpCksum->setText(uintToHexStr( fieldData(ip4_cksum, FieldValue).toUInt(), 2)); - configForm->cbIpCksumOverride->setChecked(data.is_override_cksum()); configForm->leIpSrcAddr->setText(QHostAddress(data.src_ip()).toString()); configForm->cmbIpSrcAddrMode->setCurrentIndex(data.src_ip_mode()); @@ -528,8 +669,8 @@ void Ip4Protocol::storeConfigWidget() data.set_ttl(configForm->leIpTtl->text().toULong(&isOk)); data.set_proto(configForm->leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16)); - data.set_cksum(configForm->leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); data.set_is_override_cksum(configForm->cbIpCksumOverride->isChecked()); + data.set_cksum(configForm->leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); data.set_src_ip(QHostAddress(configForm->leIpSrcAddr->text()).toIPv4Address()); data.set_src_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpSrcAddrMode->currentIndex()); @@ -539,5 +680,6 @@ void Ip4Protocol::storeConfigWidget() data.set_dst_ip(QHostAddress(configForm->leIpDstAddr->text()).toIPv4Address()); data.set_dst_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpDstAddrMode->currentIndex()); data.set_dst_ip_count(configForm->leIpDstAddrCount->text().toULong(&isOk)); + data.set_dst_ip_mask(QHostAddress(configForm->leIpDstAddrMask->text()).toIPv4Address()); } diff --git a/common/ip4.h b/common/ip4.h index 1bf8ccc..9c20936 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -6,9 +6,9 @@ #include "ip4.pb.h" #include "ui_ip4.h" -#define IP_FLAG_UNUSED 0x1 +#define IP_FLAG_MF 0x1 #define IP_FLAG_DF 0x2 -#define IP_FLAG_MF 0x4 +#define IP_FLAG_UNUSED 0x4 class Ip4ConfigForm : public QWidget, public Ui::ip4 @@ -74,10 +74,13 @@ public: virtual quint32 protocolId(ProtocolIdType type) const; virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; virtual QWidget* configWidget(); virtual void loadConfigWidget(); diff --git a/common/ip4.ui b/common/ip4.ui index 785e7e3..a3135e7 100644 --- a/common/ip4.ui +++ b/common/ip4.ui @@ -5,7 +5,7 @@ 0 0 - 504 + 527 296 @@ -35,7 +35,7 @@ - Override Header Length + Override Header Length (x4) @@ -118,7 +118,7 @@ - Fragment Offset + Fragment Offset (x8) diff --git a/common/mac.cpp b/common/mac.cpp index 53defa7..1adc9ca 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -94,26 +94,73 @@ int MacProtocol::fieldCount() const return mac_fieldCount; } +AbstractProtocol::FieldFlags MacProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case mac_dstAddr: + case mac_srcAddr: + break; + + case mac_dstMacMode: + case mac_dstMacCount: + case mac_dstMacStep: + case mac_srcMacMode: + case mac_srcMacCount: + case mac_srcMacStep: + flags |= FieldIsMeta; + break; + } + + return flags; +} + QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { switch (index) { case mac_dstAddr: + { + int u; + quint64 dstMac = 0; + + switch (data.dst_mac_mode()) + { + case OstProto::Mac::e_mm_fixed: + dstMac = data.dst_mac(); + break; + case OstProto::Mac::e_mm_inc: + u = (streamIndex % data.dst_mac_count()) * + data.dst_mac_step(); + dstMac = data.dst_mac() + u; + break; + case OstProto::Mac::e_mm_dec: + u = (streamIndex % data.dst_mac_count()) * + data.dst_mac_step(); + dstMac = data.dst_mac() - u; + break; + default: + qWarning("Unhandled dstMac_mode %d", data.dst_mac_mode()); + } + switch(attrib) { case FieldName: return QString("Desination"); case FieldValue: - return data.dst_mac(); + return dstMac; case FieldTextValue: - return QString("%1").arg(data.dst_mac(), 12, BASE_HEX, - QChar('0')); + return uintToHexStr(dstMac, 6); case FieldFrameValue: { QByteArray fv; fv.resize(8); - qToBigEndian((quint64) data.dst_mac(), (uchar*) fv.data()); + qToBigEndian(dstMac, (uchar*) fv.data()); fv.remove(0, 2); return fv; } @@ -121,22 +168,44 @@ QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, break; } break; - + } case mac_srcAddr: + { + int u; + quint64 srcMac = 0; + + switch (data.src_mac_mode()) + { + case OstProto::Mac::e_mm_fixed: + srcMac = data.src_mac(); + break; + case OstProto::Mac::e_mm_inc: + u = (streamIndex % data.src_mac_count()) * + data.src_mac_step(); + srcMac = data.src_mac() + u; + break; + case OstProto::Mac::e_mm_dec: + u = (streamIndex % data.src_mac_count()) * + data.src_mac_step(); + srcMac = data.src_mac() - u; + break; + default: + qWarning("Unhandled srcMac_mode %d", data.src_mac_mode()); + } + switch(attrib) { case FieldName: return QString("Source"); case FieldValue: - return data.src_mac(); + return srcMac; case FieldTextValue: - return QString("%1").arg(data.src_mac(), 12, BASE_HEX, - QChar('0')); + return uintToHexStr(srcMac, 6); case FieldFrameValue: { QByteArray fv; fv.resize(8); - qToBigEndian((quint64) data.src_mac(), (uchar*) fv.data()); + qToBigEndian(srcMac, (uchar*) fv.data()); fv.remove(0, 2); return fv; } @@ -144,7 +213,7 @@ QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, break; } break; - + } // Meta fields case mac_dstMacMode: case mac_dstMacCount: @@ -152,15 +221,6 @@ QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, case mac_srcMacMode: case mac_srcMacCount: case mac_srcMacStep: - switch(attrib) - { - case FieldIsMeta: - return true; - default: - break; - } - break; - default: break; } diff --git a/common/mac.h b/common/mac.h index 575b9b1..84199a5 100644 --- a/common/mac.h +++ b/common/mac.h @@ -55,6 +55,7 @@ public: virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, diff --git a/common/mac.ui b/common/mac.ui index 9afb006..ca1350e 100644 --- a/common/mac.ui +++ b/common/mac.ui @@ -5,8 +5,8 @@ 0 0 - 423 - 144 + 512 + 98 @@ -19,28 +19,14 @@ MAC - - - - Mode - - - - - - - Step - - - - + Destination - + @@ -56,7 +42,14 @@ - + + + + Mode + + + + @@ -75,7 +68,14 @@ - + + + + Count + + + + false @@ -88,7 +88,14 @@ - + + + + Step + + + + false @@ -101,14 +108,14 @@ - + Source - + >HH HH HH HH HH HH; @@ -118,7 +125,14 @@ - + + + + Mode + + + + @@ -137,7 +151,14 @@ - + + + + Count + + + + false @@ -147,7 +168,14 @@ - + + + + Step + + + + false @@ -160,29 +188,9 @@ - - - - Count - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - diff --git a/common/ostproto.pro b/common/ostproto.pro index 59b2453..192049f 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -10,6 +10,7 @@ FORMS += \ dot3.ui \ llc.ui \ snap.ui \ + vlan.ui \ ip4.ui \ tcp.ui \ udp.ui @@ -21,6 +22,7 @@ PROTOS += \ dot3.proto \ llc.proto \ snap.proto \ + vlan.proto \ ip4.proto \ tcp.proto \ udp.proto @@ -35,6 +37,7 @@ HEADERS += \ dot3.h \ llc.h \ snap.h \ + vlan.h \ ip4.h \ tcp.h \ udp.h @@ -49,6 +52,7 @@ SOURCES += \ dot3.cpp \ llc.cpp \ snap.cpp \ + vlan.cpp \ ip4.cpp \ tcp.cpp \ udp.cpp diff --git a/common/payload.cpp b/common/payload.cpp index 8e79c7d..ecaef9b 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -74,11 +74,36 @@ QString PayloadProtocol::shortName() const return QString("DATA"); } +int PayloadProtocol::protocolFrameSize() const +{ + return (stream->frame_len() - protocolFrameOffset() - SZ_FCS); +} + int PayloadProtocol::fieldCount() const { return payload_fieldCount; } +AbstractProtocol::FieldFlags PayloadProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case payload_dataPattern: + break; + + // Meta fields + case payload_dataPatternMode: + flags |= FieldIsMeta; + break; + } + + return flags; +} + QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { @@ -118,6 +143,7 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, fv[i] = 0xFF - (i % (0xFF + 1)); break; case OstProto::Payload::e_dp_random: + //! \todo cksum will be incorrect for random pattern for (int i = 0; i < dataLen; i++) fv[i] = qrand() % (0xFF + 1); break; @@ -136,15 +162,6 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, // Meta fields case payload_dataPatternMode: - switch(attrib) - { - case FieldIsMeta: - return true; - default: - break; - } - break; - default: break; } diff --git a/common/payload.h b/common/payload.h index 4a1dc03..34e9a01 100644 --- a/common/payload.h +++ b/common/payload.h @@ -45,8 +45,11 @@ public: virtual QString name() const; virtual QString shortName() const; + virtual int protocolFrameSize() const; + virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 7b49e33..9041adc 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -7,6 +7,7 @@ #include "dot3.h" #include "llc.h" #include "snap.h" +#include "vlan.h" #include "ip4.h" #include "tcp.h" #include "udp.h" @@ -24,6 +25,7 @@ ProtocolManager::ProtocolManager() registerProtocol(122, QString("dot3"), (void*) Dot3Protocol::createInstance); registerProtocol(123, QString("llc"), (void*) LlcProtocol::createInstance); registerProtocol(124, QString("snap"), (void*) SnapProtocol::createInstance); + registerProtocol(126, QString("vlan"), (void*) VlanProtocol::createInstance); registerProtocol(130, QString("ip4"), (void*) Ip4Protocol::createInstance); registerProtocol(140, QString("tcp"), (void*) TcpProtocol::createInstance); registerProtocol(141, QString("udp"), (void*) UdpProtocol::createInstance); diff --git a/common/protocolmanager.h b/common/protocolmanager.h index 5d8e1ca..de602fc 100644 --- a/common/protocolmanager.h +++ b/common/protocolmanager.h @@ -6,6 +6,7 @@ class ProtocolManager { public: + //! \todo Make these data structures private/protected static QMap nameToNumberMap; static QMap factory; diff --git a/common/sample.cpp b/common/sample.cpp new file mode 100644 index 0000000..e92c9fc --- /dev/null +++ b/common/sample.cpp @@ -0,0 +1,170 @@ +#include +#include + +#include "sample.h" + +SampleConfigForm *SampleProtocol::configForm = NULL; + +SampleConfigForm::SampleConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + +} + +SampleProtocol::SampleProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) +{ + if (configForm == NULL) + configForm = new SampleConfigForm; +} + +SampleProtocol::~SampleProtocol() +{ +} + +AbstractProtocol* SampleProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new SampleProtocol(frameProtoList, streamCore); +} + +void SampleProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::sample)->CopyFrom(data); +} + +void SampleProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::sample)) + data.MergeFrom(stream.GetExtension(OstProto::sample)); +} + +QString SampleProtocol::name() const +{ + return QString("Sample"); +} + +QString SampleProtocol::shortName() const +{ + return QString("Sample"); +} + +int SampleProtocol::fieldCount() const +{ + return sample_fieldCount; +} + +AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case sample_normal: + break; + + case sample_cksum: + flags |= FieldIsCksum; + break; + + case sample_meta: + flags |= FieldIsMeta; + break; + + default: + break; + } + + return flags; +} + +QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case sample_FIXME: + { + switch(attrib) + { + case FieldName: + return QString("FIXME"); + case FieldValue: + return data.FIXME(); + case FieldTextValue: + return QString("%1").arg(data.FIXME()); + case FieldFrameValue: + return QByteArray(1, (char)(data.FIXME() & 0xF0)); + case FieldBitSize: + return 4; + default: + break; + } + break; + + } + case sample_FIXME: + { + switch(attrib) + { + case FieldName: + return QString("FIXME"); + case FieldValue: + return FIXME; + case FieldTextValue: + return QString("%1").arg(FIXME); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(0); + qToBigEndian(FIXME, (uchar*) fv.data()); + return fv; + } + return QByteArray(1, (char)(FIXME() & 0xF0)); + case FieldBitSize: + return 4; + default: + break; + } + break; + } + // Meta fields + + case sample_FIXME: + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool SampleProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* SampleProtocol::configWidget() +{ + return configForm; +} + +void SampleProtocol::loadConfigWidget() +{ +} + +void SampleProtocol::storeConfigWidget() +{ + bool isOk; +} + diff --git a/common/sample.h b/common/sample.h new file mode 100644 index 0000000..9da187d --- /dev/null +++ b/common/sample.h @@ -0,0 +1,56 @@ +#ifndef _SAMPLE_H +#define _SAMPLE_H + +#include "abstractprotocol.h" + +#include "sample.pb.h" +#include "ui_sample.h" + +class SampleConfigForm : public QWidget, public Ui::Sample +{ + Q_OBJECT +public: + SampleConfigForm(QWidget *parent = 0); +private slots: +}; + +class SampleProtocol : public AbstractProtocol +{ +private: + OstProto::Sample data; + static SampleConfigForm *configForm; + enum samplefield + { + + sample_fieldCount + }; + +public: + SampleProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); + virtual ~SampleProtocol(); + + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/snap.ui b/common/snap.ui index 9d0e4a5..80997bd 100644 --- a/common/snap.ui +++ b/common/snap.ui @@ -5,15 +5,15 @@ 0 0 - 293 - 98 + 194 + 72 Form - - + + SNAP @@ -56,32 +56,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/common/tcp.cpp b/common/tcp.cpp index 26b14c0..ab13d54 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -70,6 +70,43 @@ int TcpProtocol::fieldCount() const return tcp_fieldCount; } +AbstractProtocol::FieldFlags TcpProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case tcp_src_port: + case tcp_dst_port: + case tcp_seq_num: + case tcp_ack_num: + case tcp_hdrlen: + case tcp_rsvd: + case tcp_flags: + case tcp_window: + break; + + case tcp_cksum: + flags |= FieldIsCksum; + break; + + case tcp_urg_ptr: + break; + + case tcp_is_override_hdrlen: + case tcp_is_override_cksum: + flags |= FieldIsMeta; + break; + + default: + break; + } + + return flags; +} + QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { @@ -142,7 +179,7 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, switch(attrib) { case FieldName: - return QString("Sequence Number"); + return QString("Acknowledgement Number"); case FieldValue: return data.ack_num(); case FieldTextValue: @@ -165,11 +202,22 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString("Header Length"); case FieldValue: - return ((data.hdrlen_rsvd() >> 4) & 0x0F); + if (data.is_override_hdrlen()) + return ((data.hdrlen_rsvd() >> 4) & 0x0F); + else + return 5; case FieldTextValue: - return QString("%1").arg((data.hdrlen_rsvd() >> 4) & 0x0F); + if (data.is_override_hdrlen()) + return QString("%1 bytes").arg( + 4 * ((data.hdrlen_rsvd() >> 4) & 0x0F)); + else + return QString("20 bytes"); case FieldFrameValue: - return QByteArray(1, (char)(data.hdrlen_rsvd() & 0xF0)); + if (data.is_override_hdrlen()) + return QByteArray(1, + (char)((data.hdrlen_rsvd() >> 4) & 0x0F)); + else + return QByteArray(1, (char) 0x05); case FieldBitSize: return 4; default: @@ -253,16 +301,43 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString("Checksum"); case FieldValue: - return data.cksum(); + { + quint16 cksum; + + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + + return cksum; + } case FieldTextValue: - return QString("%1").arg(data.cksum()); + { + quint16 cksum; + + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + + return QString("0x%1").arg(cksum, 4, BASE_HEX, QChar('0')); + } case FieldFrameValue: { + quint16 cksum; + + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + QByteArray fv; fv.resize(2); - qToBigEndian((quint16) data.cksum(), (uchar*) fv.data()); + qToBigEndian(cksum, (uchar*) fv.data()); return fv; } + case FieldBitSize: + return 16; default: break; } @@ -292,15 +367,6 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, // Meta fields case tcp_is_override_hdrlen: case tcp_is_override_cksum: - switch(attrib) - { - case FieldIsMeta: - return true; - default: - break; - } - break; - default: break; } @@ -329,12 +395,13 @@ void TcpProtocol::loadConfigWidget() configForm->leTcpSeqNum->setText(QString().setNum(data.seq_num())); configForm->leTcpAckNum->setText(QString().setNum(data.ack_num())); - configForm->leTcpHdrLen->setText(QString().setNum((data.hdrlen_rsvd() >> 4) & 0x0F)); + configForm->leTcpHdrLen->setText(fieldData(tcp_hdrlen, FieldValue).toString()); configForm->cbTcpHdrLenOverride->setChecked(data.is_override_hdrlen()); configForm->leTcpWindow->setText(QString().setNum(data.window())); - configForm->leTcpCksum->setText(QString().setNum(data.cksum())); + configForm->leTcpCksum->setText(QString("%1").arg( + fieldData(tcp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); configForm->cbTcpCksumOverride->setChecked(data.is_override_cksum()); configForm->leTcpUrgentPointer->setText(QString().setNum(data.urg_ptr())); @@ -363,7 +430,7 @@ void TcpProtocol::storeConfigWidget() data.set_window(configForm->leTcpWindow->text().toULong(&isOk)); - data.set_cksum(configForm->leTcpCksum->text().remove(QChar(' ')).toULong(&isOk)); + data.set_cksum(configForm->leTcpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); data.set_is_override_cksum(configForm->cbTcpCksumOverride->isChecked()); data.set_urg_ptr(configForm->leTcpUrgentPointer->text().toULong(&isOk)); diff --git a/common/tcp.h b/common/tcp.h index 0637fc1..bfe165b 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -6,12 +6,12 @@ #include "tcp.pb.h" #include "ui_tcp.h" -#define TCP_FLAG_URG 0x01 -#define TCP_FLAG_ACK 0x02 -#define TCP_FLAG_PSH 0x04 -#define TCP_FLAG_RST 0x08 -#define TCP_FLAG_SYN 0x10 -#define TCP_FLAG_FIN 0x20 +#define TCP_FLAG_URG 0x20 +#define TCP_FLAG_ACK 0x10 +#define TCP_FLAG_PSH 0x08 +#define TCP_FLAG_RST 0x04 +#define TCP_FLAG_SYN 0x02 +#define TCP_FLAG_FIN 0x01 class TcpConfigForm : public QWidget, public Ui::tcp { @@ -62,6 +62,7 @@ public: virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, diff --git a/common/udp.cpp b/common/udp.cpp index 4d8585a..4c642c2 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -70,6 +70,35 @@ int UdpProtocol::fieldCount() const return udp_fieldCount; } +AbstractProtocol::FieldFlags UdpProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case udp_srcPort: + case udp_dstPort: + case udp_totLen: + break; + + case udp_cksum: + flags |= FieldIsCksum; + break; + + case udp_isOverrideTotLen: + case udp_isOverrideCksum: + flags |= FieldIsMeta; + break; + + default: + break; + } + + return flags; +} + QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { @@ -160,26 +189,49 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, break; } case udp_cksum: + { + quint16 cksum; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + { + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + qDebug("UDP cksum = %hu", cksum); + } + default: + break; + } + switch(attrib) { case FieldName: return QString("Checksum"); case FieldValue: - return data.cksum(); - case FieldTextValue: - return QString("%1").arg(data.cksum()); + return cksum; case FieldFrameValue: { QByteArray fv; + fv.resize(2); - qToBigEndian((quint16) data.cksum(), (uchar*) fv.data()); + qToBigEndian(cksum, (uchar*) fv.data()); return fv; } + case FieldTextValue: + return QString("0x%1"). + arg(cksum, 4, BASE_HEX, QChar('0'));; + case FieldBitSize: + return 16; default: break; } break; - + } // Meta fields case udp_isOverrideTotLen: case udp_isOverrideCksum: @@ -214,13 +266,14 @@ QWidget* UdpProtocol::configWidget() void UdpProtocol::loadConfigWidget() { - configForm->leUdpSrcPort->setText(QString().setNum(data.src_port())); - configForm->leUdpDstPort->setText(QString().setNum(data.dst_port())); + configForm->leUdpSrcPort->setText(fieldData(udp_srcPort, FieldValue).toString()); + configForm->leUdpDstPort->setText(fieldData(udp_dstPort, FieldValue).toString()); - configForm->leUdpLength->setText(QString().setNum(data.totlen())); + configForm->leUdpLength->setText(fieldData(udp_totLen, FieldValue).toString()); configForm->cbUdpLengthOverride->setChecked(data.is_override_totlen()); - configForm->leUdpCksum->setText(QString().setNum(data.cksum())); + configForm->leUdpCksum->setText(QString("%1").arg( + fieldData(udp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); configForm->cbUdpCksumOverride->setChecked(data.is_override_cksum()); } @@ -234,7 +287,7 @@ void UdpProtocol::storeConfigWidget() data.set_totlen(configForm->leUdpLength->text().toULong(&isOk)); data.set_is_override_totlen(configForm->cbUdpLengthOverride->isChecked()); - data.set_cksum(configForm->leUdpCksum->text().remove(QChar(' ')).toULong(&isOk)); + data.set_cksum(configForm->leUdpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); data.set_is_override_cksum(configForm->cbUdpCksumOverride->isChecked()); } diff --git a/common/udp.h b/common/udp.h index 5c40330..0fea509 100644 --- a/common/udp.h +++ b/common/udp.h @@ -49,6 +49,7 @@ public: virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, diff --git a/common/vlan.cpp b/common/vlan.cpp new file mode 100644 index 0000000..7908e8e --- /dev/null +++ b/common/vlan.cpp @@ -0,0 +1,229 @@ +#include + +#include "vlan.h" + +VlanConfigForm *VlanProtocol::configForm = NULL; + +VlanConfigForm::VlanConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +VlanProtocol::VlanProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) +{ + if (configForm == NULL) + configForm = new VlanConfigForm; +} + +VlanProtocol::~VlanProtocol() +{ +} + +AbstractProtocol* VlanProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new VlanProtocol(frameProtoList, streamCore); +} + +void VlanProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::vlan)->CopyFrom(data); +} + +void VlanProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::vlan)) + data.MergeFrom(stream.GetExtension(OstProto::vlan)); +} + +QString VlanProtocol::name() const +{ + return QString("Vlan"); +} + +QString VlanProtocol::shortName() const +{ + return QString("Vlan"); +} + +int VlanProtocol::fieldCount() const +{ + return vlan_fieldCount; +} + +AbstractProtocol::FieldFlags VlanProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case vlan_tpid: + case vlan_prio: + case vlan_cfiDei: + case vlan_vlanId: + break; + + // meta-fields + case vlan_isOverrideTpid: + flags |= FieldIsMeta; + break; + } + + return flags; +} + +QVariant VlanProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case vlan_tpid: + { + quint16 tpid; + + tpid = data.is_override_tpid() ? data.tpid() : 0x8100; + + switch(attrib) + { + case FieldName: + return QString("Tag Protocol Id"); + case FieldValue: + return tpid; + case FieldTextValue: + return QString("0x%1").arg(tpid, 2, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian(tpid, (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + + case vlan_prio: + { + uint prio = ((data.vlan_tag() >> 13) & 0x07); + + switch(attrib) + { + case FieldName: + return QString("Priority"); + case FieldValue: + return prio; + case FieldTextValue: + return QString("%1").arg(prio); + case FieldFrameValue: + return QByteArray(1, (char) prio); + case FieldBitSize: + return 3; + default: + break; + } + break; + } + + case vlan_cfiDei: + { + uint cfiDei = ((data.vlan_tag() >> 12) & 0x01); + + switch(attrib) + { + case FieldName: + return QString("CFI/DEI"); + case FieldValue: + return cfiDei; + case FieldTextValue: + return QString("%1").arg(cfiDei); + case FieldFrameValue: + return QByteArray(1, (char) cfiDei); + case FieldBitSize: + return 1; + default: + break; + } + break; + } + + case vlan_vlanId: + { + quint16 vlanId = (data.vlan_tag() & 0x0FFF); + + switch(attrib) + { + case FieldName: + return QString("VLAN Id"); + case FieldValue: + return vlanId; + case FieldTextValue: + return QString("%1").arg(vlanId); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) vlanId, (uchar*) fv.data()); + return fv; + } + case FieldBitSize: + return 12; + default: + break; + } + break; + } + // Meta fields + + case vlan_isOverrideTpid: + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool VlanProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* VlanProtocol::configWidget() +{ + return configForm; +} + +void VlanProtocol::loadConfigWidget() +{ + configForm->leTpid->setText(uintToHexStr(fieldData(vlan_tpid, FieldValue).toUInt(), 2)); + configForm->cmbPrio->setCurrentIndex(fieldData(vlan_prio, FieldValue).toUInt()); + configForm->cmbCfiDei->setCurrentIndex(fieldData(vlan_cfiDei, FieldValue).toUInt()); + configForm->leVlanId->setText(fieldData(vlan_vlanId, FieldValue).toString()); + +} + +void VlanProtocol::storeConfigWidget() +{ + bool isOk; + + data.set_is_override_tpid(configForm->cbTpidOverride->isChecked()); + data.set_tpid(configForm->leTpid->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); + data.set_vlan_tag( + ((configForm->cmbPrio->currentIndex() & 0x07) << 13) | + ((configForm->cmbCfiDei->currentIndex() & 0x01) << 12) | + (configForm->leVlanId->text().toULong(&isOk) & 0x0FFF)); +} + diff --git a/common/vlan.h b/common/vlan.h new file mode 100644 index 0000000..23edf44 --- /dev/null +++ b/common/vlan.h @@ -0,0 +1,62 @@ +#ifndef _Vlan_H +#define _Vlan_H + +#include "abstractprotocol.h" + +#include "vlan.pb.h" +#include "ui_vlan.h" + +class VlanConfigForm : public QWidget, public Ui::Vlan +{ + Q_OBJECT +public: + VlanConfigForm(QWidget *parent = 0); +}; + +class VlanProtocol : public AbstractProtocol +{ +private: + OstProto::Vlan data; + static VlanConfigForm *configForm; + enum Vlanfield + { + vlan_tpid, + vlan_prio, + vlan_cfiDei, + vlan_vlanId, + + // meta-fields + vlan_isOverrideTpid, + + vlan_fieldCount + }; + +public: + VlanProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); + virtual ~VlanProtocol(); + + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/vlan.proto b/common/vlan.proto index d5ac773..6703dbc 100644 --- a/common/vlan.proto +++ b/common/vlan.proto @@ -3,13 +3,11 @@ import "protocol.proto"; package OstProto; message Vlan { // VLAN presence/absence - optional bool is_tpid_override = 10; + optional bool is_override_tpid = 1; // VLAN values - optional uint32 ctpid = 13; - optional uint32 cvlan_tag = 14; // includes prio, cfi and cvlanid - optional uint32 stpid = 15; - optional uint32 svlan_tag = 16; // includes pcp, de and svlanid + optional uint32 tpid = 2; + optional uint32 vlan_tag = 3; // includes prio, cfi and vlanid } extend Stream { diff --git a/common/vlan.ui b/common/vlan.ui index c35dc89..3e0326d 100644 --- a/common/vlan.ui +++ b/common/vlan.ui @@ -1,168 +1,179 @@ - Form - + Vlan + 0 0 - 271 - 90 + 268 + 96 Form - - - - - - - Priority - - - - - - - CFI - - - - - - - VLAN - - - - - - - true - - - Override TPID - - - - - - - true - - + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + VLAN + + + + + + true + + + Override TPID + + + + + + + Priority + + + + + + + CFI/DEI + + + + + + + VLAN + + + + + + + false + + + >HH HH; + + + + + + + + + + true + + + + 0 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + + + + true + + + + 0 + + + + + 1 + + + + + + + + true + 0 - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - - - - true - - - - 0 - - - - - 1 - - - - - - - - true - - - 0 - - - - - - - true - - - >HH HH; - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - + + + + - + + + cbTpidOverride + toggled(bool) + leTpid + setEnabled(bool) + + + 59 + 41 + + + 59 + 57 + + + + From 1357f495acad74221f64f002cfac7df8dbfc2ac7 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 2 Aug 2009 14:52:34 +0000 Subject: [PATCH 23/98] Major rewrite of the protocol framework - changes not yet complete Common ------ - Change in OstProto - Individual protocols are now extensions of (new) message 'Protocol' instead of 'Stream' - Stream now contains a repeated Protocol which also determines the ordered set of currently selected protocols; StreamCore.frame_proto which was doing this earlier has been removed - Change in AbstractProtocol Interface - Parent changed to StreamBase - Corresponding change in constructor and factory func - createInstance() - new method protocolNumber() - returns unique id for each protocol - protoDataCopyInto/From() now copies into OstProto::Protocol instead of OstProto::Stream - Change in all subclasses of AbstractProtocol to match new interface - For all protocols, configFrom is no longer static, but each protocol has its own configForm - configForm creation is lazy - configForm is still a child of the protocol i.e. it will be destroyed alongwith the protocol - TODO: convert configWidget() to a pure factory function i.e. the protocol does not own the configForm - this requires us to pass the widget into load/storeConfigWidget() methods - ProtocolCollection class removed alongwith its .h and .cpp - ProtocolList class redefined to serve the purpose of ProtocolCollection - New class ProtocolListIterator defined to iterate ProtocolList - AbstractProtocol methods now use the ProtocolListIterator - Factory function createProtocol() added to ProtocolManager - OstProto::StreamCore accessor functions moved from Stream to StreamBase Server ------ - MyService uses the newly moved accessors to StreamBase for OstProto::StreamCore members - StreamInfo now uses the protocols to create the packet Client ------ - StreamConfigDialog now uses ProtocolListIterator - So does PacketModel --- client/packetmodel.cpp | 22 +- client/packetmodel.h | 12 +- client/stream.cpp | 47 +++- client/stream.h | 128 +-------- client/streamconfigdialog.cpp | 265 +++++++++++++++++-- client/streamconfigdialog.h | 9 +- client/streamconfigdialog.ui | 26 +- client/streammodel.cpp | 2 +- common/abstractprotocol.cpp | 70 ++--- common/abstractprotocol.h | 23 +- common/dot3.cpp | 52 ++-- common/dot3.h | 14 +- common/dot3.proto | 2 +- common/eth2.cpp | 43 ++-- common/eth2.h | 14 +- common/eth2.proto | 2 +- common/eth2.ui | 64 ++--- common/ip4.cpp | 53 ++-- common/ip4.h | 15 +- common/ip4.proto | 2 +- common/llc.cpp | 43 ++-- common/llc.h | 14 +- common/llc.proto | 2 +- common/mac.cpp | 48 ++-- common/mac.h | 15 +- common/mac.proto | 2 +- common/mac.ui | 31 ++- common/ostproto.pro | 6 +- common/payload.cpp | 49 ++-- common/payload.h | 14 +- common/payload.proto | 2 +- common/protocol.proto | 37 ++- common/protocolcollection.cpp | 106 -------- common/protocolcollection.h | 30 --- common/protocollist.cpp | 8 + common/protocollist.h | 9 + common/protocollistiterator.cpp | 87 +++++++ common/protocollistiterator.h | 29 +++ common/protocolmanager.cpp | 35 ++- common/protocolmanager.h | 17 +- common/sample.cpp | 42 +-- common/sample.h | 14 +- common/snap.cpp | 43 ++-- common/snap.h | 14 +- common/snap.proto | 2 +- common/streambase.cpp | 274 +++++++++++++++++--- common/streambase.h | 104 +++++++- common/tcp.cpp | 43 ++-- common/tcp.h | 14 +- common/tcp.proto | 2 +- common/udp.cpp | 43 ++-- common/udp.h | 14 +- common/udp.proto | 2 +- common/vlan.cpp | 44 ++-- common/vlan.h | 14 +- common/vlan.proto | 2 +- server/myservice.cpp | 442 ++------------------------------ 57 files changed, 1370 insertions(+), 1192 deletions(-) delete mode 100644 common/protocolcollection.cpp delete mode 100644 common/protocolcollection.h create mode 100644 common/protocollist.cpp create mode 100644 common/protocollist.h create mode 100644 common/protocollistiterator.cpp create mode 100644 common/protocollistiterator.h diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 4dc4a31..7d9df3d 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -1,18 +1,24 @@ #include -#include "packetmodel.h" -PacketModel::PacketModel(const QList &selectedProtocols, - QObject *parent) +#include "packetmodel.h" +#include "../common/protocollistiterator.h" +#include "../common/abstractprotocol.h" + +PacketModel::PacketModel(QObject *parent) { - mSelectedProtocols = selectedProtocols; } -void PacketModel::setSelectedProtocols( - const QList &selectedProtocols) +void PacketModel::setSelectedProtocols(ProtocolListIterator &iter) { - if (mSelectedProtocols != selectedProtocols) + QList currentProtocols; + + iter.toFront(); + while (iter.hasNext()) + currentProtocols.append(iter.next()); + + if (mSelectedProtocols != currentProtocols) { - mSelectedProtocols = selectedProtocols; + mSelectedProtocols = currentProtocols; reset(); } } diff --git a/client/packetmodel.h b/client/packetmodel.h index b268134..c6b0cfc 100644 --- a/client/packetmodel.h +++ b/client/packetmodel.h @@ -2,16 +2,16 @@ #define _PACKET_MODEL_H #include -#include "abstractprotocol.h" + +class ProtocolListIterator; +class AbstractProtocol; class PacketModel: public QAbstractItemModel { public: - PacketModel(const QList &selectedProtocols, - QObject *parent = 0); - void setSelectedProtocols( - const QList &selectedProtocols); + PacketModel(QObject *parent = 0); + void setSelectedProtocols(ProtocolListIterator &iter); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; @@ -34,7 +34,7 @@ private: } ws; } IndexId; - QList mSelectedProtocols; + QList mSelectedProtocols; }; #endif diff --git a/client/stream.cpp b/client/stream.cpp index b978913..d2791e3 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -2,16 +2,14 @@ #include #include "stream.h" +//#include "../common/protocollist.h" +#include "../common/protocollistiterator.h" +#include "../common/abstractprotocol.h" Stream::Stream() { //mId = 0xFFFFFFFF; - mCore->set_is_enabled(true); - - QList protoList; - protoList.append(51); - protoList.append(52); - setFrameProtocol(protoList); + setEnabled(true); } Stream::~Stream() @@ -20,10 +18,43 @@ Stream::~Stream() void Stream::loadProtocolWidgets() { - protocols.loadConfigWidgets(); +#if 0 + //protocols.loadConfigWidgets(); + foreach(AbstractProtocol* proto, *currentFrameProtocols) + { + proto->loadConfigWidget(); + } +#else + ProtocolListIterator *iter; + + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol* p = iter->next(); + p->loadConfigWidget(); + } + delete iter; +#endif } void Stream::storeProtocolWidgets() { - protocols.storeConfigWidgets(); +#if 0 + //protocols.storeConfigWidgets(); + foreach(const AbstractProtocol* proto, frameProtocol()) + { + proto->storeConfigWidget(); + _iter->toFront(); + } +#else + ProtocolListIterator *iter; + + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol* p = iter->next(); + p->storeConfigWidget(); + } + delete iter; +#endif } diff --git a/client/stream.h b/client/stream.h index 1c19b19..1539af3 100644 --- a/client/stream.h +++ b/client/stream.h @@ -13,135 +13,11 @@ class Stream : public StreamBase { //quint32 mId; public: - void loadProtocolWidgets(); - void storeProtocolWidgets(); - -public: - enum FrameLengthMode { - e_fl_fixed, - e_fl_inc, - e_fl_dec, - e_fl_random - }; - - enum SendUnit { - e_su_packets, - e_su_bursts - }; - - enum SendMode { - e_sm_fixed, - e_sm_continuous - }; - - enum NextWhat { - e_nw_stop, - e_nw_goto_next, - e_nw_goto_id - }; - - // ------------------------------------------------------- - // Methods - // ------------------------------------------------------- Stream(); ~Stream(); - // TODO: Below methods move to StreamBase??? - - bool operator < (const Stream &s) const - { return(mCore->ordinal() < s.mCore->ordinal()); } - - quint32 id() - { return mStreamId->id();} - bool setId(quint32 id) - { mStreamId->set_id(id); return true;} - -#if 0 // FIXME(HI): needed? - quint32 portId() - { return mCore->port_id();} - bool setPortId(quint32 id) - { mCore->set_port_id(id); return true;} -#endif - - quint32 ordinal() - { return mCore->ordinal();} - bool setOrdinal(quint32 ordinal) - { mCore->set_ordinal(ordinal); return true; } - - bool isEnabled() const - { return mCore->is_enabled(); } - bool setIsEnabled(bool flag) - { mCore->set_is_enabled(flag); return true; } - - const QString name() const - { return QString().fromStdString(mCore->name()); } - bool setName(QString name) - { mCore->set_name(name.toStdString()); return true; } - - // Frame Length (includes FCS) - FrameLengthMode lenMode() - { return (FrameLengthMode) mCore->len_mode(); } - bool setLenMode(FrameLengthMode lenMode) - { mCore->set_len_mode( - (OstProto::StreamCore::FrameLengthMode) lenMode); return true; } - - quint16 frameLen() - { return mCore->frame_len(); } - bool setFrameLen(quint16 frameLen) - { mCore->set_frame_len(frameLen); return true; } - - quint16 frameLenMin() - { return mCore->frame_len_min(); } - bool setFrameLenMin(quint16 frameLenMin) - { mCore->set_frame_len_min(frameLenMin); return true; } - - quint16 frameLenMax() - { return mCore->frame_len_max(); } - bool setFrameLenMax(quint16 frameLenMax) - { mCore->set_frame_len_max(frameLenMax); return true; } - - SendUnit sendUnit() - { return (SendUnit) mControl->unit(); } - bool setSendUnit(SendUnit sendUnit) - { mControl->set_unit( - (OstProto::StreamControl::SendUnit) sendUnit); return true; } - - SendMode sendMode() - { return (SendMode) mControl->mode(); } - bool setSendMode(SendMode sendMode) - { mControl->set_mode( - (OstProto::StreamControl::SendMode) sendMode); return true; } - - NextWhat nextWhat() - { return (NextWhat) mControl->next(); } - bool setNextWhat(NextWhat nextWhat) - { mControl->set_next( - (OstProto::StreamControl::NextWhat) nextWhat); return true; } - - quint32 numPackets() - { return (quint32) mControl->num_packets(); } - bool setNumPackets(quint32 numPackets) - { mControl->set_num_packets(numPackets); return true; } - - quint32 numBursts() - { return (quint32) mControl->num_bursts(); } - bool setNumBursts(quint32 numBursts) - { mControl->set_num_bursts(numBursts); return true; } - - quint32 burstSize() - { return (quint32) mControl->packets_per_burst(); } - bool setBurstSize(quint32 packetsPerBurst) - { mControl->set_packets_per_burst(packetsPerBurst); return true; } - - quint32 packetRate() - { return (quint32) mControl->packets_per_sec(); } - bool setPacketRate(quint32 packetsPerSec) - { mControl->set_packets_per_sec(packetsPerSec); return true; } - - quint32 burstRate() - { return (quint32) mControl->bursts_per_sec(); } - bool setBurstRate(quint32 burstsPerSec) - { mControl->set_bursts_per_sec(burstsPerSec); return true; } + void loadProtocolWidgets(); + void storeProtocolWidgets(); }; #endif diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index eb6f76c..0c5fc73 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -1,9 +1,16 @@ #include + #include "streamconfigdialog.h" #include "stream.h" +#include "abstractprotocol.h" +#include "protocollistiterator.h" #include "modeltest.h" +// FIXME(HI) - remove +#include "../common/protocolmanager.h" +extern ProtocolManager OstProtocolManager; + int StreamConfigDialog::lastTopLevelTabIndex = 0; int StreamConfigDialog::lastProtoTabIndex = 0; @@ -15,6 +22,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, mpStream = new Stream; mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyInto(s); mpStream->protoDataCopyFrom(s); + _iter = mpStream->createProtocolListIterator(); setupUi(this); setupUiExtra(); @@ -97,8 +105,12 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // Force L4 Protocol = None if L3 Protocol is set to ARP connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool))); + mpAvailableProtocolsModel = new QStringListModel( + OstProtocolManager.protocolDatabase(), this); + lvAllProtocols->setModel(mpAvailableProtocolsModel); + LoadCurrentStream(); - mpPacketModel = new PacketModel(QList(), this); + mpPacketModel = new PacketModel(this); tvPacketTree->setModel(mpPacketModel); mpPacketModelTester = new ModelTest(mpPacketModel); tvPacketTree->header()->hide(); @@ -134,6 +146,7 @@ void StreamConfigDialog::setupUiExtra() QRegExp reHex4B("[0-9,a-f,A-F]{1,8}"); QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); +#if 0 // MPS - temp mask // Add the Payload widget to the dialog { QGridLayout *layout; @@ -143,6 +156,7 @@ void StreamConfigDialog::setupUiExtra() layout->addWidget(mpStream->protocol(52)->configWidget(), 0, 1); qDebug("setupUi wgt = %p", mpStream->protocol(52)->configWidget()); } +#endif // ---- Setup default stuff that cannot be done in designer ---- gbVlan->setDisabled(true); @@ -199,6 +213,7 @@ StreamConfigDialog::~StreamConfigDialog() delete mpPacketModelTester; delete mpPacketModel; +#if 0 // MPS - temp mask // Remove payload data widget so that it is not deleted when this object // is destroyed { @@ -209,6 +224,7 @@ StreamConfigDialog::~StreamConfigDialog() mpStream->protocol(52)->configWidget()->setParent(0); } } +#endif // Remove any existing widget on the L2-L4 Tabs lest they are deleted // when this object is destoryed @@ -232,53 +248,95 @@ StreamConfigDialog::~StreamConfigDialog() delete bgL3Proto; delete bgL4Proto; + delete _iter; delete mpStream; } void StreamConfigDialog::updateSelectedProtocols() { - mSelectedProtocols.clear(); +#define CHKINS(p) \ +{ \ + if (_iter->hasNext() && (_iter->peekNext()->protocolNumber() == OstProto::Protocol::k##p##FieldNumber)) \ + _iter->next(); \ + else \ + _iter->insert(OstProtocolManager.createProtocol(OstProto::Protocol::k##p##FieldNumber, mpStream)); \ +} - // FIXME: Hardcoded numbers! + _iter->toFront(); +#if 1 + qDebug("Before Update"); + while (_iter->hasNext()) + { + AbstractProtocol* p; + + p = _iter->next(); + qDebug("%p:[%d]", p, p->protocolNumber()); + } + + _iter->toFront(); +#endif // Mac - mSelectedProtocols.append(51); + CHKINS(Mac) if (cbCVlan->isEnabled() && cbCVlan->isChecked()) - mSelectedProtocols.append(126); + CHKINS(Vlan); if (rbFtEthernet2->isChecked()) - mSelectedProtocols.append(121); + CHKINS(Eth2) else if (rbFt802Dot3Raw->isChecked()) - mSelectedProtocols.append(122); + CHKINS(Dot3) else if (rbFt802Dot3Llc->isChecked()) { - mSelectedProtocols.append(122); - mSelectedProtocols.append(123); + CHKINS(Dot3); + CHKINS(Llc); } else if (rbFtLlcSnap->isChecked()) { - mSelectedProtocols.append(122); - mSelectedProtocols.append(123); - mSelectedProtocols.append(124); + CHKINS(Dot3); + CHKINS(Llc); + CHKINS(Snap); } if (rbL3Ipv4->isChecked()) - mSelectedProtocols.append(130); + CHKINS(Ip4) else if (rbL3Arp->isChecked()) - mSelectedProtocols.append(131); + CHKINS(Arp) if (rbL4Tcp->isChecked()) - mSelectedProtocols.append(140); + CHKINS(Tcp) else if (rbL4Udp->isChecked()) - mSelectedProtocols.append(141); + CHKINS(Udp) else if (rbL4Icmp->isChecked()) - mSelectedProtocols.append(142); + CHKINS(Icmp) else if (rbL4Igmp->isChecked()) - mSelectedProtocols.append(143); + CHKINS(Igmp) // Payload - mSelectedProtocols.append(52); + CHKINS(Payload) + + // Remove all protocols, if any, beyond payload + while (_iter->hasNext()) + { + _iter->next(); + _iter->remove(); + } + + +#if 1 + qDebug("After Update"); + _iter->toFront(); + while (_iter->hasNext()) + { + AbstractProtocol* p; + + p = _iter->next(); + qDebug("%p:[%d]", p, p->protocolNumber()); + } +#endif + +#undef CHKINS + } void StreamConfigDialog::updateContents() @@ -345,22 +403,17 @@ void StreamConfigDialog::on_pbNext_clicked() void StreamConfigDialog::on_twTopLevel_currentChanged(int index) { - QList protoList; - // We only process the "Packet View" tab if (index != 2) return; updateContents(); - foreach(int i, mSelectedProtocols) - if (mpStream->protocol(i)) - protoList.append(mpStream->protocol(i)); - - mpPacketModel->setSelectedProtocols(protoList); + mpPacketModel->setSelectedProtocols(*_iter); } void StreamConfigDialog::on_twProto_currentChanged(int index) { +#if 0 // MPS - temp mask QLayout *layout; QList wl; @@ -461,6 +514,39 @@ void StreamConfigDialog::on_twProto_currentChanged(int index) } break; } +#else + int selTab; + + qDebug("In %s (tab index = %d)", __FUNCTION__, index); + // We need to process only index 4 i.e. the Protocol Data tab + if (index != 4) + return; + + // Hide the ToolBox before modifying it - otherwise we have a crash !!! + tbProtocolData->hide(); + + selTab = tbProtocolData->currentIndex(); + + // Remove any existing widget on the activated tab + while (tbProtocolData->count() > 0) + { + QWidget* w = tbProtocolData->widget(0); + tbProtocolData->removeItem(0); + w->setParent(0); + } + + _iter->toFront(); + while (_iter->hasNext()) + { + AbstractProtocol* p = _iter->next(); + tbProtocolData->addItem(p->configWidget(), p->name()); + } + + if (selTab < tbProtocolData->count()) + tbProtocolData->setCurrentIndex(selTab); + + tbProtocolData->show(); +#endif } void StreamConfigDialog::update_NumPacketsAndNumBursts() @@ -504,6 +590,7 @@ void StreamConfigDialog::LoadCurrentStream() lePktLenMax->setText(str.setNum(mpStream->frameLenMax())); } +#if 0 // MPS - temp mask // Protocols { int i; @@ -620,9 +707,130 @@ void StreamConfigDialog::LoadCurrentStream() _proto_parse_done: Q_ASSERT(i == mSelectedProtocols.size()); - mpStream->loadProtocolWidgets(); } +#else + // Protocols + { + qDebug("Loading - current list"); + _iter->toFront(); + while(_iter->hasNext()) + { + AbstractProtocol* p = _iter->next(); + qDebug("%p -- %d", p, p->protocolNumber()); + } + _iter->toFront(); + +#define CHK(p) (_iter->hasNext() && _iter->peekNext()->protocolNumber() == p) + + Q_ASSERT(CHK(51)); // Mac + _iter->next(); + + // VLAN + if (CHK(126)) // VLAN + { + cbCVlan->setChecked(true); + _iter->next(); + } + + if (CHK(52)) // Payload + { + _iter->next(); + goto _proto_parse_done; + } + else if (CHK(121)) // Eth2 + { + rbFtEthernet2->setChecked(true); + _iter->next(); + } + else if (CHK(122)) // 802.3 RAW + { + _iter->next(); + if (CHK(123)) // 802.3 LLC + { + _iter->next(); + if (CHK(124)) // SNAP + { + rbFtLlcSnap->setChecked(true); + _iter->next(); + } + else + { + rbFt802Dot3Llc->setChecked(true); + } + } + else + { + rbFt802Dot3Raw->setChecked(true); + } + } + else + rbFtNone->setChecked(true); + + + // L3 + if (CHK(52)) // Payload + { + _iter->next(); + goto _proto_parse_done; + } + else if (CHK(130)) // IP4 + { + rbL3Ipv4->setChecked(true); + _iter->next(); + } + else if (CHK(131)) // ARP + { + rbL3Arp->setChecked(true); + _iter->next(); + } + else + rbL3None->setChecked(true); + + if (!_iter->hasNext()) + goto _proto_parse_done; + + // L4 + if (CHK(52)) // Payload + { + _iter->next(); + goto _proto_parse_done; + } + else if (CHK(140)) // TCP + { + rbL4Tcp->setChecked(true); + _iter->next(); + } + else if (CHK(141)) // UDP + { + rbL4Udp->setChecked(true); + _iter->next(); + } + else if (CHK(142)) // ICMP + { + rbL4Icmp->setChecked(true); + _iter->next(); + } + else if (CHK(143)) // IGMP + { + rbL4Igmp->setChecked(true); + _iter->next(); + } + else + rbL4None->setChecked(true); + + Q_ASSERT(CHK(52)); // Payload + _iter->next(); + +_proto_parse_done: + Q_ASSERT(!_iter->hasNext()); + mpStream->loadProtocolWidgets(); + +#undef CHK + } + + +#endif // Stream Control { @@ -673,6 +881,7 @@ _proto_parse_done: // TODO(MED): Change this when we support goto to specific stream leStreamId->setText(QString("0")); } + qDebug("loading stream done"); } void StreamConfigDialog::StoreCurrentStream() @@ -692,7 +901,7 @@ void StreamConfigDialog::StoreCurrentStream() // Protocols { updateSelectedProtocols(); - pStream->setFrameProtocol(mSelectedProtocols); + //pStream->setFrameProtocol(mSelectedProtocols); pStream->storeProtocolWidgets(); } diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index fa4aa82..c0e02a7 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -27,21 +27,22 @@ public: ~StreamConfigDialog(); private: - //QList *mpStreamList; QButtonGroup *bgFrameType; QButtonGroup *bgL3Proto; QButtonGroup *bgL4Proto; + QStringListModel *mpAvailableProtocolsModel; + Port& mPort; uint mCurrentStreamIndex; - Stream *mpStream; - QList mSelectedProtocols; + + Stream *mpStream; + ProtocolListIterator *_iter; PacketModel *mpPacketModel; ModelTest *mpPacketModelTester; - // The following static variables are used to track the "selected" tab // for the various tab widgets so that it can be restored when the dialog // is opened the next time diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index d803e44..198cbf2 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -12,6 +12,12 @@ 589 + + + 0 + 0 + + Edit Stream @@ -56,7 +62,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + Frame Length (including FCS) @@ -157,10 +163,10 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + - 0 + 4 @@ -516,6 +522,20 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + Protocol Data + + + + + + -1 + + + + + diff --git a/client/streammodel.cpp b/client/streammodel.cpp index c1b887c..cba20e6 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -136,7 +136,7 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r return true; case StreamStatus: - mCurrentPort->streamByIndex(index.row())->setIsEnabled(value.toBool()); + mCurrentPort->streamByIndex(index.row())->setEnabled(value.toBool()); emit(dataChanged(index, index)); return true; diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index b48f5b1..2bac712 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -1,5 +1,8 @@ #include + #include "abstractprotocol.h" +#include "streambase.h" +#include "protocollistiterator.h" /*! \class AbstractProtocol @@ -19,13 +22,9 @@ - metaFieldCount() - isMetaField() */ -AbstractProtocol::AbstractProtocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : frameProtocols(frameProtoList) +AbstractProtocol::AbstractProtocol(StreamBase *stream) { - qDebug("%s: &frameproto = %p/%p (sz:%d)", __FUNCTION__, &frameProtocols, &frameProtoList, frameProtocols.size()); - stream = parent; + mpStream = stream; metaCount = -1; protoSize = -1; } @@ -34,13 +33,17 @@ AbstractProtocol::~AbstractProtocol() { } -AbstractProtocol* AbstractProtocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream) { return NULL; } +quint32 AbstractProtocol::protocolNumber() const +{ + qDebug("Something wrong!!!"); + return 0xFFFFFFFF; +} + /*! \fn virtual void protoDataCopyInto(OstProto::OstProto::StreamCore &stream) = 0; @@ -182,13 +185,14 @@ quint32 AbstractProtocol::protocolId(ProtocolIdType type) const quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const { quint32 id = 0xFFFFFFFF; - QLinkedListIterator iter(frameProtocols); + ProtocolListIterator *iter = mpStream->createProtocolListIterator(); - if (iter.findNext(this)) + if (iter->findNext(this)) { - if (iter.hasNext()) - id = iter.next()->protocolId(type); + if (iter->hasNext()) + id = iter->next()->protocolId(type); } + delete iter; qDebug("%s: payloadProtocolId = %u", __FUNCTION__, id); return id; @@ -215,16 +219,17 @@ int AbstractProtocol::protocolFrameSize() const int AbstractProtocol::protocolFrameOffset() const { int size = 0; - QLinkedListIterator iter(frameProtocols); + ProtocolListIterator *iter = mpStream->createProtocolListIterator(); - if (iter.findNext(this)) + if (iter->findNext(this)) { - iter.previous(); - while (iter.hasPrevious()) - size += iter.previous()->protocolFrameSize(); + iter->previous(); + while (iter->hasPrevious()) + size += iter->previous()->protocolFrameSize(); } else return -1; + delete iter; qDebug("%s: ofs = %d", __FUNCTION__, size); return size; @@ -234,15 +239,16 @@ int AbstractProtocol::protocolFramePayloadSize() const { int size = 0; - QLinkedListIterator iter(frameProtocols); + ProtocolListIterator *iter = mpStream->createProtocolListIterator(); - if (iter.findNext(this)) + if (iter->findNext(this)) { - while (iter.hasNext()) - size += iter.next()->protocolFrameSize(); + while (iter->hasNext()) + size += iter->next()->protocolFrameSize(); } else return -1; + delete iter; qDebug("%s: payloadSize = %d", __FUNCTION__, size); return size; @@ -421,17 +427,18 @@ quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, CksumType cksumType) const { quint32 sum = 0xFFFF; - QLinkedListIterator iter(frameProtocols); + ProtocolListIterator *iter = mpStream->createProtocolListIterator(); Q_ASSERT(cksumType == CksumIpPseudo); - if (iter.findNext(this)) + if (iter->findNext(this)) { - iter.previous(); - if (iter.hasPrevious()) - sum = iter.previous()->protocolFrameCksum(streamIndex, + iter->previous(); + if (iter->hasPrevious()) + sum = iter->previous()->protocolFrameCksum(streamIndex, CksumIpPseudo); } + delete iter; while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); @@ -444,20 +451,21 @@ quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, { quint32 sum = 0; quint16 cksum; - QLinkedListIterator iter(frameProtocols); + ProtocolListIterator *iter = mpStream->createProtocolListIterator(); Q_ASSERT(cksumType == CksumIp); - if (iter.findNext(this)) + if (iter->findNext(this)) { - while (iter.hasNext()) + while (iter->hasNext()) { - cksum = iter.next()->protocolFrameCksum(streamIndex, CksumIp); + cksum = iter->next()->protocolFrameCksum(streamIndex, CksumIp); sum += (quint16) ~cksum; } } else return 0; + delete iter; while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index bbe8325..aca2d2d 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -9,7 +9,7 @@ #include //#include "../rpc/pbhelper.h" -#include "../common/protocol.pb.h" +#include "protocol.pb.h" #define BASE_BIN (2) #define BASE_OCT (8) @@ -19,10 +19,7 @@ #define uintToHexStr(num, bytes) \ QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) -class OstProto::StreamCore; -class AbstractProtocol; - -typedef QLinkedList ProtocolList; +class StreamBase; class AbstractProtocol { @@ -32,8 +29,7 @@ private: mutable QString protoAbbr; protected: - OstProto::StreamCore *stream; - ProtocolList &frameProtocols; + StreamBase *mpStream; public: enum FieldFlag { @@ -65,16 +61,14 @@ public: CksumMax }; - AbstractProtocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + AbstractProtocol(StreamBase *stream); virtual ~AbstractProtocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream) = 0; - virtual void protoDataCopyFrom(const OstProto::Stream &stream) = 0; + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const = 0; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) = 0; virtual QString name() const; virtual QString shortName() const; @@ -109,7 +103,6 @@ public: virtual void loadConfigWidget() = 0; virtual void storeConfigWidget() = 0; }; - Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractProtocol::FieldFlags); #endif diff --git a/common/dot3.cpp b/common/dot3.cpp index 448c0c5..be6d580 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -1,49 +1,49 @@ #include #include -#include "Dot3.h" +#include "dot3.h" +#include "streambase.h" #define SZ_FCS 4 -Dot3ConfigForm *Dot3Protocol::configForm = NULL; - Dot3ConfigForm::Dot3ConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); } -Dot3Protocol::Dot3Protocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +Dot3Protocol::Dot3Protocol(StreamBase *stream) + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new Dot3ConfigForm; + configForm = NULL; } Dot3Protocol::~Dot3Protocol() { + delete configForm; } -AbstractProtocol* Dot3Protocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* Dot3Protocol::createInstance(StreamBase *stream) { - return new Dot3Protocol(frameProtoList, streamCore); + return new Dot3Protocol(stream); } -void Dot3Protocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 Dot3Protocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::dot3)->CopyFrom(data); + return OstProto::Protocol::kDot3FieldNumber; } -void Dot3Protocol::protoDataCopyFrom(const OstProto::Stream &stream) +void Dot3Protocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::dot3)) - data.MergeFrom(stream.GetExtension(OstProto::dot3)); + protocol.MutableExtension(OstProto::dot3)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void Dot3Protocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::dot3)) + data.MergeFrom(protocol.GetExtension(OstProto::dot3)); } QString Dot3Protocol::name() const @@ -75,14 +75,14 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, { quint16 len; - len = stream->frame_len() - SZ_FCS; + len = mpStream->frameLen() - SZ_FCS; return len; } case FieldTextValue: { quint16 len; - len = stream->frame_len() - SZ_FCS; + len = mpStream->frameLen() - SZ_FCS; return QString("%1").arg(len); } case FieldFrameValue: @@ -90,7 +90,7 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, quint16 len; QByteArray fv; - len = stream->frame_len() - SZ_FCS; + len = mpStream->frameLen() - SZ_FCS; fv.resize(2); qToBigEndian(len, (uchar*) fv.data()); return fv; @@ -117,11 +117,15 @@ bool Dot3Protocol::setFieldData(int index, const QVariant &value, QWidget* Dot3Protocol::configWidget() { + if (configForm == NULL) + configForm = new Dot3ConfigForm; return configForm; } void Dot3Protocol::loadConfigWidget() { + configWidget(); + configForm->leLength->setText( fieldData(dot3_length, FieldValue).toString()); } @@ -130,6 +134,8 @@ void Dot3Protocol::storeConfigWidget() { bool isOk; + configWidget(); + data.set_length(configForm->leLength->text().toULong(&isOk)); } diff --git a/common/dot3.h b/common/dot3.h index 3b98b24..268e61d 100644 --- a/common/dot3.h +++ b/common/dot3.h @@ -17,7 +17,7 @@ class Dot3Protocol : public AbstractProtocol { private: OstProto::Dot3 data; - static Dot3ConfigForm *configForm; + Dot3ConfigForm *configForm; enum Dot3field { dot3_length, @@ -26,16 +26,14 @@ private: }; public: - Dot3Protocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + Dot3Protocol(StreamBase *stream); virtual ~Dot3Protocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/dot3.proto b/common/dot3.proto index 37f78ca..5a84c18 100644 --- a/common/dot3.proto +++ b/common/dot3.proto @@ -7,6 +7,6 @@ message Dot3 { optional uint32 length = 1; } -extend Stream { +extend Protocol { optional Dot3 dot3 = 122; } diff --git a/common/eth2.cpp b/common/eth2.cpp index 9fbfda6..1d72042 100644 --- a/common/eth2.cpp +++ b/common/eth2.cpp @@ -3,45 +3,44 @@ #include "eth2.h" -Eth2ConfigForm *Eth2Protocol::configForm = NULL; - Eth2ConfigForm::Eth2ConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); } -Eth2Protocol::Eth2Protocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +Eth2Protocol::Eth2Protocol(StreamBase *stream) + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new Eth2ConfigForm; + configForm = NULL; } Eth2Protocol::~Eth2Protocol() { + delete configForm; } -AbstractProtocol* Eth2Protocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* Eth2Protocol::createInstance(StreamBase *stream) { - return new Eth2Protocol(frameProtoList, streamCore); + return new Eth2Protocol(stream); } -void Eth2Protocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 Eth2Protocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::eth2)->CopyFrom(data); + return OstProto::Protocol::kEth2FieldNumber; } -void Eth2Protocol::protoDataCopyFrom(const OstProto::Stream &stream) +void Eth2Protocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::eth2)) - data.MergeFrom(stream.GetExtension(OstProto::eth2)); + protocol.MutableExtension(OstProto::eth2)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void Eth2Protocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::eth2)) + data.MergeFrom(protocol.GetExtension(OstProto::eth2)); } QString Eth2Protocol::name() const @@ -121,11 +120,15 @@ bool Eth2Protocol::setFieldData(int index, const QVariant &value, QWidget* Eth2Protocol::configWidget() { + if (configForm == NULL) + configForm = new Eth2ConfigForm; return configForm; } void Eth2Protocol::loadConfigWidget() { + configWidget(); + configForm->leType->setText(uintToHexStr( fieldData(eth2_type, FieldValue).toUInt(), 2)); } @@ -134,6 +137,8 @@ void Eth2Protocol::storeConfigWidget() { bool isOk; + configWidget(); + data.set_type(configForm->leType->text().remove(QChar(' ')).toULong(&isOk, 16)); } diff --git a/common/eth2.h b/common/eth2.h index e71659d..a99efbf 100644 --- a/common/eth2.h +++ b/common/eth2.h @@ -17,7 +17,7 @@ class Eth2Protocol : public AbstractProtocol { private: OstProto::Eth2 data; - static Eth2ConfigForm *configForm; + Eth2ConfigForm *configForm; enum eth2field { eth2_type = 0, @@ -26,16 +26,14 @@ private: }; public: - Eth2Protocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + Eth2Protocol(StreamBase *stream); virtual ~Eth2Protocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/eth2.proto b/common/eth2.proto index 224c25d..348888d 100644 --- a/common/eth2.proto +++ b/common/eth2.proto @@ -7,6 +7,6 @@ message Eth2 { optional uint32 type = 1; } -extend Stream { +extend Protocol { optional Eth2 eth2 = 121; } diff --git a/common/eth2.ui b/common/eth2.ui index a79068c..7bf6cdf 100644 --- a/common/eth2.ui +++ b/common/eth2.ui @@ -5,44 +5,35 @@ 0 0 - 166 - 72 + 267 + 64 Form - - - - - Ethernet II + + + + + Ethernet Type + + + leType - - - - - Ethernet Type - - - leType - - - - - - - false - - - >HH HH; - - - - - + + + + false + + + >HH HH; + + + + Qt::Horizontal @@ -55,6 +46,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/common/ip4.cpp b/common/ip4.cpp index 59a6773..653c83f 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -3,8 +3,6 @@ #include "ip4.h" -Ip4ConfigForm *Ip4Protocol::configForm = NULL; - Ip4ConfigForm::Ip4ConfigForm(QWidget *parent) : QWidget(parent) { @@ -18,6 +16,11 @@ Ip4ConfigForm::Ip4ConfigForm(QWidget *parent) this, SLOT(on_cmbIpDstAddrMode_currentIndexChanged(int))); } +Ip4ConfigForm::~Ip4ConfigForm() +{ + qDebug("IPv4 Config Form destructor called"); +} + void Ip4ConfigForm::on_cmbIpSrcAddrMode_currentIndexChanged(int index) { if (index == OstProto::Ip4::e_im_fixed) @@ -46,42 +49,38 @@ void Ip4ConfigForm::on_cmbIpDstAddrMode_currentIndexChanged(int index) } } -Ip4Protocol::Ip4Protocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +Ip4Protocol::Ip4Protocol(StreamBase *stream) + : AbstractProtocol(stream) { -#if 0 - PbHelper pbh; - - pbh.ForceSetSingularDefault(&data); -#endif - if (configForm == NULL) - configForm = new Ip4ConfigForm; + configForm = NULL; } Ip4Protocol::~Ip4Protocol() { + delete configForm; } -AbstractProtocol* Ip4Protocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* Ip4Protocol::createInstance(StreamBase *stream) { - return new Ip4Protocol(frameProtoList, streamCore); + return new Ip4Protocol(stream); } -void Ip4Protocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 Ip4Protocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::ip4)->CopyFrom(data); + return OstProto::Protocol::kIp4FieldNumber; } -void Ip4Protocol::protoDataCopyFrom(const OstProto::Stream &stream) +void Ip4Protocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::ip4)) - data.MergeFrom(stream.GetExtension(OstProto::ip4)); + protocol.MutableExtension(OstProto::ip4)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void Ip4Protocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::ip4)) + data.MergeFrom(protocol.GetExtension(OstProto::ip4)); } QString Ip4Protocol::name() const @@ -604,11 +603,15 @@ quint32 Ip4Protocol::protocolFrameCksum(int streamIndex, QWidget* Ip4Protocol::configWidget() { + if (configForm == NULL) + configForm = new Ip4ConfigForm; return configForm; } void Ip4Protocol::loadConfigWidget() { + configWidget(); + configForm->cbIpVersionOverride->setChecked(data.is_override_ver()); configForm->leIpVersion->setText(fieldData(ip4_ver, FieldValue).toString()); @@ -649,6 +652,8 @@ void Ip4Protocol::storeConfigWidget() uint ff = 0; bool isOk; + configWidget(); + data.set_is_override_ver(configForm->cbIpVersionOverride->isChecked()); data.set_ver_hdrlen(((configForm->leIpVersion->text().toULong(&isOk) & 0x0F) << 4) | (configForm->leIpHdrLen->text().toULong(&isOk) & 0x0F)); diff --git a/common/ip4.h b/common/ip4.h index 9c20936..a539e71 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -16,6 +16,7 @@ class Ip4ConfigForm : public QWidget, public Ui::ip4 Q_OBJECT public: Ip4ConfigForm(QWidget *parent = 0); + ~Ip4ConfigForm(); private slots: void on_cmbIpSrcAddrMode_currentIndexChanged(int index); void on_cmbIpDstAddrMode_currentIndexChanged(int index); @@ -25,7 +26,7 @@ class Ip4Protocol : public AbstractProtocol { private: OstProto::Ip4 data; - static Ip4ConfigForm *configForm; + Ip4ConfigForm *configForm; enum ip4field { ip4_ver = 0, @@ -58,16 +59,14 @@ private: }; public: - Ip4Protocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + Ip4Protocol(StreamBase *stream); virtual ~Ip4Protocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/ip4.proto b/common/ip4.proto index af61255..6889ffd 100644 --- a/common/ip4.proto +++ b/common/ip4.proto @@ -42,6 +42,6 @@ message Ip4 { // TODO: Options } -extend Stream { +extend Protocol { optional Ip4 ip4 = 130; } diff --git a/common/llc.cpp b/common/llc.cpp index c0183ca..150b8b8 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -3,45 +3,44 @@ #include "llc.h" -LlcConfigForm *LlcProtocol::configForm = NULL; - LlcConfigForm::LlcConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); } -LlcProtocol::LlcProtocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +LlcProtocol::LlcProtocol(StreamBase *stream) + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new LlcConfigForm; + configForm = NULL; } LlcProtocol::~LlcProtocol() { + delete configForm; } -AbstractProtocol* LlcProtocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* LlcProtocol::createInstance(StreamBase *stream) { - return new LlcProtocol(frameProtoList, streamCore); + return new LlcProtocol(stream); } -void LlcProtocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 LlcProtocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::llc)->CopyFrom(data); + return OstProto::Protocol::kLlcFieldNumber; } -void LlcProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +void LlcProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::llc)) - data.MergeFrom(stream.GetExtension(OstProto::llc)); + protocol.MutableExtension(OstProto::llc)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void LlcProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::llc)) + data.MergeFrom(protocol.GetExtension(OstProto::llc)); } QString LlcProtocol::name() const @@ -135,6 +134,8 @@ bool LlcProtocol::setFieldData(int index, const QVariant &value, QWidget* LlcProtocol::configWidget() { + if (configForm == NULL) + configForm = new LlcConfigForm; return configForm; } @@ -143,6 +144,8 @@ void LlcProtocol::loadConfigWidget() #define uintToHexStr(num, bytes) \ QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) + configWidget(); + configForm->leDsap->setText(uintToHexStr( fieldData(llc_dsap, FieldValue).toUInt(), 1)); configForm->leSsap->setText(uintToHexStr( @@ -156,6 +159,8 @@ void LlcProtocol::storeConfigWidget() { bool isOk; + configWidget(); + data.set_dsap(configForm->leDsap->text().toULong(&isOk, BASE_HEX)); data.set_ssap(configForm->leSsap->text().toULong(&isOk, BASE_HEX)); data.set_ctl(configForm->leControl->text().toULong(&isOk, BASE_HEX)); diff --git a/common/llc.h b/common/llc.h index 8403fab..9fe5d28 100644 --- a/common/llc.h +++ b/common/llc.h @@ -20,7 +20,7 @@ class LlcProtocol : public AbstractProtocol { private: OstProto::Llc data; - static LlcConfigForm *configForm; + LlcConfigForm *configForm; enum llcfield { llc_dsap = 0, @@ -31,16 +31,14 @@ private: }; public: - LlcProtocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + LlcProtocol(StreamBase *stream); virtual ~LlcProtocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/llc.proto b/common/llc.proto index c57cdbe..72a4393 100644 --- a/common/llc.proto +++ b/common/llc.proto @@ -8,6 +8,6 @@ message Llc { optional uint32 ctl = 3; } -extend Stream { +extend Protocol { optional Llc llc = 123; } diff --git a/common/mac.cpp b/common/mac.cpp index 1adc9ca..dfe3ed8 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -3,8 +3,6 @@ #include "mac.h" -MacConfigForm *MacProtocol::configForm = NULL; - MacConfigForm::MacConfigForm(QWidget *parent) : QWidget(parent) { @@ -17,6 +15,11 @@ MacConfigForm::MacConfigForm(QWidget *parent) leSrcMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); } +MacConfigForm::~MacConfigForm() +{ + qDebug("In MacConfigForm destructor"); +} + void MacConfigForm::on_cmbDstMacMode_currentIndexChanged(int index) { if (index == OstProto::Mac::e_mm_fixed) @@ -46,37 +49,38 @@ void MacConfigForm::on_cmbSrcMacMode_currentIndexChanged(int index) } -MacProtocol::MacProtocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +MacProtocol::MacProtocol(StreamBase *stream) + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new MacConfigForm; + configForm = NULL; } MacProtocol::~MacProtocol() { + delete configForm; } -AbstractProtocol* MacProtocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* MacProtocol::createInstance(StreamBase *stream) { - return new MacProtocol(frameProtoList, streamCore); + return new MacProtocol(stream); } -void MacProtocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 MacProtocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::mac)->CopyFrom(data); + return OstProto::Protocol::kMacFieldNumber; } -void MacProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +void MacProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::mac)) - data.MergeFrom(stream.GetExtension(OstProto::mac)); + protocol.MutableExtension(OstProto::mac)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void MacProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::mac)) + data.MergeFrom(protocol.GetExtension(OstProto::mac)); } QString MacProtocol::name() const @@ -238,11 +242,15 @@ bool MacProtocol::setFieldData(int index, const QVariant &value, QWidget* MacProtocol::configWidget() { + if (configForm == NULL) + configForm = new MacConfigForm; return configForm; } void MacProtocol::loadConfigWidget() { + configWidget(); + configForm->leDstMac->setText(uintToHexStr(data.dst_mac(), 6)); configForm->cmbDstMacMode->setCurrentIndex(data.dst_mac_mode()); configForm->leDstMacCount->setText(QString().setNum(data.dst_mac_count())); @@ -258,6 +266,8 @@ void MacProtocol::storeConfigWidget() { bool isOk; + configWidget(); + data.set_dst_mac(configForm->leDstMac->text().remove(QChar(' ')). toULongLong(&isOk, 16)); data.set_dst_mac_mode((OstProto::Mac::MacAddrMode) configForm-> diff --git a/common/mac.h b/common/mac.h index 84199a5..a71e7cc 100644 --- a/common/mac.h +++ b/common/mac.h @@ -13,6 +13,7 @@ class MacConfigForm : public QWidget, public Ui::mac Q_OBJECT public: MacConfigForm(QWidget *parent = 0); + virtual ~MacConfigForm(); private slots: void on_cmbDstMacMode_currentIndexChanged(int index); void on_cmbSrcMacMode_currentIndexChanged(int index); @@ -22,7 +23,7 @@ class MacProtocol : public AbstractProtocol { private: OstProto::Mac data; - static MacConfigForm *configForm; + MacConfigForm *configForm; enum macfield { mac_dstAddr = 0, @@ -39,16 +40,14 @@ private: }; public: - MacProtocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + MacProtocol(StreamBase *stream); virtual ~MacProtocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/mac.proto b/common/mac.proto index c4c5253..2e8c04e 100644 --- a/common/mac.proto +++ b/common/mac.proto @@ -24,6 +24,6 @@ message Mac { optional uint32 src_mac_step = 8 [default = 1]; } -extend Stream { +extend Protocol { optional Mac mac = 51; } diff --git a/common/mac.ui b/common/mac.ui index ca1350e..78a2c74 100644 --- a/common/mac.ui +++ b/common/mac.ui @@ -6,13 +6,13 @@ 0 0 512 - 98 + 104 Form - + @@ -81,10 +81,10 @@ false - 1 + - 1 + 0 @@ -101,10 +101,10 @@ false - 1 + - 1 + 0 @@ -164,7 +164,7 @@ false - 1 + @@ -181,16 +181,29 @@ false - 1 + - 1 + 0 + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/common/ostproto.pro b/common/ostproto.pro index 192049f..6095613 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -29,7 +29,8 @@ PROTOS += \ HEADERS += \ abstractprotocol.h \ protocolmanager.h \ - protocolcollection.h \ + protocollist.h \ + protocollistiterator.h \ streambase.h \ mac.h \ payload.h \ @@ -44,7 +45,8 @@ HEADERS += \ SOURCES += \ abstractprotocol.cpp \ protocolmanager.cpp \ - protocolcollection.cpp \ + protocollist.cpp \ + protocollistiterator.cpp \ streambase.cpp \ mac.cpp \ payload.cpp \ diff --git a/common/payload.cpp b/common/payload.cpp index ecaef9b..5633ed6 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -3,11 +3,10 @@ //#include "../client/stream.h" #include "payload.h" +#include "streambase.h" #define SZ_FCS 4 -PayloadConfigForm *PayloadProtocol::configForm = NULL; - PayloadConfigForm::PayloadConfigForm(QWidget *parent) : QWidget(parent) { @@ -31,37 +30,38 @@ void PayloadConfigForm::on_cmbPatternMode_currentIndexChanged(int index) } } -PayloadProtocol::PayloadProtocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +PayloadProtocol::PayloadProtocol(StreamBase *stream) + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new PayloadConfigForm; + configForm = NULL; } PayloadProtocol::~PayloadProtocol() { + delete configForm; } -AbstractProtocol* PayloadProtocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* PayloadProtocol::createInstance(StreamBase *stream) { - return new PayloadProtocol(frameProtoList, streamCore); + return new PayloadProtocol(stream); } -void PayloadProtocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 PayloadProtocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::payload)->CopyFrom(data); + return OstProto::Protocol::kPayloadFieldNumber; } -void PayloadProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +void PayloadProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::payload)) - data.MergeFrom(stream.GetExtension(OstProto::payload)); + protocol.MutableExtension(OstProto::payload)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void PayloadProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::payload)) + data.MergeFrom(protocol.GetExtension(OstProto::payload)); } QString PayloadProtocol::name() const @@ -76,7 +76,7 @@ QString PayloadProtocol::shortName() const int PayloadProtocol::protocolFrameSize() const { - return (stream->frame_len() - protocolFrameOffset() - SZ_FCS); + return (mpStream->frameLen() - protocolFrameOffset() - SZ_FCS); } int PayloadProtocol::fieldCount() const @@ -124,7 +124,7 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, QByteArray fv; int dataLen; - dataLen = stream->frame_len() - protocolFrameOffset(); + dataLen = mpStream->frameLen() - protocolFrameOffset(); dataLen -= SZ_FCS; fv.resize(dataLen+4); switch(data.pattern_mode()) @@ -179,12 +179,15 @@ bool PayloadProtocol::setFieldData(int index, const QVariant &value, QWidget* PayloadProtocol::configWidget() { + if (configForm == NULL) + configForm = new PayloadConfigForm; return configForm; - //return new PayloadConfigForm; } void PayloadProtocol::loadConfigWidget() { + configWidget(); + configForm->cmbPatternMode->setCurrentIndex(data.pattern_mode()); configForm->lePattern->setText(uintToHexStr(data.pattern(), 4)); } @@ -193,6 +196,8 @@ void PayloadProtocol::storeConfigWidget() { bool isOk; + configWidget(); + data.set_pattern_mode((OstProto::Payload::DataPatternMode) configForm->cmbPatternMode->currentIndex()); data.set_pattern(configForm->lePattern->text().remove(QChar(' ')).toULong(&isOk, 16)); diff --git a/common/payload.h b/common/payload.h index 34e9a01..46c1d70 100644 --- a/common/payload.h +++ b/common/payload.h @@ -19,7 +19,7 @@ class PayloadProtocol : public AbstractProtocol { private: OstProto::Payload data; - static PayloadConfigForm *configForm; + PayloadConfigForm *configForm; enum payloadfield { payload_dataPattern, @@ -31,16 +31,14 @@ private: }; public: - PayloadProtocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + PayloadProtocol(StreamBase *stream); virtual ~PayloadProtocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/payload.proto b/common/payload.proto index e97f33c..b3a6946 100644 --- a/common/payload.proto +++ b/common/payload.proto @@ -17,6 +17,6 @@ message Payload { //optional uint32 data_start_ofs = 13; } -extend Stream { +extend Protocol { optional Payload payload = 52; } diff --git a/common/protocol.proto b/common/protocol.proto index a809795..9788735 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -28,7 +28,7 @@ message StreamCore { optional uint32 frame_len_max = 17 [default = 1518]; // Currently Selected Protocols - repeated uint32 frame_proto = 20; + //repeated uint32 frame_proto = 20; } message StreamControl { @@ -61,14 +61,45 @@ message StreamControl { } +message ProtocolId { + required uint32 id = 1; +} + +message Protocol { + + required ProtocolId protocol_id = 1; + + extensions 51 to 100; // Reserved for Ostinato Use + extensions 101 to 200; // Available for use by protocols + + enum k { + kMacFieldNumber = 51; + kPayloadFieldNumber = 52; + + kEth2FieldNumber = 121; + kDot3FieldNumber = 122; + kLlcFieldNumber = 123; + kSnapFieldNumber = 124; + + kVlanFieldNumber = 126; + + kIp4FieldNumber = 130; + kArpFieldNumber = 131; + + kTcpFieldNumber = 140; + kUdpFieldNumber = 141; + kIcmpFieldNumber = 142; + kIgmpFieldNumber = 143; + } +} + message Stream { required StreamId stream_id = 1; optional StreamCore core = 2; optional StreamControl control = 3; - extensions 51 to 100; // Reserved for Ostinato Use - extensions 101 to 200; // Available for use by protocols + repeated Protocol protocol = 4; } message Void { diff --git a/common/protocolcollection.cpp b/common/protocolcollection.cpp deleted file mode 100644 index 60e6d21..0000000 --- a/common/protocolcollection.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "protocolcollection.h" - -extern ProtocolManager OstProtocolManager; - -ProtocolCollection::ProtocolCollection(ProtocolList &streamProtocols, - OstProto::StreamCore *streamCore) - : protoManager(OstProtocolManager) -{ - // Create an instance of each registered protocol - - QMapIterator iter(protoManager.factory); - - while (iter.hasNext()) - { - AbstractProtocol* (*p)(ProtocolList&, OstProto::StreamCore*); - AbstractProtocol* q; - - iter.next(); - p = (AbstractProtocol* (*)(ProtocolList&, OstProto::StreamCore*)) - iter.value(); - q = (*p)(streamProtocols, streamCore); - - protocols.insert(iter.key(), q); - } -} - -ProtocolCollection::~ProtocolCollection() -{ - QMutableMapIterator iter(protocols); - - while (iter.hasNext()) - { - iter.next(); - if (iter.value()) - { - delete iter.value(); - iter.remove(); - } - } -} - -void ProtocolCollection::protoDataCopyFrom(const OstProto::Stream &stream) const -{ - QMapIterator iter(protocols); - - while (iter.hasNext()) - { - iter.next(); - if (iter.value()) - { - iter.value()->protoDataCopyFrom(stream); - } - } -} - -void ProtocolCollection::protoDataCopyInto(OstProto::Stream &stream) const -{ - QMapIterator iter(protocols); - - while (iter.hasNext()) - { - iter.next(); - if (iter.value()) - { - iter.value()->protoDataCopyInto(stream); - } - } -} - -void ProtocolCollection::loadConfigWidgets() const -{ - QMapIterator iter(protocols); - - while (iter.hasNext()) - { - iter.next(); - if (iter.value()) - { - iter.value()->loadConfigWidget(); - } - } -} - -void ProtocolCollection::storeConfigWidgets() const -{ - QMapIterator iter(protocols); - - while (iter.hasNext()) - { - iter.next(); - if (iter.value()) - { - iter.value()->storeConfigWidget(); - } - } -} - -AbstractProtocol* ProtocolCollection::protocol(int protoNum) -{ - return protocols.value(protoNum); -} - -AbstractProtocol* ProtocolCollection::protocol(QString protoName) -{ - return protocols.value(protoManager.nameToNumberMap.value(protoName)); -} diff --git a/common/protocolcollection.h b/common/protocolcollection.h deleted file mode 100644 index 61ca418..0000000 --- a/common/protocolcollection.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _PROTOCOL_COLLECTION_H -#define _PROTOCOL_COLLECTION_H - -#include -#include - -#include "abstractprotocol.h" -#include "protocolmanager.h" - -class ProtocolCollection { - - ProtocolManager &protoManager; - QMap protocols; - -public: - ProtocolCollection(ProtocolList &streamProtocols, - OstProto::StreamCore *streamCore); - ProtocolCollection::~ProtocolCollection(); - - void protoDataCopyFrom(const OstProto::Stream &stream) const; - void protoDataCopyInto(OstProto::Stream &stream) const; - - void loadConfigWidgets() const; - void storeConfigWidgets() const; - - AbstractProtocol* protocol(int protoNum); - AbstractProtocol* protocol(QString protoName); -}; - -#endif diff --git a/common/protocollist.cpp b/common/protocollist.cpp new file mode 100644 index 0000000..26d2aab --- /dev/null +++ b/common/protocollist.cpp @@ -0,0 +1,8 @@ +#include "protocollist.h" +#include "abstractprotocol.h" + +void ProtocolList::destroy() +{ + while (!isEmpty()) + delete takeFirst(); +} diff --git a/common/protocollist.h b/common/protocollist.h new file mode 100644 index 0000000..bbf2720 --- /dev/null +++ b/common/protocollist.h @@ -0,0 +1,9 @@ +#include + +class AbstractProtocol; + +class ProtocolList : public QLinkedList +{ +public: + void destroy(); +}; diff --git a/common/protocollistiterator.cpp b/common/protocollistiterator.cpp new file mode 100644 index 0000000..20a08ec --- /dev/null +++ b/common/protocollistiterator.cpp @@ -0,0 +1,87 @@ +#include "protocollistiterator.h" +#include "protocollist.h" + +ProtocolListIterator::ProtocolListIterator(ProtocolList &list) +{ + _iter = new QMutableLinkedListIterator(list); +} + +ProtocolListIterator::~ProtocolListIterator() +{ + delete _iter; +} + +bool ProtocolListIterator::findNext(const AbstractProtocol* value) const +{ + return _iter->findNext((AbstractProtocol*)((uint)value)); +} + +bool ProtocolListIterator::findPrevious(const AbstractProtocol* value) +{ + return _iter->findPrevious((AbstractProtocol*)((uint)value)); +} + +bool ProtocolListIterator::hasNext() const +{ + return _iter->hasNext(); +} + +bool ProtocolListIterator::hasPrevious() const +{ + return _iter->hasPrevious(); +} + +void ProtocolListIterator::insert(const AbstractProtocol* value) +{ + _iter->insert((AbstractProtocol*)((uint)value)); +} + +AbstractProtocol* ProtocolListIterator::next() +{ + return _iter->next(); +} + +AbstractProtocol* ProtocolListIterator::peekNext() const +{ + return _iter->peekNext(); +} + +AbstractProtocol* ProtocolListIterator::peekPrevious() const +{ + return _iter->peekPrevious(); +} + +AbstractProtocol* ProtocolListIterator::previous() +{ + return _iter->previous(); +} + +void ProtocolListIterator::remove() +{ + _iter->remove(); +} + +void ProtocolListIterator::setValue(const AbstractProtocol* value) const +{ + _iter->setValue((AbstractProtocol*)((uint)value)); +} + +void ProtocolListIterator::toBack() +{ + _iter->toBack(); +} + +void ProtocolListIterator::toFront() +{ + _iter->toFront(); +} + +const AbstractProtocol* ProtocolListIterator::value() const +{ + return _iter->value(); +} + +AbstractProtocol* ProtocolListIterator::value() +{ + return _iter->value(); +} diff --git a/common/protocollistiterator.h b/common/protocollistiterator.h new file mode 100644 index 0000000..c2dffd3 --- /dev/null +++ b/common/protocollistiterator.h @@ -0,0 +1,29 @@ +#include + +class AbstractProtocol; +class ProtocolList; + +class ProtocolListIterator +{ +private: + QMutableLinkedListIterator *_iter; + +public: + ProtocolListIterator(ProtocolList &list); + ~ProtocolListIterator(); + bool findNext(const AbstractProtocol* value) const; + bool findPrevious(const AbstractProtocol* value); + bool hasNext() const; + bool hasPrevious() const; + void insert(const AbstractProtocol* value); + AbstractProtocol* next(); + AbstractProtocol* peekNext() const; + AbstractProtocol* peekPrevious() const; + AbstractProtocol* previous(); + void remove(); + void setValue(const AbstractProtocol* value) const; + void toBack(); + void toFront(); + const AbstractProtocol* value() const; + AbstractProtocol* value(); +}; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 9041adc..a353796 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -1,5 +1,9 @@ #include "protocolmanager.h" +// FIXME(HI): remove +#include "protocol.pb.h" +#include "abstractprotocol.h" + #include "mac.h" #include "payload.h" @@ -12,9 +16,6 @@ #include "tcp.h" #include "udp.h" -QMap ProtocolManager::factory; -QMap ProtocolManager::nameToNumberMap; - ProtocolManager OstProtocolManager; ProtocolManager::ProtocolManager() @@ -36,5 +37,33 @@ void ProtocolManager::registerProtocol(int protoNumber, QString protoName, { // TODO: validate incoming params for duplicates with existing nameToNumberMap.insert(protoName, protoNumber); + numberToNameMap.insert(protoNumber, protoName); factory.insert(protoNumber, protoInstanceCreator); } + +AbstractProtocol* ProtocolManager::createProtocol(int protoNumber, + StreamBase *stream) +{ + AbstractProtocol* (*pc)(StreamBase*); + AbstractProtocol* p; + + pc = (AbstractProtocol* (*)(StreamBase*)) + factory.value(protoNumber); + + Q_ASSERT(pc != NULL); + + p = (*pc)(stream); + + return p; +} + +AbstractProtocol* ProtocolManager::createProtocol(QString protoName, + StreamBase *stream) +{ + return createProtocol(nameToNumberMap.value(protoName), stream); +} + +QStringList ProtocolManager::protocolDatabase() +{ + return numberToNameMap.values(); +} diff --git a/common/protocolmanager.h b/common/protocolmanager.h index de602fc..ef0a605 100644 --- a/common/protocolmanager.h +++ b/common/protocolmanager.h @@ -2,18 +2,27 @@ #define _PROTOCOL_MANAGER_H #include +#include + +class AbstractProtocol; +class StreamBase; class ProtocolManager { -public: - //! \todo Make these data structures private/protected - static QMap nameToNumberMap; - static QMap factory; + QMap numberToNameMap; + QMap nameToNumberMap; + QMap factory; public: ProtocolManager(); + void registerProtocol(int protoNumber, QString protoName, void *protoCreator); + + AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream); + AbstractProtocol* createProtocol(QString protoName, StreamBase *stream); + + QStringList protocolDatabase(); }; #endif diff --git a/common/sample.cpp b/common/sample.cpp index e92c9fc..17ff0c3 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -3,46 +3,44 @@ #include "sample.h" -SampleConfigForm *SampleProtocol::configForm = NULL; - SampleConfigForm::SampleConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); - } -SampleProtocol::SampleProtocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +SampleProtocol::SampleProtocol(StreamBase *stream); + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new SampleConfigForm; + configForm = NULL; } SampleProtocol::~SampleProtocol() { + delete configForm; } -AbstractProtocol* SampleProtocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* SampleProtocol::createInstance(StreamBase *stream) { return new SampleProtocol(frameProtoList, streamCore); } -void SampleProtocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 SampleProtocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::sample)->CopyFrom(data); + return OstProto::Protocol::kSampleFieldNumber; } -void SampleProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +void SampleProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::sample)) - data.MergeFrom(stream.GetExtension(OstProto::sample)); + protocol.MutableExtension(OstProto::sample)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()) +} + +void SampleProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id()->id() == protocolNumber() && + protocol.HasExtension(OstProto::sample)) + data.MergeFrom(protocol.GetExtension(OstProto::sample)); } QString SampleProtocol::name() const @@ -156,15 +154,21 @@ bool SampleProtocol::setFieldData(int index, const QVariant &value, QWidget* SampleProtocol::configWidget() { + if (configForm == NULL) + configFrom = new SampleConfigForm; + return configForm; } void SampleProtocol::loadConfigWidget() { + configWidget(); } void SampleProtocol::storeConfigWidget() { bool isOk; + + configWidget(); } diff --git a/common/sample.h b/common/sample.h index 9da187d..e02b6bc 100644 --- a/common/sample.h +++ b/common/sample.h @@ -18,7 +18,7 @@ class SampleProtocol : public AbstractProtocol { private: OstProto::Sample data; - static SampleConfigForm *configForm; + SampleConfigForm *configForm; enum samplefield { @@ -26,16 +26,14 @@ private: }; public: - SampleProtocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + SampleProtocol(StreamBase *stream); virtual ~SampleProtocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/snap.cpp b/common/snap.cpp index 46cca1e..0aca641 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -3,45 +3,44 @@ #include "snap.h" -SnapConfigForm *SnapProtocol::configForm = NULL; - SnapConfigForm::SnapConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); } -SnapProtocol::SnapProtocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +SnapProtocol::SnapProtocol(StreamBase *stream) + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new SnapConfigForm; + configForm = NULL; } SnapProtocol::~SnapProtocol() { + delete configForm; } -AbstractProtocol* SnapProtocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* SnapProtocol::createInstance(StreamBase *stream) { - return new SnapProtocol(frameProtoList, streamCore); + return new SnapProtocol(stream); } -void SnapProtocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 SnapProtocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::snap)->CopyFrom(data); + return OstProto::Protocol::kSnapFieldNumber; } -void SnapProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +void SnapProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::snap)) - data.MergeFrom(stream.GetExtension(OstProto::snap)); + protocol.MutableExtension(OstProto::snap)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void SnapProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::snap)) + data.MergeFrom(protocol.GetExtension(OstProto::snap)); } QString SnapProtocol::name() const @@ -140,11 +139,15 @@ bool SnapProtocol::setFieldData(int index, const QVariant &value, QWidget* SnapProtocol::configWidget() { + if (configForm == NULL) + configForm = new SnapConfigForm; return configForm; } void SnapProtocol::loadConfigWidget() { + configWidget(); + configForm->leOui->setText(uintToHexStr( fieldData(snap_oui, FieldValue).toUInt(), 3)); configForm->leType->setText(uintToHexStr( @@ -155,6 +158,8 @@ void SnapProtocol::storeConfigWidget() { bool isOk; + configWidget(); + data.set_oui(configForm->leOui->text().toULong(&isOk, BASE_HEX)); data.set_type(configForm->leType->text().toULong(&isOk, BASE_HEX)); } diff --git a/common/snap.h b/common/snap.h index ba0a3b6..79e2780 100644 --- a/common/snap.h +++ b/common/snap.h @@ -17,7 +17,7 @@ class SnapProtocol : public AbstractProtocol { private: OstProto::Snap data; - static SnapConfigForm *configForm; + SnapConfigForm *configForm; enum snapfield { snap_oui = 0, @@ -27,16 +27,14 @@ private: }; public: - SnapProtocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + SnapProtocol(StreamBase *stream); virtual ~SnapProtocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/snap.proto b/common/snap.proto index c5ea432..957c213 100644 --- a/common/snap.proto +++ b/common/snap.proto @@ -7,6 +7,6 @@ message Snap { optional uint32 type = 2; } -extend Stream { +extend Protocol { optional Snap snap = 124; } diff --git a/common/streambase.cpp b/common/streambase.cpp index 4bd4faf..b98c6c6 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -1,12 +1,47 @@ #include "streambase.h" +#include "abstractprotocol.h" +#include "protocollist.h" +#include "protocollistiterator.h" +#include "protocolmanager.h" + +extern ProtocolManager OstProtocolManager; StreamBase::StreamBase() : mStreamId(new OstProto::StreamId), mCore(new OstProto::StreamCore), - mControl(new OstProto::StreamControl), - protocols(currentFrameProtocols, mCore) + mControl(new OstProto::StreamControl) { + AbstractProtocol *proto; + mStreamId->set_id(0xFFFFFFFF); + + currentFrameProtocols = new ProtocolList; + + // By default newly created streams have the mac and payload protocols + proto = OstProtocolManager.createProtocol("mac", this); + currentFrameProtocols->append(proto); + qDebug("stream: mac = %p", proto); + + proto = OstProtocolManager.createProtocol("payload", this); + currentFrameProtocols->append(proto); + qDebug("stream: payload = %p", proto); + + { + ProtocolListIterator *iter = createProtocolListIterator(); + iter->toFront(); + while (iter->hasNext()) + { + qDebug("{{%p}}", iter->next()); + // qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber()); + } + iter->toFront(); + while (iter->hasNext()) + { + qDebug("{[%d]}", iter->next()->protocolNumber()); + // qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber()); + } + delete iter; + } } StreamBase::~StreamBase() @@ -18,12 +53,20 @@ StreamBase::~StreamBase() void StreamBase::protoDataCopyFrom(const OstProto::Stream &stream) { + AbstractProtocol *proto; + mStreamId->CopyFrom(stream.stream_id()); mCore->CopyFrom(stream.core()); mControl->CopyFrom(stream.control()); - protocols.protoDataCopyFrom(stream); - setFrameProtocol(frameProtocol()); + currentFrameProtocols->destroy(); + for (int i=0; i < stream.protocol_size(); i++) + { + proto = OstProtocolManager.createProtocol( + stream.protocol(i).protocol_id().id(), this); + proto->protoDataCopyFrom(stream.protocol(i)); + currentFrameProtocols->append(proto); + } } void StreamBase::protoDataCopyInto(OstProto::Stream &stream) const @@ -32,38 +75,211 @@ void StreamBase::protoDataCopyInto(OstProto::Stream &stream) const stream.mutable_core()->CopyFrom(*mCore); stream.mutable_control()->CopyFrom(*mControl); - protocols.protoDataCopyInto(stream); -} - -QList StreamBase::frameProtocol() -{ - QList protocolList; - - for (int i = 0; i < mCore->frame_proto_size(); i++) - protocolList.append(mCore->frame_proto(i)); - - return protocolList; -} - -void StreamBase::setFrameProtocol(QList protocolList) -{ - mCore->clear_frame_proto(); - currentFrameProtocols.clear(); - - for (int i = 0; i < protocolList.size(); i++) + stream.clear_protocol(); + foreach (const AbstractProtocol* proto, *currentFrameProtocols) { - mCore->add_frame_proto(protocolList.at(i)); - currentFrameProtocols.append(protocols.protocol(protocolList.at(i))); + OstProto::Protocol *p; + + p = stream.add_protocol(); + proto->protoDataCopyInto(*p); } } -AbstractProtocol* StreamBase::protocol(int protoNum) +#if 0 +ProtocolList StreamBase::frameProtocol() { - return protocols.protocol(protoNum); + return currentFrameProtocols; } -AbstractProtocol* StreamBase::protocol(QString protoName) +void StreamBase::setFrameProtocol(ProtocolList protocolList) { - return protocols.protocol(protoName); + //currentFrameProtocols.destroy(); + currentFrameProtocols = protocolList; +} +#endif + +ProtocolListIterator* StreamBase::createProtocolListIterator() +{ + return new ProtocolListIterator(*currentFrameProtocols); } +bool StreamBase::operator < (const StreamBase &s) const +{ + return(mCore->ordinal() < s.mCore->ordinal()); +} + +quint32 StreamBase::id() +{ + return mStreamId->id(); +} + +bool StreamBase::setId(quint32 id) +{ + mStreamId->set_id(id); + return true; +} + +quint32 StreamBase::ordinal() +{ + return mCore->ordinal(); +} + +bool StreamBase::setOrdinal(quint32 ordinal) +{ + mCore->set_ordinal(ordinal); + return true; +} + +bool StreamBase::isEnabled() const +{ + return mCore->is_enabled(); +} + +bool StreamBase::setEnabled(bool flag) +{ + mCore->set_is_enabled(flag); + return true; +} + +const QString StreamBase::name() const +{ + return QString().fromStdString(mCore->name()); +} + +bool StreamBase::setName(QString name) +{ + mCore->set_name(name.toStdString()); + return true; +} + +StreamBase::FrameLengthMode StreamBase::lenMode() +{ + return (StreamBase::FrameLengthMode) mCore->len_mode(); +} + +bool StreamBase::setLenMode(FrameLengthMode lenMode) +{ + mCore->set_len_mode((OstProto::StreamCore::FrameLengthMode) lenMode); + return true; +} + +quint16 StreamBase::frameLen() +{ + return mCore->frame_len(); +} + +bool StreamBase::setFrameLen(quint16 frameLen) +{ + mCore->set_frame_len(frameLen); + return true; +} + +quint16 StreamBase::frameLenMin() +{ + return mCore->frame_len_min(); +} + +bool StreamBase::setFrameLenMin(quint16 frameLenMin) +{ + mCore->set_frame_len_min(frameLenMin); + return true; +} + +quint16 StreamBase::frameLenMax() +{ + return mCore->frame_len_max(); +} + +bool StreamBase::setFrameLenMax(quint16 frameLenMax) +{ + mCore->set_frame_len_max(frameLenMax); + return true; +} + +StreamBase::SendUnit StreamBase::sendUnit() +{ + return (StreamBase::SendUnit) mControl->unit(); +} +bool StreamBase::setSendUnit(SendUnit sendUnit) +{ + mControl->set_unit((OstProto::StreamControl::SendUnit) sendUnit); + return true; +} + +StreamBase::SendMode StreamBase::sendMode() +{ + return (StreamBase::SendMode) mControl->mode(); +} + +bool StreamBase::setSendMode(SendMode sendMode) +{ + mControl->set_mode( + (OstProto::StreamControl::SendMode) sendMode); + return true; +} + +StreamBase::NextWhat StreamBase::nextWhat() +{ + return (StreamBase::NextWhat) mControl->next(); +} + +bool StreamBase::setNextWhat(NextWhat nextWhat) +{ + mControl->set_next((OstProto::StreamControl::NextWhat) nextWhat); + return true; +} + +quint32 StreamBase::numPackets() +{ + return (quint32) mControl->num_packets(); +} + +bool StreamBase::setNumPackets(quint32 numPackets) +{ + mControl->set_num_packets(numPackets); + return true; +} + +quint32 StreamBase::numBursts() +{ + return (quint32) mControl->num_bursts(); +} + +bool StreamBase::setNumBursts(quint32 numBursts) +{ + mControl->set_num_bursts(numBursts); + return true; +} + +quint32 StreamBase::burstSize() +{ + return (quint32) mControl->packets_per_burst(); +} + +bool StreamBase::setBurstSize(quint32 packetsPerBurst) +{ + mControl->set_packets_per_burst(packetsPerBurst); + return true; +} + +quint32 StreamBase::packetRate() +{ + return (quint32) mControl->packets_per_sec(); +} + +bool StreamBase::setPacketRate(quint32 packetsPerSec) +{ + mControl->set_packets_per_sec(packetsPerSec); + return true; +} + +quint32 StreamBase::burstRate() +{ + return (quint32) mControl->bursts_per_sec(); +} + +bool StreamBase::setBurstRate(quint32 burstsPerSec) +{ + mControl->set_bursts_per_sec(burstsPerSec); + return true; +} diff --git a/common/streambase.h b/common/streambase.h index c8eb2c8..99838d9 100644 --- a/common/streambase.h +++ b/common/streambase.h @@ -1,21 +1,25 @@ #ifndef _STREAM_BASE_H #define _STREAM_BASE_H -#include +#include +#include -#include "protocolcollection.h" +#include "protocol.pb.h" + +class AbstractProtocol; +class ProtocolList; +class ProtocolListIterator; class StreamBase { -protected: // TODO: temp - make private +private: OstProto::StreamId *mStreamId; OstProto::StreamCore *mCore; OstProto::StreamControl *mControl; -private: - ProtocolList currentFrameProtocols; protected: - ProtocolCollection protocols; + //! \todo TODO: Make ProtocolList a private member of StreamBase? + ProtocolList *currentFrameProtocols; public: StreamBase(); @@ -24,13 +28,91 @@ public: void protoDataCopyFrom(const OstProto::Stream &stream); void protoDataCopyInto(OstProto::Stream &stream) const; - QList frameProtocol(); - void setFrameProtocol(QList protocolList); - - AbstractProtocol* protocol(int protoNum); - AbstractProtocol* protocol(QString protoName); + ProtocolListIterator* createProtocolListIterator(); // TODO: make a copy constructor + +public: + enum FrameLengthMode { + e_fl_fixed, + e_fl_inc, + e_fl_dec, + e_fl_random + }; + + enum SendUnit { + e_su_packets, + e_su_bursts + }; + + enum SendMode { + e_sm_fixed, + e_sm_continuous + }; + + enum NextWhat { + e_nw_stop, + e_nw_goto_next, + e_nw_goto_id + }; + + bool operator < (const StreamBase &s) const; + + quint32 id(); + bool setId(quint32 id); + +#if 0 // FIXME(HI): needed? + quint32 portId() + { return mCore->port_id();} + bool setPortId(quint32 id) + { mCore->set_port_id(id); return true;} +#endif + + quint32 ordinal(); + bool setOrdinal(quint32 ordinal); + + bool isEnabled() const; + bool setEnabled(bool flag); + + const QString name() const ; + bool setName(QString name) ; + + // Frame Length (includes FCS); + FrameLengthMode lenMode(); + bool setLenMode(FrameLengthMode lenMode); + + quint16 frameLen(); + bool setFrameLen(quint16 frameLen); + + quint16 frameLenMin(); + bool setFrameLenMin(quint16 frameLenMin); + + quint16 frameLenMax(); + bool setFrameLenMax(quint16 frameLenMax); + + SendUnit sendUnit(); + bool setSendUnit(SendUnit sendUnit); + + SendMode sendMode(); + bool setSendMode(SendMode sendMode); + + NextWhat nextWhat(); + bool setNextWhat(NextWhat nextWhat); + + quint32 numPackets(); + bool setNumPackets(quint32 numPackets); + + quint32 numBursts(); + bool setNumBursts(quint32 numBursts); + + quint32 burstSize(); + bool setBurstSize(quint32 packetsPerBurst); + + quint32 packetRate(); + bool setPacketRate(quint32 packetsPerSec); + + quint32 burstRate(); + bool setBurstRate(quint32 burstsPerSec); }; #endif diff --git a/common/tcp.cpp b/common/tcp.cpp index ab13d54..c3b732b 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -3,45 +3,44 @@ #include "tcp.h" -TcpConfigForm *TcpProtocol::configForm = NULL; - TcpConfigForm::TcpConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); } -TcpProtocol::TcpProtocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +TcpProtocol::TcpProtocol(StreamBase *stream) + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new TcpConfigForm; + configForm = NULL; } TcpProtocol::~TcpProtocol() { + delete configForm; } -AbstractProtocol* TcpProtocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* TcpProtocol::createInstance(StreamBase *stream) { - return new TcpProtocol(frameProtoList, streamCore); + return new TcpProtocol(stream); } -void TcpProtocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 TcpProtocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::tcp)->CopyFrom(data); + return OstProto::Protocol::kTcpFieldNumber; } -void TcpProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +void TcpProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::tcp)) - data.MergeFrom(stream.GetExtension(OstProto::tcp)); + protocol.MutableExtension(OstProto::tcp)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void TcpProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::tcp)) + data.MergeFrom(protocol.GetExtension(OstProto::tcp)); } QString TcpProtocol::name() const @@ -384,11 +383,15 @@ bool TcpProtocol::setFieldData(int index, const QVariant &value, QWidget* TcpProtocol::configWidget() { + if (configForm == NULL) + configForm = new TcpConfigForm; return configForm; } void TcpProtocol::loadConfigWidget() { + configWidget(); + configForm->leTcpSrcPort->setText(QString().setNum(data.src_port())); configForm->leTcpDstPort->setText(QString().setNum(data.dst_port())); @@ -419,6 +422,8 @@ void TcpProtocol::storeConfigWidget() bool isOk; int ff = 0; + configWidget(); + data.set_src_port(configForm->leTcpSrcPort->text().toULong(&isOk)); data.set_dst_port(configForm->leTcpDstPort->text().toULong(&isOk)); diff --git a/common/tcp.h b/common/tcp.h index bfe165b..36edba8 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -24,7 +24,7 @@ class TcpProtocol : public AbstractProtocol { private: OstProto::Tcp data; - static TcpConfigForm *configForm; + TcpConfigForm *configForm; enum tcpfield { tcp_src_port = 0, @@ -45,16 +45,14 @@ private: }; public: - TcpProtocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + TcpProtocol(StreamBase *stream); virtual ~TcpProtocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/tcp.proto b/common/tcp.proto index 8144bad..3cc6135 100644 --- a/common/tcp.proto +++ b/common/tcp.proto @@ -21,7 +21,7 @@ message Tcp { optional uint32 urg_ptr = 11; } -extend Stream { +extend Protocol { optional Tcp tcp = 140; } diff --git a/common/udp.cpp b/common/udp.cpp index 4c642c2..9baae78 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -3,45 +3,44 @@ #include "udp.h" -UdpConfigForm *UdpProtocol::configForm = NULL; - UdpConfigForm::UdpConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); } -UdpProtocol::UdpProtocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +UdpProtocol::UdpProtocol(StreamBase *stream) + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new UdpConfigForm; + configForm = NULL; } UdpProtocol::~UdpProtocol() { + delete configForm; } -AbstractProtocol* UdpProtocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* UdpProtocol::createInstance(StreamBase *stream) { - return new UdpProtocol(frameProtoList, streamCore); + return new UdpProtocol(stream); } -void UdpProtocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 UdpProtocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::udp)->CopyFrom(data); + return OstProto::Protocol::kUdpFieldNumber; } -void UdpProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +void UdpProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::udp)) - data.MergeFrom(stream.GetExtension(OstProto::udp)); + protocol.MutableExtension(OstProto::udp)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void UdpProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::udp)) + data.MergeFrom(protocol.GetExtension(OstProto::udp)); } QString UdpProtocol::name() const @@ -261,11 +260,15 @@ bool UdpProtocol::setFieldData(int index, const QVariant &value, QWidget* UdpProtocol::configWidget() { + if (configForm == NULL) + configForm = new UdpConfigForm; return configForm; } void UdpProtocol::loadConfigWidget() { + configWidget(); + configForm->leUdpSrcPort->setText(fieldData(udp_srcPort, FieldValue).toString()); configForm->leUdpDstPort->setText(fieldData(udp_dstPort, FieldValue).toString()); @@ -281,6 +284,8 @@ void UdpProtocol::storeConfigWidget() { bool isOk; + configWidget(); + data.set_src_port(configForm->leUdpSrcPort->text().toULong(&isOk)); data.set_dst_port(configForm->leUdpDstPort->text().toULong(&isOk)); diff --git a/common/udp.h b/common/udp.h index 0fea509..a2abbed 100644 --- a/common/udp.h +++ b/common/udp.h @@ -17,7 +17,7 @@ class UdpProtocol : public AbstractProtocol { private: OstProto::Udp data; - static UdpConfigForm *configForm; + UdpConfigForm *configForm; enum udpfield { udp_srcPort = 0, @@ -32,16 +32,14 @@ private: }; public: - UdpProtocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + UdpProtocol(StreamBase *stream); virtual ~UdpProtocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/udp.proto b/common/udp.proto index 5f9680d..89e3065 100644 --- a/common/udp.proto +++ b/common/udp.proto @@ -13,6 +13,6 @@ message Udp { optional uint32 cksum = 6; } -extend Stream { +extend Protocol { optional Udp udp = 141; } diff --git a/common/vlan.cpp b/common/vlan.cpp index 7908e8e..f261264 100644 --- a/common/vlan.cpp +++ b/common/vlan.cpp @@ -2,45 +2,44 @@ #include "vlan.h" -VlanConfigForm *VlanProtocol::configForm = NULL; - VlanConfigForm::VlanConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); } -VlanProtocol::VlanProtocol( - ProtocolList &frameProtoList, - OstProto::StreamCore *parent) - : AbstractProtocol(frameProtoList, parent) +VlanProtocol::VlanProtocol(StreamBase *stream) + : AbstractProtocol(stream) { - if (configForm == NULL) - configForm = new VlanConfigForm; + configForm = NULL; } VlanProtocol::~VlanProtocol() { + delete configForm; } -AbstractProtocol* VlanProtocol::createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore) +AbstractProtocol* VlanProtocol::createInstance(StreamBase *stream) { - return new VlanProtocol(frameProtoList, streamCore); + return new VlanProtocol(stream); } -void VlanProtocol::protoDataCopyInto(OstProto::Stream &stream) +quint32 VlanProtocol::protocolNumber() const { - // FIXME: multiple headers - stream.MutableExtension(OstProto::vlan)->CopyFrom(data); + return OstProto::Protocol::kVlanFieldNumber; } -void VlanProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +void VlanProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME: multiple headers - if (stream.HasExtension(OstProto::vlan)) - data.MergeFrom(stream.GetExtension(OstProto::vlan)); + protocol.MutableExtension(OstProto::vlan)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void VlanProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::vlan)) + data.MergeFrom(protocol.GetExtension(OstProto::vlan)); } QString VlanProtocol::name() const @@ -203,22 +202,27 @@ bool VlanProtocol::setFieldData(int index, const QVariant &value, QWidget* VlanProtocol::configWidget() { + if (configForm == NULL) + configForm = new VlanConfigForm; return configForm; } void VlanProtocol::loadConfigWidget() { + configWidget(); + configForm->leTpid->setText(uintToHexStr(fieldData(vlan_tpid, FieldValue).toUInt(), 2)); configForm->cmbPrio->setCurrentIndex(fieldData(vlan_prio, FieldValue).toUInt()); configForm->cmbCfiDei->setCurrentIndex(fieldData(vlan_cfiDei, FieldValue).toUInt()); configForm->leVlanId->setText(fieldData(vlan_vlanId, FieldValue).toString()); - } void VlanProtocol::storeConfigWidget() { bool isOk; + configWidget(); + data.set_is_override_tpid(configForm->cbTpidOverride->isChecked()); data.set_tpid(configForm->leTpid->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); data.set_vlan_tag( diff --git a/common/vlan.h b/common/vlan.h index 23edf44..fedf315 100644 --- a/common/vlan.h +++ b/common/vlan.h @@ -17,7 +17,7 @@ class VlanProtocol : public AbstractProtocol { private: OstProto::Vlan data; - static VlanConfigForm *configForm; + VlanConfigForm *configForm; enum Vlanfield { vlan_tpid, @@ -32,16 +32,14 @@ private: }; public: - VlanProtocol(ProtocolList &frameProtoList, - OstProto::StreamCore *parent = 0); + VlanProtocol(StreamBase *stream); virtual ~VlanProtocol(); - static AbstractProtocol* createInstance( - ProtocolList &frameProtoList, - OstProto::StreamCore *streamCore = 0); + static AbstractProtocol* createInstance(StreamBase *stream); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Stream &stream); - virtual void protoDataCopyFrom(const OstProto::Stream &stream); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); virtual QString name() const; virtual QString shortName() const; diff --git a/common/vlan.proto b/common/vlan.proto index 6703dbc..0232612 100644 --- a/common/vlan.proto +++ b/common/vlan.proto @@ -10,6 +10,6 @@ message Vlan { optional uint32 vlan_tag = 3; // includes prio, cfi and vlanid } -extend Stream { +extend Protocol { optional Vlan vlan = 126; } diff --git a/server/myservice.cpp b/server/myservice.cpp index 546fda5..6d9d2ae 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -1,8 +1,12 @@ -#include "myservice.h" -#include "qdebug.h" #include #include +#include "qdebug.h" + +#include "myservice.h" +#include "../common/protocollist.h" +#include "../common/abstractprotocol.h" + #if 0 #include @@ -26,50 +30,31 @@ StreamInfo::~StreamInfo() { } -#if 0 -quint32 StreamInfo::pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp, - quint8 protocol, quint16 len) -{ - quint32 sum; - - sum = srcIp >> 16; - sum += srcIp & 0xFFFF; - sum += dstIp >> 16; - sum += dstIp & 0xFFFF; - sum += (quint16) (protocol); - sum += len; - - // Above calculation done assuming 'big endian' - so convert to host order - return qFromBigEndian(sum); -} -#endif - - int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) { int pktLen, len = 0; // Decide a frame length based on length mode - switch(mCore->len_mode()) + switch(lenMode()) { case OstProto::StreamCore::e_fl_fixed: - pktLen = mCore->frame_len(); + pktLen = frameLen(); break; case OstProto::StreamCore::e_fl_inc: - pktLen = mCore->frame_len_min() + (n % - (mCore->frame_len_max() - mCore->frame_len_min() + 1)); + pktLen = frameLenMin() + (n % + (frameLenMax() - frameLenMin() + 1)); break; case OstProto::StreamCore::e_fl_dec: - pktLen = mCore->frame_len_max() - (n % - (mCore->frame_len_max() - mCore->frame_len_min() + 1)); + pktLen = frameLenMax() - (n % + (frameLenMax() - frameLenMin() + 1)); break; case OstProto::StreamCore::e_fl_random: - pktLen = mCore->frame_len_min() + (qrand() % - (mCore->frame_len_max() - mCore->frame_len_min() + 1)); + pktLen = frameLenMin() + (qrand() % + (frameLenMax() - frameLenMin() + 1)); break; default: qWarning("Unhandled len mode %d. Using default 64", - mCore->len_mode()); + lenMode()); pktLen = 64; break; } @@ -81,11 +66,11 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) return 0; // FIXME: Calculated pktLen is an input to Payload Protocol - for (int i = 0; i < mCore->frame_proto_size(); i++) + foreach(const AbstractProtocol* proto, *currentFrameProtocols) { QByteArray ba; - ba = protocol(mCore->frame_proto(i))->protocolFrameValue(n); + ba = proto->protocolFrameValue(n); if (len + ba.size() < bufMaxSize) { memcpy(buf+len, ba.constData(), ba.size()); @@ -94,379 +79,6 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) } return pktLen; - -#if 0 // Proto FW - int u, pktLen, dataLen, len = 0; - quint32 srcIp, dstIp; // need it later for TCP/UDP cksum calculation - quint32 cumCksum = 0; // cumulative cksum used to combine partial cksums - int tcpOfs, udpOfs; // needed to fill in cksum later - uchar scratch[8]; - - // We always have a Mac Header! - switch (d.mac().dst_mac_mode()) - { - case OstProto::Mac::e_mm_fixed: - qToBigEndian((quint64) d.mac().dst_mac(), scratch); - break; - case OstProto::Mac::e_mm_inc: - u = (n % d.mac().dst_mac_count()) * d.mac().dst_mac_step(); - qToBigEndian((quint64) d.mac().dst_mac() + u, scratch); - break; - case OstProto::Mac::e_mm_dec: - u = (n % d.mac().dst_mac_count()) * d.mac().dst_mac_step(); - qToBigEndian((quint64) d.mac().dst_mac() - u, scratch); - break; - default: - qWarning("Unhandled dstMac_mode %d", d.mac().dst_mac_mode()); - } - memcpy((buf + len), scratch + 2, 6); - len += 6; - - switch (d.mac().src_mac_mode()) - { - case OstProto::Mac::e_mm_fixed: - qToBigEndian((quint64) d.mac().src_mac(), scratch); - break; - case OstProto::Mac::e_mm_inc: - u = (n % d.mac().src_mac_count()) * d.mac().src_mac_step(); - qToBigEndian((quint64) d.mac().src_mac() + u, scratch); - break; - case OstProto::Mac::e_mm_dec: - u = (n % d.mac().src_mac_count()) * d.mac().src_mac_step(); - qToBigEndian((quint64) d.mac().src_mac() - u, scratch); - break; - default: - qWarning("Unhandled srcMac_mode %d", d.mac().src_mac_mode()); - } - memcpy((buf + len), scratch + 2, 6); - len += 6; - - - // Frame Type - Part 1 (pre VLAN info) - switch(d.core().ft()) - { - case OstProto::StreamCore::e_ft_none: - case OstProto::StreamCore::e_ft_eth_2: - break; - case OstProto::StreamCore::e_ft_802_3_raw: - qToBigEndian((quint16) pktLen, buf+len); - len += 2; - break; - case OstProto::StreamCore::e_ft_802_3_llc: - qToBigEndian((quint16) pktLen, buf+len); - len += 2; - buf[len+0] = (quint8) d.llc().dsap(); - buf[len+1] = (quint8) d.llc().ssap(); - buf[len+2] = (quint8) d.llc().ctl(); - len +=3; - break; - case OstProto::StreamCore::e_ft_snap: - qToBigEndian((quint16) pktLen, buf+len); - len += 2; - buf[len+0] = (quint8) d.llc().dsap(); - buf[len+1] = (quint8) d.llc().ssap(); - buf[len+2] = (quint8) d.llc().ctl(); - len +=3; - qToBigEndian((quint32) d.snap().oui(), scratch); - memcpy((buf + len), scratch + 2, 3); - len += 3; - break; - default: - qWarning("Unhandled frame type %d\n", d.core().ft()); - } - - // VLAN - if (d.vlan().is_svlan_tagged()) - { - if (d.vlan().is_stpid_override()) - qToBigEndian((quint16) d.vlan().stpid(), buf+len); - else - qToBigEndian((quint16) 0x88a8, buf+len); - len += 2 ; - - qToBigEndian((quint16) d.vlan().svlan_tag(), buf+len); - len += 2 ; - } - - if (d.vlan().is_cvlan_tagged()) - { - if (d.vlan().is_ctpid_override()) - qToBigEndian((quint16) d.vlan().ctpid(), buf+len); - else - qToBigEndian((quint16) 0x8100, buf+len); - len += 2 ; - - qToBigEndian((quint16) d.vlan().cvlan_tag(), buf+len); - len += 2 ; - } - - // Frame Type - Part 2 (post VLAN info) - switch(d.core().ft()) - { - case OstProto::StreamCore::e_ft_none: - break; - case OstProto::StreamCore::e_ft_eth_2: - qToBigEndian((quint16) d.eth2().type(), buf+len); - len += 2; - break; - case OstProto::StreamCore::e_ft_802_3_raw: - case OstProto::StreamCore::e_ft_802_3_llc: - break; - case OstProto::StreamCore::e_ft_snap: - qToBigEndian((quint16) d.eth2().type(), buf+len); - len += 2; - break; - default: - qWarning("Unhandled frame type %d\n", d.core().ft()); - } - - // L3 - switch (d.core().l3_proto()) - { - case OstProto::StreamCore::e_l3_none: - break; - case OstProto::StreamCore::e_l3_ip: - { - quint32 subnet, host; - int ipOfs = len; - - buf[len+0] = (quint8) (d.ip().ver_hdrlen()); - buf[len+1] = (quint8) (d.ip().tos()); - len += 2; - - if (d.ip().is_override_totlen()) - qToBigEndian((quint16) d.ip().tot_len(), buf+len); - else - qToBigEndian((quint16) (pktLen - ipOfs), buf+len); - len += 2; - - qToBigEndian((quint16) d.ip().id(), buf+len); - len += 2; - - qToBigEndian((quint16) (( (d.ip().flags() & 0x3) << 13) | - (d.ip().frag_ofs() & 0x1FFF)), buf+len); - len += 2; - - buf[len+0] = (quint8) (d.ip().ttl()); - buf[len+1] = (quint8) (d.ip().proto()); - len += 2; - - // cksum calculated after filling in the rest - qToBigEndian((quint16) 0, buf+len); - len += 2; - - // Get Src/Dst IP for this packet using respective IpMode - switch(d.ip().src_ip_mode()) - { - case OstProto::Ip::e_im_fixed: - srcIp = (quint32) d.ip().src_ip(); - qToBigEndian(srcIp, buf+len); - break; - case OstProto::Ip::e_im_inc_host: - u = n % d.ip().src_ip_count(); - subnet = d.ip().src_ip() & d.ip().src_ip_mask(); - host = (((d.ip().src_ip() & ~d.ip().src_ip_mask()) + u) & - ~d.ip().src_ip_mask()); - srcIp = (quint32) (subnet | host); - qToBigEndian(srcIp, buf+len); - break; - case OstProto::Ip::e_im_dec_host: - u = n % d.ip().src_ip_count(); - subnet = d.ip().src_ip() & d.ip().src_ip_mask(); - host = (((d.ip().src_ip() & ~d.ip().src_ip_mask()) - u) & - ~d.ip().src_ip_mask()); - srcIp = (quint32) (subnet | host); - qToBigEndian(srcIp, buf+len); - break; - case OstProto::Ip::e_im_random_host: - subnet = d.ip().src_ip() & d.ip().src_ip_mask(); - host = (qrand() & ~d.ip().src_ip_mask()); - srcIp = (quint32) (subnet | host); - qToBigEndian(srcIp, buf+len); - break; - default: - qWarning("Unhandled src_ip_mode = %d", d.ip().src_ip_mode()); - } - len +=4; - - switch(d.ip().dst_ip_mode()) - { - case OstProto::Ip::e_im_fixed: - dstIp = (quint32) d.ip().dst_ip(); - qToBigEndian(dstIp, buf+len); - break; - case OstProto::Ip::e_im_inc_host: - u = n % d.ip().dst_ip_count(); - subnet = d.ip().dst_ip() & d.ip().dst_ip_mask(); - host = (((d.ip().dst_ip() & ~d.ip().dst_ip_mask()) + u) & - ~d.ip().dst_ip_mask()); - dstIp = (quint32) (subnet | host); - qToBigEndian(dstIp, buf+len); - break; - case OstProto::Ip::e_im_dec_host: - u = n % d.ip().dst_ip_count(); - subnet = d.ip().dst_ip() & d.ip().dst_ip_mask(); - host = (((d.ip().dst_ip() & ~d.ip().dst_ip_mask()) - u) & - ~d.ip().dst_ip_mask()); - dstIp = (quint32) (subnet | host); - qToBigEndian(dstIp, buf+len); - break; - case OstProto::Ip::e_im_random_host: - subnet = d.ip().dst_ip() & d.ip().dst_ip_mask(); - host = (qrand() & ~d.ip().dst_ip_mask()); - dstIp = (quint32) (subnet | host); - qToBigEndian(dstIp, buf+len); - break; - default: - qWarning("Unhandled dst_ip_mode = %d", d.ip().dst_ip_mode()); - } - len +=4; - - // Calculate and fill in cksum (unless overridden) - if (d.ip().is_override_cksum()) - qToBigEndian((quint16) d.ip().cksum(), buf+ipOfs+10); - else - *((quint16*)(buf + ipOfs + 10)) = ipv4Cksum(buf + ipOfs, len-ipOfs); - break; - - } - case OstProto::StreamCore::e_l3_arp: - // TODO(LOW) - break; - default: - qWarning("Unhandled l3 proto %d\n", d.core().l3_proto()); - } - - switch (d.core().l4_proto()) - { - case OstProto::StreamCore::e_l4_none: - break; - case OstProto::StreamCore::e_l4_tcp: - { - tcpOfs = len; - - cumCksum = pseudoHdrCksumPartial(srcIp, dstIp, 6, pktLen - len); - - qToBigEndian((quint16) d.tcp().src_port(), buf+len); - len += 2; - qToBigEndian((quint16) d.tcp().dst_port(), buf+len); - len += 2; - - qToBigEndian((quint32) d.tcp().seq_num(), buf+len); - len += 4; - qToBigEndian((quint32) d.tcp().ack_num(), buf+len); - len += 4; - - if (d.tcp().is_override_hdrlen()) - buf[len+0] = (quint8) d.tcp().hdrlen_rsvd(); - else - buf[len+0] = (quint8) 0x50; // FIXME(LOW): Hardcoding - buf[len+1] = (quint8) d.tcp().flags(); - len += 2; - - qToBigEndian((quint16) d.tcp().window(), buf+len); - len +=2; - - // Fill in cksum as 0 for cksum calculation, actual cksum filled later - qToBigEndian((quint16) 0, buf+len); - len +=2; - - qToBigEndian((quint16) d.tcp().urg_ptr(), buf+len); - len +=2; - - // Accumulate cumulative cksum - cumCksum += ipv4CksumPartial(buf + tcpOfs, len - tcpOfs); - - break; - } - case OstProto::StreamCore::e_l4_udp: - { - udpOfs = len; - - cumCksum = pseudoHdrCksumPartial(srcIp, dstIp, 17, pktLen - len); - - qToBigEndian((quint16) d.udp().src_port(), buf+len); - len += 2; - qToBigEndian((quint16) d.udp().dst_port(), buf+len); - len += 2; - - if (d.udp().is_override_totlen()) - qToBigEndian((quint16) d.udp().totlen(), buf+len); - else - qToBigEndian((quint16) (pktLen - udpOfs), buf+len); - len +=2; - - // Fill in cksum as 0 for cksum calculation, actual cksum filled later - qToBigEndian((quint16) 0, buf+len); - len +=2; - - // Accumulate cumulative cksum - cumCksum += ipv4CksumPartial(buf + udpOfs, len - udpOfs); - - break; - } - case OstProto::StreamCore::e_l4_icmp: - // TODO(LOW) - break; - case OstProto::StreamCore::e_l4_igmp: - // TODO(LOW) - break; - default: - qWarning("Unhandled l4 proto %d\n", d.core().l4_proto()); - } - - // Fill-in the data pattern - dataLen = pktLen - len; - switch(d.core().pattern_mode()) - { - case OstProto::StreamCore::e_dp_fixed_word: - for (int i = 0; i < (dataLen/4)+1; i++) - qToBigEndian((quint32) d.core().pattern(), buf+len+(i*4)); - break; - case OstProto::StreamCore::e_dp_inc_byte: - for (int i = 0; i < dataLen; i++) - buf[len + i] = i % (0xFF + 1); - break; - case OstProto::StreamCore::e_dp_dec_byte: - for (int i = 0; i < dataLen; i++) - buf[len + i] = 0xFF - (i % (0xFF + 1)); - break; - case OstProto::StreamCore::e_dp_random: - for (int i = 0; i < dataLen; i++) - buf[len + i] = qrand() % (0xFF + 1); - break; - default: - qWarning("Unhandled data pattern %d", d.core().pattern_mode()); - } -#endif - -#if 0 // Proto FW - // Calculate TCP/UDP checksum over the data pattern/payload and fill in - switch (d.core().l4_proto()) - { - case OstProto::StreamCore::e_l4_tcp: - if (d.tcp().is_override_cksum()) - qToBigEndian((quint16) d.tcp().cksum(), buf + tcpOfs + 16); - else - *((quint16*)(buf + tcpOfs + 16)) = - ipv4Cksum(buf + len, dataLen, cumCksum); - break; - case OstProto::StreamCore::e_l4_udp: - if (d.udp().is_override_cksum()) - qToBigEndian((quint16) d.udp().cksum(), buf + udpOfs + 6); - else - *((quint16*)(buf + udpOfs + 6)) = - ipv4Cksum(buf + len, dataLen, cumCksum); - break; - case OstProto::StreamCore::e_l4_none: - case OstProto::StreamCore::e_l4_icmp: - case OstProto::StreamCore::e_l4_igmp: - // No cksum processing required - break; - } - return pktLen; -#endif - } @@ -589,28 +201,28 @@ void PortInfo::update() for (int i = 0; i < streamList.size(); i++) { //_restart: - if (streamList[i]->mCore->is_enabled()) + if (streamList[i]->isEnabled()) { long numPackets, numBursts; long ibg, ipg; - switch (streamList[i]->mControl->unit()) + switch (streamList[i]->sendUnit()) { case OstProto::StreamControl::e_su_bursts: - numBursts = streamList[i]->mControl->num_bursts(); - numPackets = streamList[i]->mControl->packets_per_burst(); - ibg = 1000000/streamList[i]->mControl->bursts_per_sec(); + numBursts = streamList[i]->numBursts(); + numPackets = streamList[i]->burstSize(); + ibg = 1000000/streamList[i]->burstRate(); ipg = 0; break; case OstProto::StreamControl::e_su_packets: numBursts = 1; - numPackets = streamList[i]->mControl->num_packets(); + numPackets = streamList[i]->numPackets(); ibg = 0; - ipg = 1000000/streamList[i]->mControl->packets_per_sec(); + ipg = 1000000/streamList[i]->packetRate(); break; default: qWarning("Unhandled stream control unit %d", - streamList[i]->mControl->unit()); + streamList[i]->sendUnit()); continue; } qDebug("numBursts = %ld, numPackets = %ld\n", @@ -672,7 +284,7 @@ void PortInfo::update() } } // for (numBursts) - switch(streamList[i]->mControl->next()) + switch(streamList[i]->nextWhat()) { case ::OstProto::StreamControl::e_nw_stop: goto _stop_no_more_pkts; @@ -697,7 +309,7 @@ void PortInfo::update() default: qFatal("---------- %s: Unhandled case (%d) -----------", - __FUNCTION__, streamList[i]->mControl->next() ); + __FUNCTION__, streamList[i]->nextWhat() ); break; } From 4c2df3c5a7c794a8b3a6fcd0d7bb79fcbaeb0b20 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 23 Sep 2009 14:53:26 +0000 Subject: [PATCH 24/98] Protocols --------- - all protocols on allocation of a configWidget, also populate it before returning from configWidget() - VLAN TPID override is now correctly saved and restored from/to its widget (vlan.cpp) - Payload protocol returns a minimum frame value of 1 byte size (Hack to avoid crash in stream config dialog when sum of all protocol frame sizes is greater than the frame length - small layout changes in mac widget (mac.ui) - src/dst ip mask changed from 255.255.255.255 to 255.255.255.0 (ip4.proto) - src mac changed from u32 to u64 (mac.proto) - "Combo Protocol" protocol container introduced to define newer protocols as a combination of existing protocols e.g. dot2 = dot3 + llc - THIS IS NOT YET COMPLETE (comboprotocol.h) Client/StreamConfigDialog ------------------------- - Advanced Protocol Selection implemented - Simple Protocol Selection rewritten to work alongside Advanced - Payload Widget is treated like any other protocol - hence it is not placedinto the dialog specially - Any protocol selection change (in Simple/Advanced mode) immediately triggers change in the Stream's protocolList - Protocol Widgets now are arranged in a toolBox on a top level tab of the dialog instead of a nested tabWidget - Vlan selection (Simple Mode) uses Radio buttons instead of checkboxes - Double Tagged (SVlan + CVlan) now works via Simple Mode --- client/icons/arrow_down.png | Bin 0 -> 379 bytes client/icons/arrow_right.png | Bin 0 -> 349 bytes client/icons/arrow_up.png | Bin 0 -> 372 bytes client/icons/delete.png | Bin 0 -> 715 bytes client/ostinato.qrc | 4 + client/streamconfigdialog.cpp | 1469 +++++++++++++++++++++------------ client/streamconfigdialog.h | 40 +- client/streamconfigdialog.ui | 821 ++++++++++-------- common/comboprotocol.h | 133 +++ common/dot3.cpp | 3 + common/eth2.cpp | 3 + common/ip4.cpp | 3 + common/ip4.proto | 4 +- common/llc.cpp | 3 + common/mac.cpp | 3 + common/mac.proto | 2 +- common/mac.ui | 335 ++++---- common/ostproto.pro | 1 + common/payload.cpp | 8 + common/sample.cpp | 5 +- common/snap.cpp | 3 + common/tcp.cpp | 3 + common/udp.cpp | 3 + common/vlan.cpp | 4 + 24 files changed, 1782 insertions(+), 1068 deletions(-) create mode 100644 client/icons/arrow_down.png create mode 100644 client/icons/arrow_right.png create mode 100644 client/icons/arrow_up.png create mode 100644 client/icons/delete.png create mode 100644 common/comboprotocol.h diff --git a/client/icons/arrow_down.png b/client/icons/arrow_down.png new file mode 100644 index 0000000000000000000000000000000000000000..2c4e279377bf348f9cf53894e76bb673ccf067bd GIT binary patch literal 379 zcmV->0fhdEP)RB*?~^j!LKVQ>(O&A{Xr%)RXLn#U zs4LtZ6rCMFY5|B2$)yG$6aaIFo>#A+qW*AYQLZl(!&BX$x7Ik;qO170ssEM z@$bKXf%rGW?|(r27bf-TSv zD}TdX0CM*JhkLO)8|Y^+n~Q^sK~hqR;q|N647YFGy>NTZJsWr!5CaSfwJm@a><8NX v2&h?|6w#wHUuW*nL5>vZR zlg{G&%mT~|kL3ei%GW0*UOHUMs5XI$4uxe-L?I@SAefq*207}Iqtjm#e5*fP53AiC z)C|RQfwzxx<#_WfANRGZx{+tFDl8~Q?;~Ve=lM^*8UTTnVL?HTDz8uta0D@d28E9S z_)i8aLz^UE6PPKymi;2GJ`34{eIia-CtfAt0H61rk0 SPTNud0000C4}Mrzlg<+1Y8PEBfUp0jJpx4B>@E+cy3`^(Gw`Mf+2&yxZm<$to~Vpgvg&QKNR z_f#1(r6svZt%iF?s+n<8X?B&!h3g9Dbb8_=MX}!;HiQSAh`bp^WMl~Z-44teO7W_Y zV4thSL{h;rJY7!l3%5J4H1!tIzB`Dv+YxO(haWeausGZYkI8^hWj6mzo=L0{%;yxzh{5!Htr?51 zvG|W62MzC8BZ76hRpCyO2zOn<%e)K>NHge!-~)Ap33OdWw6hsLYbCxGNt0%wk_2z7 zfyYvXheSG)5HRK1VB~%mq7Dmurw#bi@hEcOr3&G1ZiF*$M=&9nB#VNf&Q^r$4G5kp zTURh&s)E0%5&hyVD}sp<72~zmAY`Y(9aqO6CXF%=zFHGzO-A&I(pE}v70YQxCPJ{Y z4L+?5-crdLn3ZRPEs!A4ehEY3ZRpL~w9>@aMN+{F4dI@v&>(QDHQum!mG~E^$OS8l z!7?%Uwib*ROP67Hw`ika)gX-(8Ia`-u_IEhxG7U<13kSsMW+$lbb2dUMm5p6pa}cjgA+U$^mJ^AjD?&bdi)8~y+Q002ovPDHLkV1g8IMc@Dc literal 0 HcmV?d00001 diff --git a/client/ostinato.qrc b/client/ostinato.qrc index 7b735f7..48ab66a 100644 --- a/client/ostinato.qrc +++ b/client/ostinato.qrc @@ -1,5 +1,8 @@ + icons/arrow_down.png + icons/arrow_right.png + icons/arrow_up.png icons/bullet_error.png icons/bullet_green.png icons/bullet_orange.png @@ -7,6 +10,7 @@ icons/bullet_yellow.png icons/control_play.png icons/control_stop.png + icons/delete.png icons/magnifier.png icons/portgroup_add.png icons/portgroup_connect.png diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 0c5fc73..98bc612 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -12,7 +12,6 @@ extern ProtocolManager OstProtocolManager; int StreamConfigDialog::lastTopLevelTabIndex = 0; -int StreamConfigDialog::lastProtoTabIndex = 0; StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent) : QDialog (parent), mPort(port) @@ -23,17 +22,22 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyInto(s); mpStream->protoDataCopyFrom(s); _iter = mpStream->createProtocolListIterator(); + isUpdateInProgress = false; setupUi(this); setupUiExtra(); connect(bgFrameType, SIGNAL(buttonClicked(int)), - this, SLOT(updateContents())); + this, SLOT(updateFrameTypeProtocol(int))); + connect(bgVlan, SIGNAL(buttonClicked(int)), + this, SLOT(updateVlanProtocol(int))); connect(bgL3Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateContents())); + this, SLOT(updateL3Protocol(int))); connect(bgL4Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateContents())); - + this, SLOT(updateL4Protocol(int))); + connect(bgPayloadProto, SIGNAL(buttonClicked(int)), + this, SLOT(updatePayloadProtocol(int))); + //! \todo causes a crash! #if 0 connect(lePktLen, SIGNAL(textEdited(QString)), @@ -44,8 +48,9 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // Enable VLAN Choices only if FT = Eth2 or SNAP connect(rbFtNone, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool))); - - connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); + connect(rbFtOther, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool))); + connect(rbFtNone, SIGNAL(clicked(bool)), rbVlanNone, SLOT(click())); + connect(rbFtNone, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); // Enable/Disable L3 Protocol Choices for FT None connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); @@ -58,7 +63,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); // Force L3 = None if FT = 802.3 Raw - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); + connect(rbFt802Dot3Raw, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); // Enable/Disable L3 Protocol Choices for FT 802Dot3Raw connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); @@ -66,7 +71,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); // Force L3 = None if FT = 802.3 LLC (to ensure a valid L3 is selected) - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); + connect(rbFt802Dot3Llc, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); // Enable/Disable L3 Protocol Choices for FT 802Dot3Llc connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); @@ -78,6 +83,10 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); + // Force L3 = Other if FT = Other + connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool))); + connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool))); + // Enable/Disable L4 Protocol Choices for L3 Protocol None connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); connect(rbL3None, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool))); @@ -86,7 +95,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbL3None, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool))); // Force L4 Protocol = None if L3 Protocol is set to None - connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool))); + connect(rbL3None, SIGNAL(clicked(bool)), rbL4None, SLOT(click())); // Enable/Disable L4 Protocol Choices for L3 Protocol IPv4 connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); @@ -103,11 +112,31 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool))); // Force L4 Protocol = None if L3 Protocol is set to ARP - connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool))); + connect(rbL3Arp, SIGNAL(clicked(bool)), rbL4None, SLOT(click())); + + // Force L4 = Other if L3 = Other + connect(rbL3Other, SIGNAL(toggled(bool)), rbL4Other, SLOT(setChecked(bool))); + connect(rbL3Other, SIGNAL(toggled(bool)), gbL4Proto, SLOT(setDisabled(bool))); + + // Force Payload = Other if L4 = Other + connect(rbL4Other, SIGNAL(toggled(bool)), rbPayloadOther, SLOT(setChecked(bool))); + connect(rbL4Other, SIGNAL(toggled(bool)), gbPayloadProto, SLOT(setDisabled(bool))); mpAvailableProtocolsModel = new QStringListModel( OstProtocolManager.protocolDatabase(), this); lvAllProtocols->setModel(mpAvailableProtocolsModel); + mpSelectedProtocolsModel = new QStringListModel(this); + lvSelectedProtocols->setModel(mpSelectedProtocolsModel); + + + connect(lvAllProtocols->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, SLOT(when_lvAllProtocols_selectionChanged( + const QItemSelection&, const QItemSelection&))); + connect(lvSelectedProtocols->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_lvSelectedProtocols_currentChanged(const QModelIndex&, + const QModelIndex&))); LoadCurrentStream(); mpPacketModel = new PacketModel(this); @@ -119,8 +148,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // TODO(MED): - //! \todo Implement then enable these protocols - SVLAN, ARP, ICMP, IGMP - cbSVlan->setHidden(true); + //! \todo Implement then enable these protocols - ARP, IPv6, ICMP, IGMP rbL3Arp->setHidden(true); rbL3Ipv6->setHidden(true); rbL4Icmp->setHidden(true); @@ -136,8 +164,6 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // Finally, restore the saved last selected tab for the various tab widgets twTopLevel->setCurrentIndex(lastTopLevelTabIndex); - if (twProto->isTabEnabled(lastProtoTabIndex)) - twProto->setCurrentIndex(lastProtoTabIndex); } void StreamConfigDialog::setupUiExtra() @@ -146,53 +172,66 @@ void StreamConfigDialog::setupUiExtra() QRegExp reHex4B("[0-9,a-f,A-F]{1,8}"); QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); -#if 0 // MPS - temp mask - // Add the Payload widget to the dialog - { - QGridLayout *layout; - - layout = static_cast(twTopLevel->widget(0)->layout()); - - layout->addWidget(mpStream->protocol(52)->configWidget(), 0, 1); - qDebug("setupUi wgt = %p", mpStream->protocol(52)->configWidget()); - } -#endif - // ---- Setup default stuff that cannot be done in designer ---- gbVlan->setDisabled(true); bgFrameType = new QButtonGroup(); +#if 0 foreach(QRadioButton *btn, gbFrameType->findChildren()) bgFrameType->addButton(btn); +#else + bgFrameType->addButton(rbFtNone, 0); + bgFrameType->addButton(rbFtEthernet2, 121); + bgFrameType->addButton(rbFt802Dot3Raw, 122); + bgFrameType->addButton(rbFt802Dot3Llc, 123); + bgFrameType->addButton(rbFtLlcSnap, 124); + bgFrameType->addButton(rbFtOther, -1); +#endif + + bgVlan = new QButtonGroup(); + bgVlan->addButton(rbVlanNone, 0); + bgVlan->addButton(rbVlanSingle, 126); + bgVlan->addButton(rbVlanDouble, 127); bgL3Proto = new QButtonGroup(); +#if 0 foreach(QRadioButton *btn, gbL3Proto->findChildren()) bgL3Proto->addButton(btn); +#else + bgL3Proto->addButton(rbL3None, 0); + bgL3Proto->addButton(rbL3Ipv4, 130); + bgL3Proto->addButton(rbL3Ipv6, -1); + bgL3Proto->addButton(rbL3Arp, -1); + bgL3Proto->addButton(rbL3Other, -1); +#endif bgL4Proto = new QButtonGroup(); +#if 0 foreach(QRadioButton *btn, gbL4Proto->findChildren()) bgL4Proto->addButton(btn); +#else + bgL4Proto->addButton(rbL4None, 0); + bgL4Proto->addButton(rbL4Tcp, 140); + bgL4Proto->addButton(rbL4Udp, 141); + bgL4Proto->addButton(rbL4Icmp, -1); + bgL4Proto->addButton(rbL4Igmp, -1); + bgL4Proto->addButton(rbL4Other, -1); +#endif - //twProto->setTabEnabled(2, FALSE); - //twProto->setTabEnabled(3, FALSE); - + bgPayloadProto = new QButtonGroup(); +#if 0 + foreach(QRadioButton *btn, gbPayloadProto->findChildren()) + bgPayloadProto->addButton(btn); +#else + bgPayloadProto->addButton(rbPayloadPattern, 52); + bgPayloadProto->addButton(rbPayloadOther, -1); +#endif /* ** Setup Validators */ // Meta Data //! \todo - doesn't seem to work - range validator needs a spinbox? //lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); - - // L2 Ethernet -#if 0 // Proto FW - leDstMac->setValidator(new QRegExpValidator(reMac, this)); - leSrcMac->setValidator(new QRegExpValidator(reMac, this)); - leDstMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); - leSrcMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); - leCvlanTpid->setValidator(new QRegExpValidator(reHex2B, this)); - leSvlanTpid->setValidator(new QRegExpValidator(reHex2B, this)); - //leEtherType->setValidator(new QRegExpValidator(reHex2B, this)); -#endif /* ** Setup Connections @@ -213,138 +252,16 @@ StreamConfigDialog::~StreamConfigDialog() delete mpPacketModelTester; delete mpPacketModel; -#if 0 // MPS - temp mask - // Remove payload data widget so that it is not deleted when this object - // is destroyed - { - QLayout *layout = twTopLevel->widget(0)->layout(); - if (layout) - { - layout->removeWidget(mpStream->protocol(52)->configWidget()); - mpStream->protocol(52)->configWidget()->setParent(0); - } - } -#endif - - // Remove any existing widget on the L2-L4 Tabs lest they are deleted - // when this object is destoryed - for (int i = 1; i <= 3; i++) - { - QLayout *layout = twProto->widget(i)->layout(); - if (layout) - { - QLayoutItem *child; - while ((child = layout->takeAt(0)) != 0) - { - Q_ASSERT(child->widget() != 0); - // Don't delete the child widget - reparent it - child->widget()->setParent(0); - } - delete layout; - } - } - delete bgFrameType; + delete bgVlan; delete bgL3Proto; delete bgL4Proto; + delete bgPayloadProto; delete _iter; delete mpStream; } -void StreamConfigDialog::updateSelectedProtocols() -{ -#define CHKINS(p) \ -{ \ - if (_iter->hasNext() && (_iter->peekNext()->protocolNumber() == OstProto::Protocol::k##p##FieldNumber)) \ - _iter->next(); \ - else \ - _iter->insert(OstProtocolManager.createProtocol(OstProto::Protocol::k##p##FieldNumber, mpStream)); \ -} - - _iter->toFront(); -#if 1 - qDebug("Before Update"); - while (_iter->hasNext()) - { - AbstractProtocol* p; - - p = _iter->next(); - qDebug("%p:[%d]", p, p->protocolNumber()); - } - - _iter->toFront(); -#endif - - // Mac - CHKINS(Mac) - - if (cbCVlan->isEnabled() && cbCVlan->isChecked()) - CHKINS(Vlan); - - if (rbFtEthernet2->isChecked()) - CHKINS(Eth2) - else if (rbFt802Dot3Raw->isChecked()) - CHKINS(Dot3) - else if (rbFt802Dot3Llc->isChecked()) - { - CHKINS(Dot3); - CHKINS(Llc); - } - else if (rbFtLlcSnap->isChecked()) - { - CHKINS(Dot3); - CHKINS(Llc); - CHKINS(Snap); - } - - if (rbL3Ipv4->isChecked()) - CHKINS(Ip4) - else if (rbL3Arp->isChecked()) - CHKINS(Arp) - - if (rbL4Tcp->isChecked()) - CHKINS(Tcp) - else if (rbL4Udp->isChecked()) - CHKINS(Udp) - else if (rbL4Icmp->isChecked()) - CHKINS(Icmp) - else if (rbL4Igmp->isChecked()) - CHKINS(Igmp) - - // Payload - CHKINS(Payload) - - // Remove all protocols, if any, beyond payload - while (_iter->hasNext()) - { - _iter->next(); - _iter->remove(); - } - - -#if 1 - qDebug("After Update"); - _iter->toFront(); - while (_iter->hasNext()) - { - AbstractProtocol* p; - - p = _iter->next(); - qDebug("%p:[%d]", p, p->protocolNumber()); - } -#endif - -#undef CHKINS - -} - -void StreamConfigDialog::updateContents() -{ - StoreCurrentStream(); - LoadCurrentStream(); -} - void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode) { if (mode == "Fixed") @@ -401,152 +318,232 @@ void StreamConfigDialog::on_pbNext_clicked() #endif } -void StreamConfigDialog::on_twTopLevel_currentChanged(int index) +void StreamConfigDialog::on_tbSelectProtocols_currentChanged(int index) { - // We only process the "Packet View" tab - if (index != 2) - return; - - updateContents(); - mpPacketModel->setSelectedProtocols(*_iter); + qDebug("%s, index = %d", __FUNCTION__, index); + switch (index) + { + case 0: + updateSelectProtocolsSimpleWidget(); + break; + case 1: + updateSelectProtocolsAdvancedWidget(); + break; + default: + qFatal("%s: unexpected index = %d", __FUNCTION__, index); + } } -void StreamConfigDialog::on_twProto_currentChanged(int index) +void StreamConfigDialog::when_lvAllProtocols_selectionChanged( + const QItemSelection &selected, const QItemSelection &deselected) { -#if 0 // MPS - temp mask - QLayout *layout; - QList wl; + int size = lvAllProtocols->selectionModel()->selectedIndexes().size(); - // We need to process only indices 1-3 i.e. the L2, L3 and L4 tabs - if ((index < 1) || (index > 3)) + qDebug("%s: selected.indexes().size = %d\n", __FUNCTION__, size); + + tbAdd->setEnabled(size > 0); +} + +void StreamConfigDialog::when_lvSelectedProtocols_currentChanged( + const QModelIndex ¤t, const QModelIndex &previous) +{ + qDebug("%s: currentRow = %d\n", __FUNCTION__, current.row()); + + tbDelete->setEnabled(current.isValid()); + tbUp->setEnabled(current.isValid() && (current.row() != 0)); + tbDown->setEnabled(current.isValid() && + (current.row() != (current.model()->rowCount() - 1))); +} + +void StreamConfigDialog::on_tbAdd_clicked() +{ + int n = 0; + QModelIndex idx2; + AbstractProtocol *p; + QModelIndexList selection; + + selection = lvAllProtocols->selectionModel()->selectedIndexes(); + + // Validation + if (selection.size() == 0) return; - // Remove any existing widget on the activated tab - layout = twProto->widget(index)->layout(); - if (layout) - { - QLayoutItem *child; - while ((child = layout->takeAt(0)) != 0) - { - Q_ASSERT(child->widget() != 0); - // Don't delete the child widget - reparent it - child->widget()->setParent(0); - } - delete layout; - } - - // FIXME: protocol id hardcodings - switch(index) - { - case 1: // L2 - wl.append(mpStream->protocol("mac")->configWidget()); - if (cbCVlan->isEnabled() && cbCVlan->isChecked()) - wl.append(mpStream->protocol("vlan")->configWidget()); - if (rbFtEthernet2->isChecked()) - wl.append(mpStream->protocol("eth2")->configWidget()); - else if (rbFt802Dot3Raw->isChecked()) - wl.append(mpStream->protocol("dot3")->configWidget()); - else if (rbFt802Dot3Llc->isChecked()) - { - wl.append(mpStream->protocol("dot3")->configWidget()); - wl.append(mpStream->protocol("llc")->configWidget()); - } - else if (rbFtLlcSnap->isChecked()) - { - wl.append(mpStream->protocol("dot3")->configWidget()); - wl.append(mpStream->protocol("llc")->configWidget()); - wl.append(mpStream->protocol("snap")->configWidget()); - } - - { - int i, r = 0, c = 0; - QGridLayout *layout = new QGridLayout; - - Q_ASSERT(wl.size() > 0); - - // We use a 2 column layout for the L2 Tab - - layout->addWidget(wl.at(0), r, c, 1, -1); - r++; - for (i=1; i < wl.size(); i++) - { - layout->addWidget(wl.at(i), r, c); - if ((i % 2) == 0) - r++; - c = (c+1) % 2; - - } - if ((i % 2) == 0) - r++; - layout->setRowStretch(r, 10); - - twProto->widget(index)->setLayout(layout); - } - break; - case 2: // L3 - if (rbL3Ipv4->isChecked()) - wl.append(mpStream->protocol("ip4")->configWidget()); - - if (wl.size()) - { - QVBoxLayout *layout = new QVBoxLayout; - - for (int i=0; i < wl.size(); i++) - layout->addWidget(wl.at(i)); - - twProto->widget(index)->setLayout(layout); - } - break; - case 3: // L4 - if (rbL4Tcp->isChecked()) - wl.append(mpStream->protocol("tcp")->configWidget()); - else if (rbL4Udp->isChecked()) - wl.append(mpStream->protocol("udp")->configWidget()); - - if (wl.size()) - { - QVBoxLayout *layout = new QVBoxLayout; - - for (int i=0; i < wl.size(); i++) - layout->addWidget(wl.at(i)); - - twProto->widget(index)->setLayout(layout); - } - break; - } -#else - int selTab; - - qDebug("In %s (tab index = %d)", __FUNCTION__, index); - // We need to process only index 4 i.e. the Protocol Data tab - if (index != 4) - return; - - // Hide the ToolBox before modifying it - otherwise we have a crash !!! - tbProtocolData->hide(); - - selTab = tbProtocolData->currentIndex(); - - // Remove any existing widget on the activated tab - while (tbProtocolData->count() > 0) - { - QWidget* w = tbProtocolData->widget(0); - tbProtocolData->removeItem(0); - w->setParent(0); - } + idx2 = lvSelectedProtocols->currentIndex(); + if (idx2.isValid()) + n = idx2.row(); _iter->toFront(); - while (_iter->hasNext()) + while (n--) { - AbstractProtocol* p = _iter->next(); - tbProtocolData->addItem(p->configWidget(), p->name()); + if (!_iter->hasNext()) + return; + + p = _iter->next(); } - if (selTab < tbProtocolData->count()) - tbProtocolData->setCurrentIndex(selTab); + foreach(QModelIndex idx, selection) + _iter->insert(OstProtocolManager.createProtocol( + mpAvailableProtocolsModel->stringList().at(idx.row()), mpStream)); - tbProtocolData->show(); -#endif + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx2); +} + +void StreamConfigDialog::on_tbDelete_clicked() +{ + int n; + QModelIndex idx; + AbstractProtocol *p; + + idx = lvSelectedProtocols->currentIndex(); + + // Validation + if (!idx.isValid()) + return; + + n = idx.row() + 1; + + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; + + p = _iter->next(); + } + + _iter->remove(); + delete p; + + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx); +} + +void StreamConfigDialog::on_tbUp_clicked() +{ + int m, n; + QModelIndex idx; + AbstractProtocol *p; + + idx = lvSelectedProtocols->currentIndex(); + + // Validation + if (!idx.isValid() || idx.row() == 0) + return; + + m = n = idx.row() + 1; + + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; + + p = _iter->next(); + } + + _iter->remove(); + _iter->previous(); + _iter->insert(p); + + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx.sibling(m-2, 0)); +} + +void StreamConfigDialog::on_tbDown_clicked() +{ + int m, n; + QModelIndex idx; + AbstractProtocol *p; + + idx = lvSelectedProtocols->currentIndex(); + + // Validation + if (!idx.isValid() || idx.row() == idx.model()->rowCount()) + return; + + m = n = idx.row() + 1; + + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; + + p = _iter->next(); + } + + _iter->remove(); + _iter->next(); + _iter->insert(p); + + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx.sibling(m,0)); +} + +void StreamConfigDialog::updateSelectProtocolsAdvancedWidget() +{ + QStringList selProtoList; + + qDebug("%s", __FUNCTION__); + + _iter->toFront(); + while(_iter->hasNext()) + { + AbstractProtocol* p = _iter->next(); + qDebug("%p -- %d", p, p->protocolNumber()); + selProtoList.append(p->shortName()); + } + mpSelectedProtocolsModel->setStringList(selProtoList); +} + +void StreamConfigDialog::on_twTopLevel_currentChanged(int index) +{ + switch (index) + { + // Protocol Data + case 1: + { + QWidget *selWidget; + + // Hide the ToolBox before modifying it - else we have a crash !!! + tbProtocolData->hide(); + + selWidget = tbProtocolData->currentWidget(); + + // Remove all existing protocol widgets + while (tbProtocolData->count() > 0) + { + QWidget* w = tbProtocolData->widget(0); + tbProtocolData->removeItem(0); + w->setParent(0); + } + + // Repopulate the widgets + _iter->toFront(); + while (_iter->hasNext()) + { + AbstractProtocol* p = _iter->next(); + tbProtocolData->addItem(p->configWidget(), p->name()); + } + + tbProtocolData->setCurrentWidget(selWidget); + + tbProtocolData->show(); + break; + } + + // Packet View + case 3: + { + StoreCurrentStream(); + mpPacketModel->setSelectedProtocols(*_iter); + break; + } + + default: + break; + } } void StreamConfigDialog::update_NumPacketsAndNumBursts() @@ -576,6 +573,635 @@ void StreamConfigDialog::on_lePattern_editingFinished() } #endif +bool StreamConfigDialog::skipProtocols(int layer) +{ +#define CHK(p) (_iter->hasNext() && _iter->peekNext()->protocolNumber() == p) + + _iter->toFront(); + + // Check and skip 'mac' + if (CHK(51)) + _iter->next(); + else + goto _unexpected_proto; + + if (layer == 0) + goto _done; + + // Skip VLANs + while (CHK(126)) + _iter->next(); + + if (layer == 1) + goto _done; + + // Skip L2 (FrameType) + if (CHK(121)) // Eth2 + _iter->next(); + else if (CHK(122)) // 802.3 RAW + { + _iter->next(); + if (CHK(123)) // 802.3 LLC + { + _iter->next(); + if (CHK(124)) // SNAP + _iter->next(); + } + } + else + goto _unexpected_proto; + + if (layer == 2) + goto _done; + + // Skip L3 + if (CHK(130)) // IP4 + _iter->next(); + else if (CHK(131)) // ARP + _iter->next(); + else + goto _unexpected_proto; + + if (layer == 3) + goto _done; + + // Skip L4 + if (CHK(140)) // TCP + _iter->next(); + else if (CHK(141)) // UDP + _iter->next(); + else if (CHK(142)) // ICMP + _iter->next(); + else if (CHK(143)) // IGMP + _iter->next(); + else + goto _unexpected_proto; + + if (layer == 4) + goto _done; + + goto _unexpected_proto; + +_done: + return true; + +_unexpected_proto: + qWarning("%s: unexpected protocol", __FUNCTION__); + return false; + +#undef CHK +} + +void StreamConfigDialog::updateFrameTypeProtocol(int newId) +{ + static int oldId = 0; + AbstractProtocol *p; + + qDebug("%s:old id = %d new id = %d, upd? = %d", __FUNCTION__, oldId, newId, + isUpdateInProgress); + + if (oldId == newId) + return; // Nothing to be done + + if (!isUpdateInProgress) + { + Q_ASSERT(newId != -1); + + if (!skipProtocols(1)) + goto _error; + + // Delete old Id + switch (oldId) + { + case 0: + break; + case -1: + // Blindly remove the current protocol + p =_iter->next(); + _iter->remove(); + delete p; + break; + + case 121: // ethernet + case 122: // dot3 + p =_iter->next(); + if (p->protocolNumber() != (quint32) oldId) + goto _error; + + _iter->remove(); + delete p; + break; + case 123: // dot3 llc + p =_iter->next(); + if (p->protocolNumber() != 122) + goto _error; + _iter->remove(); + delete p; + + p =_iter->next(); + if (p->protocolNumber() != 123) + goto _error; + _iter->remove(); + delete p; + break; + case 124: // dot3 llc snap + p =_iter->next(); + if (p->protocolNumber() != 122) + goto _error; + _iter->remove(); + delete p; + + p =_iter->next(); + if (p->protocolNumber() != 123) + goto _error; + _iter->remove(); + delete p; + + p =_iter->next(); + if (p->protocolNumber() != 124) + goto _error; + _iter->remove(); + delete p; + break; + default: + goto _error; + } + + // Insert new Id + switch (newId) + { + case 0: + break; + case 121: // ethernet + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; + case 122: // dot3 + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; + case 123: // dot3 llc + _iter->insert(OstProtocolManager.createProtocol( + 122, mpStream)); + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; + case 124: // dot3 llc snap + _iter->insert(OstProtocolManager.createProtocol( + 122, mpStream)); + _iter->insert(OstProtocolManager.createProtocol( + 123, mpStream)); + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; + default: + goto _error; + } + } + + oldId = newId; + return; + +_error: + qFatal("%s: unexpected incident", __FUNCTION__); +} + +void StreamConfigDialog::updateVlanProtocol(int newId) +{ + static int oldId = 0; + AbstractProtocol *p; + + qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, + isUpdateInProgress); + + if (oldId == newId) + return; // Nothing to be done + + if (!isUpdateInProgress) + { + Q_ASSERT(newId != -1); + + if (!skipProtocols(0)) + goto _error; + + // Delete oldId proto + switch (oldId) + { + case 0: + switch (newId) + { + case 127: + _iter->insert(OstProtocolManager.createProtocol( + 126, mpStream)); + // No 'break'; fallthrough - by design! + case 126: + _iter->insert(OstProtocolManager.createProtocol( + 126, mpStream)); + break; + default: + goto _error; + } + break; + + case 126: + if (!_iter->hasNext()) + goto _error; + p =_iter->next(); + if (p->protocolNumber() != 126) + goto _error; + switch (newId) + { + case 0: + _iter->remove(); + delete p; + break; + + case 127: + _iter->insert(OstProtocolManager.createProtocol( + 126, mpStream)); + break; + default: + goto _error; + } + break; + + case 127: + if (!_iter->hasNext()) + goto _error; + p =_iter->next(); + if (p->protocolNumber() != 126) + goto _error; + p =_iter->next(); + if (p->protocolNumber() != 126) + goto _error; + switch (newId) + { + case 0: + _iter->previous(); + _iter->previous(); + p =_iter->next(); + _iter->remove(); + delete p; + p =_iter->next(); + _iter->remove(); + delete p; + break; + + case 126: + _iter->previous(); + _iter->previous(); + p =_iter->next(); + _iter->remove(); + delete p; + break; + default: + goto _error; + } + break; + default: + goto _error; + } + } + + oldId = newId; + return; + +_error: + qFatal("%s: unexpected incident", __FUNCTION__); +} + +void StreamConfigDialog::updateL3Protocol(int newId) +{ + static int oldId = 0; + AbstractProtocol *p; + + qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, + isUpdateInProgress); + + if (oldId == newId) + return; // Nothing to be done + + if (!isUpdateInProgress) + { + Q_ASSERT(newId != -1); + + if (!skipProtocols(2)) + goto _error; + + switch (oldId) + { + case 0: + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; + + case -1: + default: + if (!_iter->hasNext()) + goto _error; + + p =_iter->next(); + + if ((oldId != -1) && (p->protocolNumber() == (quint32) newId)) + goto _error; + + if (newId) + _iter->setValue(OstProtocolManager.createProtocol( + newId, mpStream)); + else + _iter->remove(); + delete p; + break; + } + } + + oldId = newId; + return; + +_error: + qFatal("%s: unexpected incident", __FUNCTION__); +} + +void StreamConfigDialog::updateL4Protocol(int newId) +{ + static int oldId = 0; + AbstractProtocol *p; + + qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, + isUpdateInProgress); + + if (oldId == newId) + return; // Nothing to be done + + if (!isUpdateInProgress) + { + Q_ASSERT(newId != -1); + + if (!skipProtocols(3)) + goto _error; + + switch (oldId) + { + case 0: + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; + + case -1: + default: + if (!_iter->hasNext()) + goto _error; + + p =_iter->next(); + + if ((oldId != -1) && (p->protocolNumber() == (quint32) newId)) + goto _error; + + if (newId) + _iter->setValue(OstProtocolManager.createProtocol( + newId, mpStream)); + else + _iter->remove(); + delete p; + break; + } + } + + oldId = newId; + return; + +_error: + qFatal("%s: unexpected incident", __FUNCTION__); +} + +void StreamConfigDialog::updatePayloadProtocol(int newId) +{ + static int oldId = 52; + AbstractProtocol *p; + + qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, + isUpdateInProgress); + + if (oldId == newId) + return; // Nothing to be done + + if (!isUpdateInProgress) + { + Q_ASSERT(newId != 0); + Q_ASSERT(newId != -1); + + if (!skipProtocols(4)) + goto _error; + + if (!_iter->hasNext()) + goto _error; + + p =_iter->next(); + + _iter->setValue(OstProtocolManager.createProtocol( + newId, mpStream)); + delete p; + while (_iter->hasNext()) + { + + p = _iter->next(); + _iter->remove(); + delete p; + } + } + + oldId = newId; + return; + +_error: + qFatal("%s: unexpected incident", __FUNCTION__); +} + +void StreamConfigDialog::updateSelectProtocolsSimpleWidget() +{ +#define CHK(p) (_iter->hasNext() && _iter->peekNext()->protocolNumber() == p) + + qDebug("%s", __FUNCTION__); + + isUpdateInProgress = true; + + _iter->toFront(); + + // + // We expect first protocol to be 'mac' usually + // + if (CHK(51)) // Mac + { + _iter->next(); + } + else + { + rbFtOther->setChecked(true); + goto _done; + } + + + // + // Check for "VLAN" + // + if (CHK(126)) // VLAN + { + _iter->next(); + if (CHK(126)) // VLAN + { + rbVlanDouble->setChecked(true); + updateVlanProtocol(127); + _iter->next(); + } + else + { + rbVlanSingle->setChecked(true); + updateVlanProtocol(126); + } + } + else + { + rbVlanNone->setChecked(true); + updateVlanProtocol(0); + } + + + // + // Identify and set "FrameType" + // + if (CHK(52)) // Payload + { + rbFtNone->click(); + goto _payload; + } + else if (CHK(121)) // Eth2 + { + rbFtEthernet2->click(); + _iter->next(); + } + else if (CHK(122)) // 802.3 RAW + { + _iter->next(); + if (CHK(123)) // 802.3 LLC + { + _iter->next(); + if (CHK(124)) // SNAP + { + rbFtLlcSnap->click(); + _iter->next(); + } + else + { + rbFt802Dot3Llc->click(); + } + } + else + { + rbFt802Dot3Raw->click(); + } + } + else + { + rbFtOther->setChecked(true); + goto _done; + } + + + // + // --- L3 --- + // + if (CHK(130)) // IP4 + { + rbL3Ipv4->click(); + _iter->next(); + } + else if (CHK(131)) // ARP + { + rbL3Arp->click(); + _iter->next(); + } + else if (CHK(52)) // Payload + { + rbL3None->click(); + goto _payload; + } + else + { + rbL3Other->setChecked(true); + goto _done; + } + + // + // --- L4 --- + // + if (!_iter->hasNext()) + { + rbL4Other->setChecked(true); + goto _done; + } + else if (CHK(140)) // TCP + { + rbL4Tcp->click(); + _iter->next(); + } + else if (CHK(141)) // UDP + { + rbL4Udp->click(); + _iter->next(); + } + else if (CHK(142)) // ICMP + { + rbL4Icmp->click(); + _iter->next(); + } + else if (CHK(143)) // IGMP + { + rbL4Igmp->click(); + _iter->next(); + } + else if (CHK(52)) // Payload + { + rbL4None->click(); + goto _payload; + } + else + { + rbL4Other->setChecked(true); + goto _done; + } + +_payload: + // + // Payload + // + if (CHK(52)) // Payload + { + rbPayloadPattern->click(); + _iter->next(); + } + + // If there is any protocol beyond "data pattern" ... + if (_iter->hasNext()) + rbPayloadOther->setChecked(true); + +_done: + // If any "other" protocols are checked, QButtonGroup signals + // are not triggered since the "other" radioButton's are disabled + // - so update manually + if (rbFtOther->isChecked()) + updateFrameTypeProtocol(-1); + if (rbL3Other->isChecked()) + updateL3Protocol(-1); + if (rbL4Other->isChecked()) + updateL4Protocol(-1); + if (rbPayloadOther->isChecked()) + updatePayloadProtocol(-1); + isUpdateInProgress = false; + + return; +#undef CHK +} + void StreamConfigDialog::LoadCurrentStream() { QString str; @@ -590,247 +1216,13 @@ void StreamConfigDialog::LoadCurrentStream() lePktLenMax->setText(str.setNum(mpStream->frameLenMax())); } -#if 0 // MPS - temp mask // Protocols { - int i; + updateSelectProtocolsSimpleWidget(); + updateSelectProtocolsAdvancedWidget(); - qDebug("Selected Protocols.size() = %d", mSelectedProtocols.size()); - mSelectedProtocols = mpStream->frameProtocol(); - qDebug("Selected Protocols.size() = %d", mSelectedProtocols.size()); - for (i = 0; i < mSelectedProtocols.size(); i++) - qDebug("%d: %d", i, mSelectedProtocols.at(i)); - - Q_ASSERT(mSelectedProtocols.size() >= 2); // Mac + Payload: mandatory - - i = 0; - Q_ASSERT(mSelectedProtocols.at(i) == 51); // Mac - i++; - - // VLAN - if (mSelectedProtocols.at(i) == 126) // VLAN - { - cbCVlan->setChecked(true); - i++; - } - - if (mSelectedProtocols.at(i) == 52) // Payload - { - i++; - goto _proto_parse_done; - } - else if (mSelectedProtocols.at(i) == 121) // Eth2 - { - rbFtEthernet2->setChecked(true); - i++; - } - else if (mSelectedProtocols.at(i) == 122) // 802.3 RAW - { - if ((mSelectedProtocols.size() > (i+1)) && - (mSelectedProtocols.at(i+1) == 123)) // 802.3 LLC - { - if ((mSelectedProtocols.size() > (i+2)) && - (mSelectedProtocols.at(i+2) == 124)) // SNAP - { - rbFtLlcSnap->setChecked(true); - i+=3; - } - else - { - rbFt802Dot3Llc->setChecked(true); - i+=2; - } - } - else - { - rbFt802Dot3Raw->setChecked(true); - i++; - } - } - else - rbFtNone->setChecked(true); - - - // L3 - if (mSelectedProtocols.at(i) == 52) // Payload - { - i++; - goto _proto_parse_done; - } - else if (mSelectedProtocols.at(i) == 130) // IP4 - { - rbL3Ipv4->setChecked(true); - i++; - } - else if (mSelectedProtocols.at(i) == 131) // ARP - { - rbL3Arp->setChecked(true); - i++; - } - else - rbL3None->setChecked(true); - - if (i == mSelectedProtocols.size()) - goto _proto_parse_done; - - // L4 - if (mSelectedProtocols.at(i) == 52) // Payload - { - i++; - goto _proto_parse_done; - } - else if (mSelectedProtocols.at(i) == 140) // TCP - { - rbL4Tcp->setChecked(true); - i++; - } - else if (mSelectedProtocols.at(i) == 141) // UDP - { - rbL4Udp->setChecked(true); - i++; - } - else if (mSelectedProtocols.at(i) == 142) // ICMP - { - rbL4Icmp->setChecked(true); - i++; - } - else if (mSelectedProtocols.at(i) == 143) // IGMP - { - rbL4Igmp->setChecked(true); - i++; - } - else - rbL4None->setChecked(true); - - Q_ASSERT(mSelectedProtocols.at(i) == 52); // Payload - i++; - -_proto_parse_done: - Q_ASSERT(i == mSelectedProtocols.size()); mpStream->loadProtocolWidgets(); } -#else - // Protocols - { - qDebug("Loading - current list"); - _iter->toFront(); - while(_iter->hasNext()) - { - AbstractProtocol* p = _iter->next(); - qDebug("%p -- %d", p, p->protocolNumber()); - } - _iter->toFront(); - -#define CHK(p) (_iter->hasNext() && _iter->peekNext()->protocolNumber() == p) - - Q_ASSERT(CHK(51)); // Mac - _iter->next(); - - // VLAN - if (CHK(126)) // VLAN - { - cbCVlan->setChecked(true); - _iter->next(); - } - - if (CHK(52)) // Payload - { - _iter->next(); - goto _proto_parse_done; - } - else if (CHK(121)) // Eth2 - { - rbFtEthernet2->setChecked(true); - _iter->next(); - } - else if (CHK(122)) // 802.3 RAW - { - _iter->next(); - if (CHK(123)) // 802.3 LLC - { - _iter->next(); - if (CHK(124)) // SNAP - { - rbFtLlcSnap->setChecked(true); - _iter->next(); - } - else - { - rbFt802Dot3Llc->setChecked(true); - } - } - else - { - rbFt802Dot3Raw->setChecked(true); - } - } - else - rbFtNone->setChecked(true); - - - // L3 - if (CHK(52)) // Payload - { - _iter->next(); - goto _proto_parse_done; - } - else if (CHK(130)) // IP4 - { - rbL3Ipv4->setChecked(true); - _iter->next(); - } - else if (CHK(131)) // ARP - { - rbL3Arp->setChecked(true); - _iter->next(); - } - else - rbL3None->setChecked(true); - - if (!_iter->hasNext()) - goto _proto_parse_done; - - // L4 - if (CHK(52)) // Payload - { - _iter->next(); - goto _proto_parse_done; - } - else if (CHK(140)) // TCP - { - rbL4Tcp->setChecked(true); - _iter->next(); - } - else if (CHK(141)) // UDP - { - rbL4Udp->setChecked(true); - _iter->next(); - } - else if (CHK(142)) // ICMP - { - rbL4Icmp->setChecked(true); - _iter->next(); - } - else if (CHK(143)) // IGMP - { - rbL4Igmp->setChecked(true); - _iter->next(); - } - else - rbL4None->setChecked(true); - - Q_ASSERT(CHK(52)); // Payload - _iter->next(); - -_proto_parse_done: - Q_ASSERT(!_iter->hasNext()); - mpStream->loadProtocolWidgets(); - -#undef CHK - } - - -#endif // Stream Control { @@ -900,8 +1292,6 @@ void StreamConfigDialog::StoreCurrentStream() // Protocols { - updateSelectedProtocols(); - //pStream->setFrameProtocol(mSelectedProtocols); pStream->storeProtocolWidgets(); } @@ -937,13 +1327,14 @@ void StreamConfigDialog::on_pbOk_clicked() OstProto::Stream s; // Store dialog contents into stream - //updateSelectedProtocols(); StoreCurrentStream(); + + // Copy the data from the "local working copy of stream" to "actual stream" mpStream->protoDataCopyInto(s); - mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyFrom(s);; + mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyFrom(s); + qDebug("stream stored"); lastTopLevelTabIndex = twTopLevel->currentIndex(); - lastProtoTabIndex = twProto->currentIndex(); } diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index c0e02a7..4b774f7 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -29,10 +29,13 @@ public: private: QButtonGroup *bgFrameType; + QButtonGroup *bgVlan; QButtonGroup *bgL3Proto; QButtonGroup *bgL4Proto; + QButtonGroup *bgPayloadProto; QStringListModel *mpAvailableProtocolsModel; + QStringListModel *mpSelectedProtocolsModel; Port& mPort; uint mCurrentStreamIndex; @@ -40,6 +43,8 @@ private: Stream *mpStream; ProtocolListIterator *_iter; + bool isUpdateInProgress; + PacketModel *mpPacketModel; ModelTest *mpPacketModelTester; @@ -47,7 +52,6 @@ private: // for the various tab widgets so that it can be restored when the dialog // is opened the next time static int lastTopLevelTabIndex; - static int lastProtoTabIndex; void setupUiExtra(); void updateSelectedProtocols(); @@ -56,15 +60,37 @@ private: private slots: void on_cmbPktLenMode_currentIndexChanged(QString mode); - void on_pbPrev_clicked(); - void on_pbNext_clicked(); - - void updateContents(); + void update_NumPacketsAndNumBursts(); void on_twTopLevel_currentChanged(int index); - void on_twProto_currentChanged(int index); + void on_tbSelectProtocols_currentChanged(int index); - void update_NumPacketsAndNumBursts(); + // "Simple" Protocol Selection related + bool skipProtocols(int layer); + + void updateFrameTypeProtocol(int id); + void updateVlanProtocol(int id); + void updateL3Protocol(int id); + void updateL4Protocol(int id); + void updatePayloadProtocol(int id); + + void updateSelectProtocolsSimpleWidget(); + + // "Advanced" Protocol Selection related + void when_lvAllProtocols_selectionChanged( + const QItemSelection &selected, const QItemSelection &deselected); + void when_lvSelectedProtocols_currentChanged( + const QModelIndex ¤t, const QModelIndex &previous); + + void on_tbAdd_clicked(); + void on_tbDelete_clicked(); + void on_tbUp_clicked(); + void on_tbDown_clicked(); + + void updateSelectProtocolsAdvancedWidget(); + + void on_pbPrev_clicked(); + void on_pbNext_clicked(); void on_pbOk_clicked(); }; diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 198cbf2..6e15d3b 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,8 +8,8 @@ 0 0 - 636 - 589 + 524 + 458 @@ -35,8 +35,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff true - - + + @@ -46,7 +46,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - Packet Config + Protocol Selection @@ -56,7 +56,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 171 + 241 20 @@ -164,237 +164,366 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + - 4 + 0 - - - Protocols + + + + 0 + 0 + 465 + 226 + + + + Simple + + + + + + Frame Type + + + + + + None (Mac Only) + + + true + + + + + + + Ethernet II + + + false + + + + + + + 802.3 Raw + + + + + + + 802.3 LLC + + + false + + + + + + + 802.3 LLC SNAP + + + + + + + false + + + Other + + + + + + + + + + true + + + VLAN + + + false + + + false + + + + + + None + + + true + + + + + + + Single Tag + + + + + + + Double Tag + + + + + + + + + + L3 + + + + + + None + + + true + + + + + + + false + + + IPv4 + + + false + + + + + + + false + + + IPv6 + + + + + + + false + + + ARP + + + + + + + false + + + Other + + + + + + + + + + L4 + + + + + + None + + + true + + + + + + + false + + + ICMP + + + + + + + false + + + IGMP + + + + + + + false + + + TCP + + + + + + + false + + + UDP + + + + + + + false + + + Other + + + + + + + + + + Payload + + + + + + Pattern + + + true + + + + + + + false + + + Other + + + + + + + + + + Qt::Vertical + + + + 107 + 24 + + + + + + + + + + 0 + 0 + 250 + 135 + + + + Advanced - - - Frame Type + + + Available Protocols - - - - - None - - - true - - - - - - - Ethernet II - - - false - - - - - - - 802.3 Raw - - - - - - - 802.3 LLC - - - false - - - - - - - LLC SNAP - - - - - - + + true - - VLAN + + QAbstractItemView::ExtendedSelection - - false + + QAbstractItemView::SelectRows - - false - - - - - - true - - - CVLAN - - - - - - - true - - - SVLAN - - - - + + + + - - - L3 + + + Qt::Vertical - - - - - None - - - true - - - - - - - false - - - IPv4 - - - false - - - - - - - false - - - IPv6 - - - - - - - false - - - ARP - - - - - - - false - - - Other - - - - - + + + 20 + 40 + + + - - - L4 + + + false + + + > + + + :/icons/arrow_right.png - - - - - None - - - true - - - - - - - false - - - ICMP - - - - - - - false - - - IGMP - - - - - - - false - - - TCP - - - - - - - false - - - UDP - - - - - - - false - - - Other - - - - @@ -404,8 +533,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 182 - 16 + 20 + 40 @@ -413,126 +542,78 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - - Advanced Protocol Selection - - - true - - - false - - - - - - - - - - Available Protocols - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - > - - - - - - - < - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Selected Protocols - - - - - - - - - - - - - - - - - - L2 - - - - - - L3 - - - - - L4 - - - - - - Protocol Data - - - - - - -1 - - + + + + + Selected Protocols + + + + + + + + + false + + + ^ + + + :/icons/arrow_up.png + + + + + + + false + + + v + + + :/icons/arrow_down.png + + + + + + + false + + + - + + + :/icons/delete.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QAbstractItemView::SelectRows + + + + @@ -540,6 +621,20 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + Protocol Data + + + + + + -1 + + + + + Stream Control @@ -925,7 +1020,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + @@ -989,7 +1084,55 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff lePktLen lePktLenMin lePktLenMax - twProto + rbFtNone + rbFtEthernet2 + rbFt802Dot3Raw + rbFt802Dot3Llc + rbFtLlcSnap + rbFtOther + rbVlanNone + rbVlanSingle + rbVlanDouble + rbL3None + rbL3Ipv4 + rbL3Ipv6 + rbL3Arp + rbL3Other + rbL4None + rbL4Icmp + rbL4Igmp + rbL4Tcp + rbL4Udp + rbL4Other + rbPayloadPattern + rbPayloadOther + pbPrev + pbNext + pbOk + pbCancel + rbSendBursts + leNumPackets + leNumBursts + lePacketsPerBurst + rbActionStop + rbActionGotoNext + rbActionGotoStream + leStreamId + rbModeFixed + rbModeContinuous + lePacketsPerSec + leBurstsPerSec + leGapIsg + leGapIpg + leGapIbg + tvPacketTree + tbDown + tbDelete + lvSelectedProtocols + rbSendPackets + tbUp + lvAllProtocols + tbAdd diff --git a/common/comboprotocol.h b/common/comboprotocol.h new file mode 100644 index 0000000..62828cb --- /dev/null +++ b/common/comboprotocol.h @@ -0,0 +1,133 @@ +#ifndef _COMBO_PROTOCOL_H +#define _COMBO_PROTOCOL_H + +#include "abstractprotocol.h" + +template +class ComboProtocol : public AbstractProtocol +{ +private: + ProtoA *protoA; + ProtoB *protoB; + QWidget *configForm; + +public: + ComboProtocol(StreamBase *stream) + { + protoA = new ProtoA(stream); + protoB = new ProtoB(stream); + configForm = NULL; + } + virtual ~ComboProtocol() + { + delete protoA; + delete protoB; + delete configForm; + } + + static ComboProtocol* createInstance(StreamBase *stream) + { + return new ComboProtocol(stream); + } + + virtual quint32 protocolNumber() const + { + return 0; //FIXME + } + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const + { + // FIXME + } + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) + { + // FIXME + } + + virtual QString name() const + { + return protoA->name() + "/" + protoB->name(); + } + virtual QString shortName() const + { + return protoA->shortName() + "/" + protoB->shortName(); + } + + virtual quint32 protocolId(ProtocolIdType type) const + { + return protoA->protocolId(type); + } + //quint32 payloadProtocolId(ProtocolIdType type) const; + + virtual int fieldCount() const + { + return protoA->fieldCount() + protoB->fieldCount(); + } + //virtual int metaFieldCount() const; + //int frameFieldCount() const; + + virtual FieldFlags fieldFlags(int index) const + { + if (index < protoA->fieldCount()) + return protoA->fieldFlags(index); + else + return protoB->fieldFlags(index); + } + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const + { + if (index < protoA->fieldCount()) + return protoA->fieldData(index); + else + return protoB->fieldData(index); + } + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue) + { + if (index < protoA->fieldCount()) + return protoA->fieldData(index); + else + return protoB->fieldData(index); + } + +#if 0 + QByteArray protocolFrameValue(int streamIndex = 0, + bool forCksum = false) const; + virtual int protocolFrameSize() const; + int protocolFrameOffset() const; + int protocolFramePayloadSize() const; + + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFrameHeaderCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFramePayloadCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; +#endif + + virtual QWidget* configWidget() + { + if (configForm == NULL) + { + QVBoxLayout *layout = new VBoxLayout; + + configForm = new QWidget; + layout->addWidget(protoA->configWidget()); + layout->addWidget(protoB->configWidget()); + configForm->setLayout(layout); + } + return configForm; + } + virtual void loadConfigWidget() + { + protoA->loadConfigWidget(); + protoB->loadConfigWidget(); + } + virtual void storeConfigWidget() + { + protoA->storeConfigWidget(); + protoB->storeConfigWidget(); + } +}; + +#endif diff --git a/common/dot3.cpp b/common/dot3.cpp index be6d580..f020b6e 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -118,7 +118,10 @@ bool Dot3Protocol::setFieldData(int index, const QVariant &value, QWidget* Dot3Protocol::configWidget() { if (configForm == NULL) + { configForm = new Dot3ConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/eth2.cpp b/common/eth2.cpp index 1d72042..d1c4b9c 100644 --- a/common/eth2.cpp +++ b/common/eth2.cpp @@ -121,7 +121,10 @@ bool Eth2Protocol::setFieldData(int index, const QVariant &value, QWidget* Eth2Protocol::configWidget() { if (configForm == NULL) + { configForm = new Eth2ConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/ip4.cpp b/common/ip4.cpp index 653c83f..296f09b 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -604,7 +604,10 @@ quint32 Ip4Protocol::protocolFrameCksum(int streamIndex, QWidget* Ip4Protocol::configWidget() { if (configForm == NULL) + { configForm = new Ip4ConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/ip4.proto b/common/ip4.proto index 6889ffd..c17ec75 100644 --- a/common/ip4.proto +++ b/common/ip4.proto @@ -31,13 +31,13 @@ message Ip4 { optional fixed32 src_ip = 14; optional IpAddrMode src_ip_mode = 15 [default = e_im_fixed]; optional uint32 src_ip_count = 16 [default = 16]; - optional fixed32 src_ip_mask = 17 [default = 0xFFFFFFFF]; + optional fixed32 src_ip_mask = 17 [default = 0xFFFFFF00]; // Destination IP optional fixed32 dst_ip = 18; optional IpAddrMode dst_ip_mode = 19 [default = e_im_fixed]; optional uint32 dst_ip_count = 20 [default = 16]; - optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFFFF]; + optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFF00]; // TODO: Options } diff --git a/common/llc.cpp b/common/llc.cpp index 150b8b8..8fe57af 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -135,7 +135,10 @@ bool LlcProtocol::setFieldData(int index, const QVariant &value, QWidget* LlcProtocol::configWidget() { if (configForm == NULL) + { configForm = new LlcConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/mac.cpp b/common/mac.cpp index dfe3ed8..7f87a5b 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -243,7 +243,10 @@ bool MacProtocol::setFieldData(int index, const QVariant &value, QWidget* MacProtocol::configWidget() { if (configForm == NULL) + { configForm = new MacConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/mac.proto b/common/mac.proto index 2e8c04e..a49c34e 100644 --- a/common/mac.proto +++ b/common/mac.proto @@ -18,7 +18,7 @@ message Mac { optional uint32 dst_mac_step = 4 [default = 1]; // Src Mac - optional uint32 src_mac = 5; + optional uint64 src_mac = 5; optional MacAddrMode src_mac_mode = 6 [default = e_mm_fixed]; optional uint32 src_mac_count = 7 [default = 16]; optional uint32 src_mac_step = 8 [default = 1]; diff --git a/common/mac.ui b/common/mac.ui index 78a2c74..821cf00 100644 --- a/common/mac.ui +++ b/common/mac.ui @@ -5,193 +5,170 @@ 0 0 - 512 - 104 + 391 + 116 Form - - - - - MAC + + + + + Address - - - - - Destination - - - - - - - - 120 - 0 - - - - >HH HH HH HH HH HH; - - - - - - - - - - Mode - - - - - - - - Fixed - - - - - Increment - - - - - Decrement - - - - - - - - Count - - - - - - - false - - - - - - 0 - - - - - - - Step - - - - - - - false - - - - - - 0 - - - - - - - Source - - - - - - - >HH HH HH HH HH HH; - - - - - - - - - - Mode - - - - - - - - Fixed - - - - - Increment - - - - - Decrement - - - - - - - - Count - - - - - - - false - - - - - - - - - - Step - - - - - - - false - - - - - - 0 - - - - - + + + + Mode + + + + + + + Count + + + + + + + Step + + + + + + + Destination + + + + + + + + 120 + 0 + + + + >HH HH HH HH HH HH; + + + + + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + + + + false + + + + + + 0 + + + + + + + false + + + + + + 0 + + + + + + + Source + + + + + + + >HH HH HH HH HH HH; + + + + + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + + + + false + + + + + + + + + + false + + + + + + 0 + + + + Qt::Vertical diff --git a/common/ostproto.pro b/common/ostproto.pro index 6095613..0e095a1 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -28,6 +28,7 @@ PROTOS += \ udp.proto HEADERS += \ abstractprotocol.h \ + comboprotocol.h \ protocolmanager.h \ protocollist.h \ protocollistiterator.h \ diff --git a/common/payload.cpp b/common/payload.cpp index 5633ed6..6c93cb3 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -126,6 +126,11 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, dataLen = mpStream->frameLen() - protocolFrameOffset(); dataLen -= SZ_FCS; + + // FIXME: Hack! Bad! Bad! Very Bad!!! + if (dataLen <= 0) + dataLen = 1; + fv.resize(dataLen+4); switch(data.pattern_mode()) { @@ -180,7 +185,10 @@ bool PayloadProtocol::setFieldData(int index, const QVariant &value, QWidget* PayloadProtocol::configWidget() { if (configForm == NULL) + { configForm = new PayloadConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/sample.cpp b/common/sample.cpp index 17ff0c3..9dbb81e 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -155,7 +155,10 @@ bool SampleProtocol::setFieldData(int index, const QVariant &value, QWidget* SampleProtocol::configWidget() { if (configForm == NULL) - configFrom = new SampleConfigForm; + { + configForm = new SampleConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/snap.cpp b/common/snap.cpp index 0aca641..26f5c6c 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -140,7 +140,10 @@ bool SnapProtocol::setFieldData(int index, const QVariant &value, QWidget* SnapProtocol::configWidget() { if (configForm == NULL) + { configForm = new SnapConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/tcp.cpp b/common/tcp.cpp index c3b732b..279efc1 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -384,7 +384,10 @@ bool TcpProtocol::setFieldData(int index, const QVariant &value, QWidget* TcpProtocol::configWidget() { if (configForm == NULL) + { configForm = new TcpConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/udp.cpp b/common/udp.cpp index 9baae78..7564d2a 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -261,7 +261,10 @@ bool UdpProtocol::setFieldData(int index, const QVariant &value, QWidget* UdpProtocol::configWidget() { if (configForm == NULL) + { configForm = new UdpConfigForm; + loadConfigWidget(); + } return configForm; } diff --git a/common/vlan.cpp b/common/vlan.cpp index f261264..2f60601 100644 --- a/common/vlan.cpp +++ b/common/vlan.cpp @@ -203,7 +203,10 @@ bool VlanProtocol::setFieldData(int index, const QVariant &value, QWidget* VlanProtocol::configWidget() { if (configForm == NULL) + { configForm = new VlanConfigForm; + loadConfigWidget(); + } return configForm; } @@ -211,6 +214,7 @@ void VlanProtocol::loadConfigWidget() { configWidget(); + configForm->cbTpidOverride->setChecked(data.is_override_tpid()); configForm->leTpid->setText(uintToHexStr(fieldData(vlan_tpid, FieldValue).toUInt(), 2)); configForm->cmbPrio->setCurrentIndex(fieldData(vlan_prio, FieldValue).toUInt()); configForm->cmbCfiDei->setCurrentIndex(fieldData(vlan_cfiDei, FieldValue).toUInt()); From a937112e6325cf18e018be408848c916ad6aedc8 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 11 Oct 2009 06:07:27 +0000 Subject: [PATCH 25/98] Checking in intermediate changes in Stream Config Dialog. Changes to related to handling of protocols after introducing combo protocol --- client/streamconfigdialog.cpp | 790 +++++++++++++++------------------- 1 file changed, 344 insertions(+), 446 deletions(-) diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 98bc612..9bdae53 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -27,7 +27,9 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, setupUi(this); setupUiExtra(); - connect(bgFrameType, SIGNAL(buttonClicked(int)), + connect(bgL1Proto, SIGNAL(buttonClicked(int)), + this, SLOT(updateL1Protocol(int))); + connect(bgL2Proto, SIGNAL(buttonClicked(int)), this, SLOT(updateFrameTypeProtocol(int))); connect(bgVlan, SIGNAL(buttonClicked(int)), this, SLOT(updateVlanProtocol(int))); @@ -47,9 +49,17 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // Time to play match the signals and slots! // Enable VLAN Choices only if FT = Eth2 or SNAP +#if 0 connect(rbFtNone, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool))); connect(rbFtOther, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool))); connect(rbFtNone, SIGNAL(clicked(bool)), rbVlanNone, SLOT(click())); +#endif + + // Force all protocols = None if L1 = None + connect(rbL1None, SIGNAL(clicked(bool)), rbVlanNone, SLOT(click())); + connect(rbL1None, SIGNAL(clicked(bool)), rbFtNone, SLOT(click())); + connect(rbL1None, SIGNAL(clicked(bool)), rbPayloadNone, SLOT(click())); + connect(rbFtNone, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); // Enable/Disable L3 Protocol Choices for FT None @@ -173,36 +183,43 @@ void StreamConfigDialog::setupUiExtra() QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); // ---- Setup default stuff that cannot be done in designer ---- +#if 0 gbVlan->setDisabled(true); +#endif - bgFrameType = new QButtonGroup(); + bgL1Proto = new QButtonGroup(); + bgL1Proto->addButton(rbL1None, ButtonIdNone); + bgL1Proto->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber); + bgL1Proto->addButton(rbL1Other, ButtonIdOther); + + bgL2Proto = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbFrameType->findChildren()) - bgFrameType->addButton(btn); + bgL2Proto->addButton(btn); #else - bgFrameType->addButton(rbFtNone, 0); - bgFrameType->addButton(rbFtEthernet2, 121); - bgFrameType->addButton(rbFt802Dot3Raw, 122); - bgFrameType->addButton(rbFt802Dot3Llc, 123); - bgFrameType->addButton(rbFtLlcSnap, 124); - bgFrameType->addButton(rbFtOther, -1); + bgL2Proto->addButton(rbFtNone, ButtonIdNone); + bgL2Proto->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); + bgL2Proto->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); + bgL2Proto->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); + bgL2Proto->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); + bgL2Proto->addButton(rbFtOther, ButtonIdOther); #endif bgVlan = new QButtonGroup(); - bgVlan->addButton(rbVlanNone, 0); - bgVlan->addButton(rbVlanSingle, 126); - bgVlan->addButton(rbVlanDouble, 127); + bgVlan->addButton(rbVlanNone, ButtonIdNone); + bgVlan->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); + bgVlan->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); bgL3Proto = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbL3Proto->findChildren()) bgL3Proto->addButton(btn); #else - bgL3Proto->addButton(rbL3None, 0); - bgL3Proto->addButton(rbL3Ipv4, 130); - bgL3Proto->addButton(rbL3Ipv6, -1); - bgL3Proto->addButton(rbL3Arp, -1); - bgL3Proto->addButton(rbL3Other, -1); + bgL3Proto->addButton(rbL3None, ButtonIdNone); + bgL3Proto->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); + bgL3Proto->addButton(rbL3Ipv6, 0xFFFF); + bgL3Proto->addButton(rbL3Arp, 0xFFFF); + bgL3Proto->addButton(rbL3Other, ButtonIdOther); #endif bgL4Proto = new QButtonGroup(); @@ -211,11 +228,11 @@ void StreamConfigDialog::setupUiExtra() bgL4Proto->addButton(btn); #else bgL4Proto->addButton(rbL4None, 0); - bgL4Proto->addButton(rbL4Tcp, 140); - bgL4Proto->addButton(rbL4Udp, 141); - bgL4Proto->addButton(rbL4Icmp, -1); - bgL4Proto->addButton(rbL4Igmp, -1); - bgL4Proto->addButton(rbL4Other, -1); + bgL4Proto->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); + bgL4Proto->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); + bgL4Proto->addButton(rbL4Icmp, 0xFFFF); + bgL4Proto->addButton(rbL4Igmp, 0xFFFF); + bgL4Proto->addButton(rbL4Other, ButtonIdOther); #endif bgPayloadProto = new QButtonGroup(); @@ -223,8 +240,9 @@ void StreamConfigDialog::setupUiExtra() foreach(QRadioButton *btn, gbPayloadProto->findChildren()) bgPayloadProto->addButton(btn); #else - bgPayloadProto->addButton(rbPayloadPattern, 52); - bgPayloadProto->addButton(rbPayloadOther, -1); + bgPayloadProto->addButton(rbPayloadNone, ButtonIdNone); + bgPayloadProto->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); + bgPayloadProto->addButton(rbPayloadOther, ButtonIdOther); #endif /* ** Setup Validators @@ -252,7 +270,8 @@ StreamConfigDialog::~StreamConfigDialog() delete mpPacketModelTester; delete mpPacketModel; - delete bgFrameType; + delete bgL1Proto; + delete bgL2Proto; delete bgVlan; delete bgL3Proto; delete bgL4Proto; @@ -573,91 +592,93 @@ void StreamConfigDialog::on_lePattern_editingFinished() } #endif +/*! +Skip protocols upto and including the layer specified. + 0 - L1 + 1 - VLAN + 2 - L2 + 3 - L3 + 4 - L4 +TODO: Convert the above values to enum?? +*/ bool StreamConfigDialog::skipProtocols(int layer) { -#define CHK(p) (_iter->hasNext() && _iter->peekNext()->protocolNumber() == p) + int id; + QAbstractButton *btn; _iter->toFront(); - // Check and skip 'mac' - if (CHK(51)) - _iter->next(); - else - goto _unexpected_proto; + // Skip L1 + if (_iter->hasNext()) + { + id = _iter->next()->protocolNumber(); + btn = bgL1Proto->button(id); + if (btn == NULL) + _iter->previous(); + } if (layer == 0) goto _done; - // Skip VLANs - while (CHK(126)) - _iter->next(); + // Skip VLAN + if(_iter->hasNext()) + { + id = _iter->next()->protocolNumber(); + btn = bgVlan->button(id); + if (btn == NULL) + _iter->previous(); + } if (layer == 1) goto _done; - // Skip L2 (FrameType) - if (CHK(121)) // Eth2 - _iter->next(); - else if (CHK(122)) // 802.3 RAW + // Skip L2 + if(_iter->hasNext()) { - _iter->next(); - if (CHK(123)) // 802.3 LLC - { - _iter->next(); - if (CHK(124)) // SNAP - _iter->next(); - } + id = _iter->next()->protocolNumber(); + btn = bgL2Proto->button(id); + if (btn == NULL) + _iter->previous(); } - else - goto _unexpected_proto; if (layer == 2) goto _done; // Skip L3 - if (CHK(130)) // IP4 - _iter->next(); - else if (CHK(131)) // ARP - _iter->next(); - else - goto _unexpected_proto; + if (_iter->hasNext()) + { + id = _iter->next()->protocolNumber(); + btn = bgL3Proto->button(id); + if (btn == NULL) + _iter->previous(); + } if (layer == 3) goto _done; // Skip L4 - if (CHK(140)) // TCP - _iter->next(); - else if (CHK(141)) // UDP - _iter->next(); - else if (CHK(142)) // ICMP - _iter->next(); - else if (CHK(143)) // IGMP - _iter->next(); - else - goto _unexpected_proto; + if(_iter->hasNext()) + { + id = _iter->next()->protocolNumber(); + btn = bgL4Proto->button(id); + if (btn == NULL) + _iter->previous(); + } if (layer == 4) goto _done; - goto _unexpected_proto; + return false; _done: return true; - -_unexpected_proto: - qWarning("%s: unexpected protocol", __FUNCTION__); - return false; - -#undef CHK } -void StreamConfigDialog::updateFrameTypeProtocol(int newId) +void StreamConfigDialog::updateL1Protocol(int newId) { - static int oldId = 0; - AbstractProtocol *p; + static int oldId; - qDebug("%s:old id = %d new id = %d, upd? = %d", __FUNCTION__, oldId, newId, + qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, isUpdateInProgress); if (oldId == newId) @@ -665,111 +686,41 @@ void StreamConfigDialog::updateFrameTypeProtocol(int newId) if (!isUpdateInProgress) { - Q_ASSERT(newId != -1); + AbstractProtocol *p; - if (!skipProtocols(1)) - goto _error; + _iter->toFront(); + + Q_ASSERT(newId != ButtonIdOther); - // Delete old Id switch (oldId) { - case 0: - break; - case -1: - // Blindly remove the current protocol - p =_iter->next(); - _iter->remove(); - delete p; + case ButtonIdNone: + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); break; - case 121: // ethernet - case 122: // dot3 - p =_iter->next(); - if (p->protocolNumber() != (quint32) oldId) - goto _error; - - _iter->remove(); - delete p; - break; - case 123: // dot3 llc - p =_iter->next(); - if (p->protocolNumber() != 122) - goto _error; - _iter->remove(); - delete p; - - p =_iter->next(); - if (p->protocolNumber() != 123) - goto _error; - _iter->remove(); - delete p; - break; - case 124: // dot3 llc snap - p =_iter->next(); - if (p->protocolNumber() != 122) - goto _error; - _iter->remove(); - delete p; - - p =_iter->next(); - if (p->protocolNumber() != 123) - goto _error; - _iter->remove(); - delete p; - - p =_iter->next(); - if (p->protocolNumber() != 124) - goto _error; - _iter->remove(); - delete p; - break; + case ButtonIdOther: default: - goto _error; - } + Q_ASSERT(_iter->hasNext()); + p =_iter->next(); - // Insert new Id - switch (newId) - { - case 0: + if (newId) + _iter->setValue(OstProtocolManager.createProtocol( + newId, mpStream)); + else + _iter->remove(); + delete p; break; - case 121: // ethernet - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - case 122: // dot3 - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - case 123: // dot3 llc - _iter->insert(OstProtocolManager.createProtocol( - 122, mpStream)); - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - case 124: // dot3 llc snap - _iter->insert(OstProtocolManager.createProtocol( - 122, mpStream)); - _iter->insert(OstProtocolManager.createProtocol( - 123, mpStream)); - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - default: - goto _error; } } oldId = newId; return; - -_error: - qFatal("%s: unexpected incident", __FUNCTION__); } void StreamConfigDialog::updateVlanProtocol(int newId) { - static int oldId = 0; - AbstractProtocol *p; + static int oldId; qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, isUpdateInProgress); @@ -779,101 +730,90 @@ void StreamConfigDialog::updateVlanProtocol(int newId) if (!isUpdateInProgress) { - Q_ASSERT(newId != -1); + int ret; + AbstractProtocol *p; - if (!skipProtocols(0)) - goto _error; + ret = skipProtocols(0); + + Q_ASSERT(ret == true); + Q_ASSERT(oldId != ButtonIdOther); + Q_ASSERT(newId != ButtonIdOther); - // Delete oldId proto switch (oldId) { - case 0: - switch (newId) - { - case 127: - _iter->insert(OstProtocolManager.createProtocol( - 126, mpStream)); - // No 'break'; fallthrough - by design! - case 126: - _iter->insert(OstProtocolManager.createProtocol( - 126, mpStream)); - break; - default: - goto _error; - } + case ButtonIdNone: + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); break; - case 126: - if (!_iter->hasNext()) - goto _error; - p =_iter->next(); - if (p->protocolNumber() != 126) - goto _error; - switch (newId) - { - case 0: - _iter->remove(); - delete p; - break; - - case 127: - _iter->insert(OstProtocolManager.createProtocol( - 126, mpStream)); - break; - default: - goto _error; - } - break; - - case 127: - if (!_iter->hasNext()) - goto _error; - p =_iter->next(); - if (p->protocolNumber() != 126) - goto _error; - p =_iter->next(); - if (p->protocolNumber() != 126) - goto _error; - switch (newId) - { - case 0: - _iter->previous(); - _iter->previous(); - p =_iter->next(); - _iter->remove(); - delete p; - p =_iter->next(); - _iter->remove(); - delete p; - break; - - case 126: - _iter->previous(); - _iter->previous(); - p =_iter->next(); - _iter->remove(); - delete p; - break; - default: - goto _error; - } - break; + case ButtonIdOther: default: - goto _error; + Q_ASSERT(_iter->hasNext()); + p =_iter->next(); + + if (newId) + _iter->setValue(OstProtocolManager.createProtocol( + newId, mpStream)); + else + _iter->remove(); + delete p; + break; } } - + oldId = newId; return; +} -_error: - qFatal("%s: unexpected incident", __FUNCTION__); +void StreamConfigDialog::updateFrameTypeProtocol(int newId) +{ + static int oldId; + + qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, + isUpdateInProgress); + + if (oldId == newId) + return; // Nothing to be done + + if (!isUpdateInProgress) + { + int ret; + AbstractProtocol *p; + + ret = skipProtocols(1); + + Q_ASSERT(ret == true); + Q_ASSERT(newId != ButtonIdOther); + + switch (oldId) + { + case ButtonIdNone: + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; + + case ButtonIdOther: + default: + Q_ASSERT(_iter->hasNext()); + p =_iter->next(); + + if (newId) + _iter->setValue(OstProtocolManager.createProtocol( + newId, mpStream)); + else + _iter->remove(); + delete p; + break; + } + } + + oldId = newId; + return; } void StreamConfigDialog::updateL3Protocol(int newId) { - static int oldId = 0; - AbstractProtocol *p; + static int oldId; qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, isUpdateInProgress); @@ -883,28 +823,26 @@ void StreamConfigDialog::updateL3Protocol(int newId) if (!isUpdateInProgress) { - Q_ASSERT(newId != -1); + int ret; + AbstractProtocol *p; - if (!skipProtocols(2)) - goto _error; + ret = skipProtocols(2); + + Q_ASSERT(ret == true); + Q_ASSERT(newId != ButtonIdOther); switch (oldId) { - case 0: + case ButtonIdNone: _iter->insert(OstProtocolManager.createProtocol( newId, mpStream)); break; - case -1: + case ButtonIdOther: default: - if (!_iter->hasNext()) - goto _error; - + Q_ASSERT(_iter->hasNext()); p =_iter->next(); - if ((oldId != -1) && (p->protocolNumber() == (quint32) newId)) - goto _error; - if (newId) _iter->setValue(OstProtocolManager.createProtocol( newId, mpStream)); @@ -917,15 +855,11 @@ void StreamConfigDialog::updateL3Protocol(int newId) oldId = newId; return; - -_error: - qFatal("%s: unexpected incident", __FUNCTION__); } void StreamConfigDialog::updateL4Protocol(int newId) { - static int oldId = 0; - AbstractProtocol *p; + static int oldId; qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, isUpdateInProgress); @@ -935,28 +869,26 @@ void StreamConfigDialog::updateL4Protocol(int newId) if (!isUpdateInProgress) { - Q_ASSERT(newId != -1); + int ret; + AbstractProtocol *p; - if (!skipProtocols(3)) - goto _error; + ret = skipProtocols(3); + + Q_ASSERT(ret == true); + Q_ASSERT(newId != ButtonIdOther); switch (oldId) { - case 0: + case ButtonIdNone: _iter->insert(OstProtocolManager.createProtocol( newId, mpStream)); break; - case -1: + case ButtonIdOther: default: - if (!_iter->hasNext()) - goto _error; - + Q_ASSERT(_iter->hasNext()); p =_iter->next(); - if ((oldId != -1) && (p->protocolNumber() == (quint32) newId)) - goto _error; - if (newId) _iter->setValue(OstProtocolManager.createProtocol( newId, mpStream)); @@ -969,15 +901,11 @@ void StreamConfigDialog::updateL4Protocol(int newId) oldId = newId; return; - -_error: - qFatal("%s: unexpected incident", __FUNCTION__); } void StreamConfigDialog::updatePayloadProtocol(int newId) { - static int oldId = 52; - AbstractProtocol *p; + static int oldId; qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, isUpdateInProgress); @@ -987,219 +915,189 @@ void StreamConfigDialog::updatePayloadProtocol(int newId) if (!isUpdateInProgress) { - Q_ASSERT(newId != 0); - Q_ASSERT(newId != -1); + int ret; + AbstractProtocol *p; - if (!skipProtocols(4)) - goto _error; + ret = skipProtocols(4); + + Q_ASSERT(ret == true); + Q_ASSERT(newId != ButtonIdOther); - if (!_iter->hasNext()) - goto _error; - - p =_iter->next(); - - _iter->setValue(OstProtocolManager.createProtocol( - newId, mpStream)); - delete p; - while (_iter->hasNext()) + switch (oldId) { + case ButtonIdNone: + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; - p = _iter->next(); - _iter->remove(); - delete p; + case ButtonIdOther: + default: + Q_ASSERT(_iter->hasNext()); + p =_iter->next(); + + if (newId) + _iter->setValue(OstProtocolManager.createProtocol( + newId, mpStream)); + else + _iter->remove(); + delete p; + while (_iter->hasNext()) + { + + p = _iter->next(); + _iter->remove(); + delete p; + } + break; } } oldId = newId; return; - -_error: - qFatal("%s: unexpected incident", __FUNCTION__); } void StreamConfigDialog::updateSelectProtocolsSimpleWidget() { -#define CHK(p) (_iter->hasNext() && _iter->peekNext()->protocolNumber() == p) + quint32 id; + QAbstractButton *btn; qDebug("%s", __FUNCTION__); isUpdateInProgress = true; + // Reset to default state + rbL1None->setChecked(true); + rbVlanNone->setChecked(true); + rbFtNone->setChecked(true); + rbL3None->setChecked(true); + rbL4None->setChecked(true); + rbPayloadNone->setChecked(true); + _iter->toFront(); - // - // We expect first protocol to be 'mac' usually - // - if (CHK(51)) // Mac - { - _iter->next(); - } + // L1 (optional if followed by Payload) + if (!_iter->hasNext()) // No protocols at all? + goto _done; + + id = _iter->next()->protocolNumber(); + btn = bgL1Proto->button(id); + + if (btn && btn->isEnabled()) + btn->click(); else { - rbFtOther->setChecked(true); - goto _done; - } - - - // - // Check for "VLAN" - // - if (CHK(126)) // VLAN - { - _iter->next(); - if (CHK(126)) // VLAN - { - rbVlanDouble->setChecked(true); - updateVlanProtocol(127); - _iter->next(); - } + btn = bgPayloadProto->button(id); + if (btn && btn->isEnabled()) + goto _payload; else - { - rbVlanSingle->setChecked(true); - updateVlanProtocol(126); - } - } - else - { - rbVlanNone->setChecked(true); - updateVlanProtocol(0); + goto _otherL1; } - - // - // Identify and set "FrameType" - // - if (CHK(52)) // Payload - { - rbFtNone->click(); - goto _payload; - } - else if (CHK(121)) // Eth2 - { - rbFtEthernet2->click(); - _iter->next(); - } - else if (CHK(122)) // 802.3 RAW - { - _iter->next(); - if (CHK(123)) // 802.3 LLC - { - _iter->next(); - if (CHK(124)) // SNAP - { - rbFtLlcSnap->click(); - _iter->next(); - } - else - { - rbFt802Dot3Llc->click(); - } - } - else - { - rbFt802Dot3Raw->click(); - } - } - else - { - rbFtOther->setChecked(true); - goto _done; - } - - - // - // --- L3 --- - // - if (CHK(130)) // IP4 - { - rbL3Ipv4->click(); - _iter->next(); - } - else if (CHK(131)) // ARP - { - rbL3Arp->click(); - _iter->next(); - } - else if (CHK(52)) // Payload - { - rbL3None->click(); - goto _payload; - } - else - { - rbL3Other->setChecked(true); - goto _done; - } - - // - // --- L4 --- - // + // VLAN (optional) if (!_iter->hasNext()) - { - rbL4Other->setChecked(true); goto _done; - } - else if (CHK(140)) // TCP - { - rbL4Tcp->click(); - _iter->next(); - } - else if (CHK(141)) // UDP - { - rbL4Udp->click(); - _iter->next(); - } - else if (CHK(142)) // ICMP - { - rbL4Icmp->click(); - _iter->next(); - } - else if (CHK(143)) // IGMP - { - rbL4Igmp->click(); - _iter->next(); - } - else if (CHK(52)) // Payload - { - rbL4None->click(); - goto _payload; - } + + id = _iter->next()->protocolNumber(); + btn = bgVlan->button(id); + + if (btn && btn->isEnabled()) + btn->click(); + else + _iter->previous(); + + // L2 (optional if followed by Payload) + if (!_iter->hasNext()) + goto _done; + + id = _iter->next()->protocolNumber(); + btn = bgL2Proto->button(id); + + if (btn && btn->isEnabled()) + btn->click(); else { - rbL4Other->setChecked(true); - goto _done; + btn = bgPayloadProto->button(id); + if (btn && btn->isEnabled()) + goto _payload; + else + goto _otherL2; } + // L3 (optional if followed by Payload) + if (!_iter->hasNext()) + goto _done; + + id = _iter->next()->protocolNumber(); + btn = bgL3Proto->button(id); + + if (btn && btn->isEnabled()) + btn->click(); + else + { + btn = bgPayloadProto->button(id); + if (btn && btn->isEnabled()) + goto _payload; + else + goto _otherL3; + } + + // L4 (optional if followed by Payload) + if (!_iter->hasNext()) + goto _done; + + id = _iter->next()->protocolNumber(); + btn = bgL4Proto->button(id); + + if (btn && btn->isEnabled()) + btn->click(); + else + { + btn = bgPayloadProto->button(id); + if (btn && btn->isEnabled()) + goto _payload; + else + goto _otherL4; + } + + // Payload Data + if (!_iter->hasNext()) + goto _done; + + id = _iter->next()->protocolNumber(); + btn = bgPayloadProto->button(id); + _payload: - // - // Payload - // - if (CHK(52)) // Payload - { - rbPayloadPattern->click(); - _iter->next(); - } + if (btn && btn->isEnabled()) + btn->click(); + else + goto _otherPayload; - // If there is any protocol beyond "data pattern" ... + // If more protocol(s) beyond payload ... if (_iter->hasNext()) - rbPayloadOther->setChecked(true); + goto _otherPayload; + + goto _done; + +_otherL1: + bgL1Proto->button(ButtonIdOther)->setChecked(true); + updateL1Protocol(ButtonIdOther); +_otherL2: + bgL2Proto->button(ButtonIdOther)->setChecked(true); + updateFrameTypeProtocol(ButtonIdOther); +_otherL3: + bgL3Proto->button(ButtonIdOther)->setChecked(true); + updateL3Protocol(ButtonIdOther); +_otherL4: + bgL4Proto->button(ButtonIdOther)->setChecked(true); + updateL4Protocol(ButtonIdOther); +_otherPayload: + bgPayloadProto->button(ButtonIdOther)->setChecked(true); + updatePayloadProtocol(ButtonIdOther); _done: - // If any "other" protocols are checked, QButtonGroup signals - // are not triggered since the "other" radioButton's are disabled - // - so update manually - if (rbFtOther->isChecked()) - updateFrameTypeProtocol(-1); - if (rbL3Other->isChecked()) - updateL3Protocol(-1); - if (rbL4Other->isChecked()) - updateL4Protocol(-1); - if (rbPayloadOther->isChecked()) - updatePayloadProtocol(-1); isUpdateInProgress = false; return; -#undef CHK } void StreamConfigDialog::LoadCurrentStream() From 0094f618d34683dbb3844da646115c1584b6f52b Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 14 Oct 2009 15:16:56 +0000 Subject: [PATCH 26/98] Protocol Framework related -------------------------- - AbstractProtocol Constructor and Factory function now take an optional (default NULL) "parent" abstract protocol in addition to the stream; this "parent" protocol is non-NULL for protocols which are aggregated in a ComboProtocol - All subclasses of AbstractProtocol modified as per the above interface change - ProtocolManager also modifed as per the above interface change - new data members in AbstractProtocol - prev, next; the AbstractProtocol implementation now uses these members to traverse protocols on the list instead of ProtocolListIterator; this change required for ComboProtocol - ProtocolListIterator updates these new members - prev/next on insert/remove/replace - ComboProtocol and ProtocolListIterator classes made friends of AbstractProtocol - ComboProtocol implemented as a template class (completed) - Dot2LLc implemented as a combo of Dot3Raw and LLC - Dot2Snap implemented as a combo of Dot2Llc and SNAP - VlanStack implemented as a combo of VLAN + VLAN - ProtocolManager now uses the ProtocolId enums rather than hardcoded values Stream Config Dialog -------------------- - "None" radio button added to all protocol levels - Protocol Level 1 added with 'mac' as the only valid protocol in the "simple" mode widget - With Dot2Llc, Dot2Snap and VlanStack implemented as "combo" protocols, the protocol choice radiobuttons in the "simple" mode are now 1:1 with a protocol; this has the following implications/advantages: - Updates of the "simple" mode widget from/to stream's protocolList is simpler; this code has now been rewritten to take advantage of 1:1 - This paves the way for exporting tunneled protocols 4over4, 4over6, 6over4 etc. in the "simple" mode - This should also (hopefully) require less changes when adding a new protocol; more work needs to be done to reach this goal Fixes ----- - Dot3Protocol now derives "length" correctly for VLAN tagged packets - StreamBase now uses the ProtocolListIterator to append the default protocols in a stream instead of directly manipulating ProtocolList; also in protoDataCopyFrom() Others (Client/Server) ---------------------- - Port Packet Capture implemented; "view capture" is pending (hack put in place now for testing) --- client/packetmodel.cpp | 5 +- client/portgroup.cpp | 108 +++++ client/portgroup.h | 7 + client/portstatswindow.cpp | 36 ++ client/streamconfigdialog.cpp | 711 +++++++++----------------------- client/streamconfigdialog.h | 34 +- client/streamconfigdialog.ui | 224 ++++++---- common/abstractprotocol.cpp | 101 ++--- common/abstractprotocol.h | 15 +- common/comboprotocol.h | 87 ++-- common/dot2llc.h | 11 + common/dot2llc.proto | 14 + common/dot2snap.h | 11 + common/dot2snap.proto | 12 + common/dot3.cpp | 20 +- common/dot3.h | 5 +- common/eth2.cpp | 9 +- common/eth2.h | 5 +- common/ip4.cpp | 11 +- common/ip4.h | 5 +- common/llc.cpp | 9 +- common/llc.h | 5 +- common/mac.cpp | 9 +- common/mac.h | 5 +- common/ostproto.pro | 6 + common/payload.cpp | 9 +- common/payload.h | 5 +- common/protocol.proto | 4 + common/protocollistiterator.cpp | 31 +- common/protocollistiterator.h | 4 +- common/protocolmanager.cpp | 51 ++- common/protocolmanager.h | 6 +- common/sample.cpp | 9 +- common/sample.h | 5 +- common/snap.cpp | 9 +- common/snap.h | 5 +- common/streambase.cpp | 18 +- common/tcp.cpp | 9 +- common/tcp.h | 5 +- common/udp.cpp | 9 +- common/udp.h | 5 +- common/vlan.cpp | 9 +- common/vlan.h | 5 +- common/vlanstack.h | 10 + common/vlanstack.proto | 12 + server/myservice.cpp | 109 ++++- server/myservice.h | 21 + 47 files changed, 1029 insertions(+), 786 deletions(-) create mode 100644 common/dot2llc.h create mode 100644 common/dot2llc.proto create mode 100644 common/dot2snap.h create mode 100644 common/dot2snap.proto create mode 100644 common/vlanstack.h create mode 100644 common/vlanstack.proto diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 7d9df3d..908de63 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -46,7 +46,7 @@ int PacketModel::rowCount(const QModelIndex &parent) const qWarning("%s: Unhandled ItemType", __FUNCTION__); } - Q_ASSERT(1 == 1); // Unreachable code + Q_ASSERT(1 == 0); // Unreachable code qWarning("%s: Catch all - need to investigate", __FUNCTION__); return 0; // catch all } @@ -86,13 +86,14 @@ QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) cons goto _exit; case ITYP_FIELD: + Q_ASSERT(1 == 0); // Unreachable code goto _exit; default: qWarning("%s: Unhandled ItemType", __FUNCTION__); } - Q_ASSERT(1 == 1); // Unreachable code + Q_ASSERT(1 == 0); // Unreachable code _exit: return index; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index f9f84d2..4614528 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -479,6 +479,93 @@ _exit: return; } +void PortGroup::startCapture(QList *portList) +{ + OstProto::PortIdList portIdList; + OstProto::Ack *ack; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + ack = new OstProto::Ack; + if (portList == NULL) + goto _exit; + else + { + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + } + + serviceStub->startCapture(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStartCaptureAck, ack)); +_exit: + return; +} + +void PortGroup::stopCapture(QList *portList) +{ + OstProto::PortIdList portIdList; + OstProto::Ack *ack; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + ack = new OstProto::Ack; + if (portList == NULL) + goto _exit; + else + { + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + } + + serviceStub->stopCapture(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStopCaptureAck, ack)); +_exit: + return; +} + +void PortGroup::viewCapture(QList *portList) +{ + OstProto::PortIdList portIdList; + OstProto::CaptureBufferList *bufList; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + bufList = new OstProto::CaptureBufferList; + if (portList == NULL) + goto _exit; + else + { + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + } + + serviceStub->getCaptureBuffer(rpcController, &portIdList, bufList, + NewCallback(this, &PortGroup::processViewCaptureAck, bufList)); +_exit: + return; +} + void PortGroup::processStartTxAck(OstProto::Ack *ack) { qDebug("In %s", __FUNCTION__); @@ -493,6 +580,27 @@ void PortGroup::processStopTxAck(OstProto::Ack *ack) delete ack; } +void PortGroup::processStartCaptureAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + delete ack; +} + +void PortGroup::processStopCaptureAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + delete ack; +} + +void PortGroup::processViewCaptureAck(OstProto::CaptureBufferList *bufList) +{ + qDebug("In %s", __FUNCTION__); + + delete bufList; +} + void PortGroup::getPortStats() { OstProto::PortStatsList *portStatsList; diff --git a/client/portgroup.h b/client/portgroup.h index 2ffcbaf..c297674 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -75,6 +75,13 @@ public: void stopTx(QList *portList = NULL); void processStopTxAck(OstProto::Ack *ack); + void startCapture(QList *portList = NULL); + void processStartCaptureAck(OstProto::Ack *ack); + void stopCapture(QList *portList = NULL); + void processStopCaptureAck(OstProto::Ack *ack); + void viewCapture(QList *portList = NULL); + void processViewCaptureAck(OstProto::CaptureBufferList *bufList); + void getPortStats(); void processPortStatsList(OstProto::PortStatsList *portStatsList); void clearPortStats(QList *portList = NULL); diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index d1340a6..26e2b10 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -61,16 +61,52 @@ void PortStatsWindow::on_tbStopTransmit_clicked() void PortStatsWindow::on_tbStartCapture_clicked() { // TODO(MED) + QList pgpl; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + startCapture(&pgpl[i].portList); + } } void PortStatsWindow::on_tbStopCapture_clicked() { // TODO(MED) + QList pgpl; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + stopCapture(&pgpl[i].portList); + } } void PortStatsWindow::on_tbViewCapture_clicked() { // TODO(MED) + QList pgpl; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + viewCapture(&pgpl[i].portList); + } } void PortStatsWindow::on_tbClear_clicked() diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 9bdae53..30649b3 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -27,18 +27,13 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, setupUi(this); setupUiExtra(); - connect(bgL1Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateL1Protocol(int))); - connect(bgL2Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateFrameTypeProtocol(int))); - connect(bgVlan, SIGNAL(buttonClicked(int)), - this, SLOT(updateVlanProtocol(int))); - connect(bgL3Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateL3Protocol(int))); - connect(bgL4Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateL4Protocol(int))); - connect(bgPayloadProto, SIGNAL(buttonClicked(int)), - this, SLOT(updatePayloadProtocol(int))); + for (int i = ProtoMin; i < ProtoMax; i++) + { + bgProto[i]->setProperty("ProtocolLevel", i); + bgProto[i]->setProperty("ProtocolId", ButtonIdNone); + connect(bgProto[i], SIGNAL(buttonClicked(int)), + this, SLOT(updateProtocol(int))); + } //! \todo causes a crash! #if 0 @@ -48,35 +43,16 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // Time to play match the signals and slots! - // Enable VLAN Choices only if FT = Eth2 or SNAP -#if 0 - connect(rbFtNone, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool))); - connect(rbFtOther, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool))); - connect(rbFtNone, SIGNAL(clicked(bool)), rbVlanNone, SLOT(click())); -#endif - - // Force all protocols = None if L1 = None - connect(rbL1None, SIGNAL(clicked(bool)), rbVlanNone, SLOT(click())); - connect(rbL1None, SIGNAL(clicked(bool)), rbFtNone, SLOT(click())); - connect(rbL1None, SIGNAL(clicked(bool)), rbPayloadNone, SLOT(click())); - - connect(rbFtNone, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); - - // Enable/Disable L3 Protocol Choices for FT None - connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); + // If L1/FT = None, force subsequent protocol level(s) also to None + connect(rbL1None, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool))); // Enable/Disable L3 Protocol Choices for FT Ethernet2 - connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); // Force L3 = None if FT = 802.3 Raw connect(rbFt802Dot3Raw, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); - - // Enable/Disable L3 Protocol Choices for FT 802Dot3Raw - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool))); connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); @@ -84,12 +60,10 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFt802Dot3Llc, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); // Enable/Disable L3 Protocol Choices for FT 802Dot3Llc - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); // Enable/Disable L3 Protocol Choices for FT 802.3 LLC SNAP - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); @@ -97,25 +71,16 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool))); connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool))); - // Enable/Disable L4 Protocol Choices for L3 Protocol None - connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); - connect(rbL3None, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool))); - connect(rbL3None, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool))); - connect(rbL3None, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool))); - connect(rbL3None, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool))); - - // Force L4 Protocol = None if L3 Protocol is set to None - connect(rbL3None, SIGNAL(clicked(bool)), rbL4None, SLOT(click())); + // If L3 = None, force subsequent protocol level also to None + connect(rbL3None, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool))); // Enable/Disable L4 Protocol Choices for L3 Protocol IPv4 - connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setEnabled(bool))); // Enable/Disable L4 Protocol Choices for L3 Protocol ARP - connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool))); connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool))); connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool))); @@ -183,66 +148,62 @@ void StreamConfigDialog::setupUiExtra() QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); // ---- Setup default stuff that cannot be done in designer ---- -#if 0 - gbVlan->setDisabled(true); -#endif + bgProto[ProtoL1] = new QButtonGroup(); + bgProto[ProtoL1]->addButton(rbL1None, ButtonIdNone); + bgProto[ProtoL1]->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber); + bgProto[ProtoL1]->addButton(rbL1Other, ButtonIdOther); - bgL1Proto = new QButtonGroup(); - bgL1Proto->addButton(rbL1None, ButtonIdNone); - bgL1Proto->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber); - bgL1Proto->addButton(rbL1Other, ButtonIdOther); - - bgL2Proto = new QButtonGroup(); + bgProto[ProtoL2] = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbFrameType->findChildren()) bgL2Proto->addButton(btn); #else - bgL2Proto->addButton(rbFtNone, ButtonIdNone); - bgL2Proto->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); - bgL2Proto->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); - bgL2Proto->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); - bgL2Proto->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); - bgL2Proto->addButton(rbFtOther, ButtonIdOther); + bgProto[ProtoL2]->addButton(rbFtNone, ButtonIdNone); + bgProto[ProtoL2]->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); + bgProto[ProtoL2]->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); + bgProto[ProtoL2]->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); + bgProto[ProtoL2]->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); + bgProto[ProtoL2]->addButton(rbFtOther, ButtonIdOther); #endif - bgVlan = new QButtonGroup(); - bgVlan->addButton(rbVlanNone, ButtonIdNone); - bgVlan->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); - bgVlan->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); + bgProto[ProtoVlan] = new QButtonGroup(); + bgProto[ProtoVlan]->addButton(rbVlanNone, ButtonIdNone); + bgProto[ProtoVlan]->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); + bgProto[ProtoVlan]->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); - bgL3Proto = new QButtonGroup(); + bgProto[ProtoL3] = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbL3Proto->findChildren()) - bgL3Proto->addButton(btn); + bgProto[ProtoL3]->addButton(btn); #else - bgL3Proto->addButton(rbL3None, ButtonIdNone); - bgL3Proto->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); - bgL3Proto->addButton(rbL3Ipv6, 0xFFFF); - bgL3Proto->addButton(rbL3Arp, 0xFFFF); - bgL3Proto->addButton(rbL3Other, ButtonIdOther); + bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone); + bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); + bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Arp, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther); #endif - bgL4Proto = new QButtonGroup(); + bgProto[ProtoL4] = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbL4Proto->findChildren()) - bgL4Proto->addButton(btn); + bgProto[ProtoL4]->addButton(btn); #else - bgL4Proto->addButton(rbL4None, 0); - bgL4Proto->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); - bgL4Proto->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); - bgL4Proto->addButton(rbL4Icmp, 0xFFFF); - bgL4Proto->addButton(rbL4Igmp, 0xFFFF); - bgL4Proto->addButton(rbL4Other, ButtonIdOther); + bgProto[ProtoL4]->addButton(rbL4None, 0); + bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); + bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); + bgProto[ProtoL4]->addButton(rbL4Icmp, 0xFFFF); + bgProto[ProtoL4]->addButton(rbL4Igmp, 0xFFFF); + bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther); #endif - bgPayloadProto = new QButtonGroup(); + bgProto[ProtoPayload] = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbPayloadProto->findChildren()) - bgPayloadProto->addButton(btn); + bgProto[ProtoPayload]->addButton(btn); #else - bgPayloadProto->addButton(rbPayloadNone, ButtonIdNone); - bgPayloadProto->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); - bgPayloadProto->addButton(rbPayloadOther, ButtonIdOther); + bgProto[ProtoPayload]->addButton(rbPayloadNone, ButtonIdNone); + bgProto[ProtoPayload]->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); + bgProto[ProtoPayload]->addButton(rbPayloadOther, ButtonIdOther); #endif /* ** Setup Validators @@ -270,12 +231,8 @@ StreamConfigDialog::~StreamConfigDialog() delete mpPacketModelTester; delete mpPacketModel; - delete bgL1Proto; - delete bgL2Proto; - delete bgVlan; - delete bgL3Proto; - delete bgL4Proto; - delete bgPayloadProto; + for (int i = ProtoMin; i < ProtoMax; i++) + delete bgProto[i]; delete _iter; delete mpStream; @@ -594,149 +551,122 @@ void StreamConfigDialog::on_lePattern_editingFinished() /*! Skip protocols upto and including the layer specified. - 0 - L1 - 1 - VLAN - 2 - L2 - 3 - L3 - 4 - L4 -TODO: Convert the above values to enum?? */ bool StreamConfigDialog::skipProtocols(int layer) { - int id; - QAbstractButton *btn; - _iter->toFront(); - // Skip L1 - if (_iter->hasNext()) + for (int i = ProtoMin; i <= layer; i++) { - id = _iter->next()->protocolNumber(); - btn = bgL1Proto->button(id); - if (btn == NULL) - _iter->previous(); + if(_iter->hasNext()) + { + int id; + QAbstractButton *btn; + + id = _iter->peekNext()->protocolNumber(); + btn = bgProto[i]->button(id); + if (btn) + _iter->next(); + } } - if (layer == 0) - goto _done; - - // Skip VLAN - if(_iter->hasNext()) - { - id = _iter->next()->protocolNumber(); - btn = bgVlan->button(id); - if (btn == NULL) - _iter->previous(); - } - - if (layer == 1) - goto _done; - - // Skip L2 - if(_iter->hasNext()) - { - id = _iter->next()->protocolNumber(); - btn = bgL2Proto->button(id); - if (btn == NULL) - _iter->previous(); - } - - if (layer == 2) - goto _done; - - // Skip L3 - if (_iter->hasNext()) - { - id = _iter->next()->protocolNumber(); - btn = bgL3Proto->button(id); - if (btn == NULL) - _iter->previous(); - } - - if (layer == 3) - goto _done; - - // Skip L4 - if(_iter->hasNext()) - { - id = _iter->next()->protocolNumber(); - btn = bgL4Proto->button(id); - if (btn == NULL) - _iter->previous(); - } - - if (layer == 4) - goto _done; - - return false; - -_done: return true; } -void StreamConfigDialog::updateL1Protocol(int newId) +/*! +Protocol choices (except "None" and "Other") for a protocol button group are disabled if checked is true, else they are enabled +*/ +void StreamConfigDialog::disableProtocols(QButtonGroup *protocolGroup, bool checked) { - static int oldId; - - qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, - isUpdateInProgress); - - if (oldId == newId) - return; // Nothing to be done - - if (!isUpdateInProgress) + qDebug("%s: btnGrp = %p, chk? = %d", __FUNCTION__, protocolGroup, checked); + foreach(QAbstractButton *btn, protocolGroup->buttons()) { - AbstractProtocol *p; + int id = protocolGroup->id(btn); - _iter->toFront(); - - Q_ASSERT(newId != ButtonIdOther); - - switch (oldId) - { - case ButtonIdNone: - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - - case ButtonIdOther: - default: - Q_ASSERT(_iter->hasNext()); - p =_iter->next(); - - if (newId) - _iter->setValue(OstProtocolManager.createProtocol( - newId, mpStream)); - else - _iter->remove(); - delete p; - break; - } + if ((id != ButtonIdNone) && (id != ButtonIdOther)) + btn->setDisabled(checked); } - - oldId = newId; - return; } -void StreamConfigDialog::updateVlanProtocol(int newId) +void StreamConfigDialog::forceProtocolNone(bool checked) { - static int oldId; + QObject *btn; - qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, - isUpdateInProgress); + btn = sender(); + Q_ASSERT(btn != NULL); - if (oldId == newId) - return; // Nothing to be done + qDebug("%s: chk? = %d, btn = %p, L1 = %p, L2 = %p, L3 = %p", __FUNCTION__, + checked, btn, rbL1None, rbFtNone, rbL3None); + + if (btn == rbL1None) + { + if (checked) + { + bgProto[ProtoVlan]->button(ButtonIdNone)->click(); + bgProto[ProtoL2]->button(ButtonIdNone)->click(); + bgProto[ProtoPayload]->button(ButtonIdNone)->click(); + } + + disableProtocols(bgProto[ProtoVlan], checked); + disableProtocols(bgProto[ProtoL2], checked); + disableProtocols(bgProto[ProtoPayload], checked); + } + else if (btn == rbFtNone) + { + if (checked) + bgProto[ProtoL3]->button(ButtonIdNone)->click(); + disableProtocols(bgProto[ProtoL3], checked); + } + else if (btn == rbL3None) + { + if (checked) + bgProto[ProtoL4]->button(ButtonIdNone)->click(); + disableProtocols(bgProto[ProtoL4], checked); + } + else + { + Q_ASSERT(1 == 0); // Unreachable code! + } +} + +void StreamConfigDialog::updateProtocol(int newId) +{ + int level; + QButtonGroup *btnGrp; + + btnGrp = static_cast(sender()); + Q_ASSERT(btnGrp != NULL); + + level = btnGrp->property("ProtocolLevel").toInt(); + Q_ASSERT(btnGrp == bgProto[level]); + + __updateProtocol(level, newId); +} + +void StreamConfigDialog::__updateProtocol(int level, int newId) +{ + int oldId; + QButtonGroup *btnGrp; + + Q_ASSERT((level >= ProtoMin) && (level <= ProtoMax)); + btnGrp = bgProto[level]; + oldId = btnGrp->property("ProtocolId").toInt(); + + qDebug("%s: level = %d old id = %d new id = %d upd? = %d", __FUNCTION__, + level, oldId, newId, isUpdateInProgress); + + if (newId == oldId) + return; if (!isUpdateInProgress) { int ret; AbstractProtocol *p; - ret = skipProtocols(0); - + ret = skipProtocols(level-1); Q_ASSERT(ret == true); - Q_ASSERT(oldId != ButtonIdOther); + + Q_ASSERT(oldId != newId); Q_ASSERT(newId != ButtonIdOther); switch (oldId) @@ -757,347 +687,96 @@ void StreamConfigDialog::updateVlanProtocol(int newId) else _iter->remove(); delete p; - break; - } - } - - oldId = newId; - return; -} - -void StreamConfigDialog::updateFrameTypeProtocol(int newId) -{ - static int oldId; - - qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, - isUpdateInProgress); - - if (oldId == newId) - return; // Nothing to be done - - if (!isUpdateInProgress) - { - int ret; - AbstractProtocol *p; - - ret = skipProtocols(1); - - Q_ASSERT(ret == true); - Q_ASSERT(newId != ButtonIdOther); - - switch (oldId) - { - case ButtonIdNone: - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - - case ButtonIdOther: - default: - Q_ASSERT(_iter->hasNext()); - p =_iter->next(); - - if (newId) - _iter->setValue(OstProtocolManager.createProtocol( - newId, mpStream)); - else - _iter->remove(); - delete p; - break; - } - } - - oldId = newId; - return; -} - -void StreamConfigDialog::updateL3Protocol(int newId) -{ - static int oldId; - - qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, - isUpdateInProgress); - - if (oldId == newId) - return; // Nothing to be done - - if (!isUpdateInProgress) - { - int ret; - AbstractProtocol *p; - - ret = skipProtocols(2); - - Q_ASSERT(ret == true); - Q_ASSERT(newId != ButtonIdOther); - - switch (oldId) - { - case ButtonIdNone: - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - - case ButtonIdOther: - default: - Q_ASSERT(_iter->hasNext()); - p =_iter->next(); - - if (newId) - _iter->setValue(OstProtocolManager.createProtocol( - newId, mpStream)); - else - _iter->remove(); - delete p; - break; - } - } - - oldId = newId; - return; -} - -void StreamConfigDialog::updateL4Protocol(int newId) -{ - static int oldId; - - qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, - isUpdateInProgress); - - if (oldId == newId) - return; // Nothing to be done - - if (!isUpdateInProgress) - { - int ret; - AbstractProtocol *p; - - ret = skipProtocols(3); - - Q_ASSERT(ret == true); - Q_ASSERT(newId != ButtonIdOther); - - switch (oldId) - { - case ButtonIdNone: - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - - case ButtonIdOther: - default: - Q_ASSERT(_iter->hasNext()); - p =_iter->next(); - - if (newId) - _iter->setValue(OstProtocolManager.createProtocol( - newId, mpStream)); - else - _iter->remove(); - delete p; - break; - } - } - - oldId = newId; - return; -} - -void StreamConfigDialog::updatePayloadProtocol(int newId) -{ - static int oldId; - - qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, - isUpdateInProgress); - - if (oldId == newId) - return; // Nothing to be done - - if (!isUpdateInProgress) - { - int ret; - AbstractProtocol *p; - - ret = skipProtocols(4); - - Q_ASSERT(ret == true); - Q_ASSERT(newId != ButtonIdOther); - - switch (oldId) - { - case ButtonIdNone: - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - - case ButtonIdOther: - default: - Q_ASSERT(_iter->hasNext()); - p =_iter->next(); - - if (newId) - _iter->setValue(OstProtocolManager.createProtocol( - newId, mpStream)); - else - _iter->remove(); - delete p; - while (_iter->hasNext()) + if (level == ProtoPayload) { - - p = _iter->next(); - _iter->remove(); - delete p; + while (_iter->hasNext()) + { + p = _iter->next(); + _iter->remove(); + delete p; + } } break; } } - oldId = newId; + btnGrp->setProperty("ProtocolId", newId); return; } void StreamConfigDialog::updateSelectProtocolsSimpleWidget() { - quint32 id; + int i; + quint32 id; QAbstractButton *btn; qDebug("%s", __FUNCTION__); isUpdateInProgress = true; - // Reset to default state - rbL1None->setChecked(true); - rbVlanNone->setChecked(true); - rbFtNone->setChecked(true); - rbL3None->setChecked(true); - rbL4None->setChecked(true); - rbPayloadNone->setChecked(true); + // Reset to default state ... + for (i = ProtoMin; i < ProtoMax; i++) + bgProto[i]->button(ButtonIdNone)->click(); + // ... now iterate and update _iter->toFront(); - // L1 (optional if followed by Payload) - if (!_iter->hasNext()) // No protocols at all? - goto _done; - - id = _iter->next()->protocolNumber(); - btn = bgL1Proto->button(id); - - if (btn && btn->isEnabled()) - btn->click(); - else + for (i = ProtoMin; i < ProtoMax; i++) { - btn = bgPayloadProto->button(id); + if (!_iter->hasNext()) + goto _done; + + id = _iter->next()->protocolNumber(); + btn = bgProto[i]->button(id); + if (btn && btn->isEnabled()) - goto _payload; + btn->click(); else - goto _otherL1; + { + switch (i) + { + case ProtoVlan: + _iter->previous(); + break; + + case ProtoPayload: + goto _other; + + default: + btn = bgProto[ProtoPayload]->button(id); + if (btn && btn->isEnabled()) + { + btn->click(); + break; + } + else + goto _other; + } + } } - // VLAN (optional) - if (!_iter->hasNext()) - goto _done; - - id = _iter->next()->protocolNumber(); - btn = bgVlan->button(id); - - if (btn && btn->isEnabled()) - btn->click(); - else - _iter->previous(); - - // L2 (optional if followed by Payload) - if (!_iter->hasNext()) - goto _done; - - id = _iter->next()->protocolNumber(); - btn = bgL2Proto->button(id); - - if (btn && btn->isEnabled()) - btn->click(); - else - { - btn = bgPayloadProto->button(id); - if (btn && btn->isEnabled()) - goto _payload; - else - goto _otherL2; - } - - // L3 (optional if followed by Payload) - if (!_iter->hasNext()) - goto _done; - - id = _iter->next()->protocolNumber(); - btn = bgL3Proto->button(id); - - if (btn && btn->isEnabled()) - btn->click(); - else - { - btn = bgPayloadProto->button(id); - if (btn && btn->isEnabled()) - goto _payload; - else - goto _otherL3; - } - - // L4 (optional if followed by Payload) - if (!_iter->hasNext()) - goto _done; - - id = _iter->next()->protocolNumber(); - btn = bgL4Proto->button(id); - - if (btn && btn->isEnabled()) - btn->click(); - else - { - btn = bgPayloadProto->button(id); - if (btn && btn->isEnabled()) - goto _payload; - else - goto _otherL4; - } - - // Payload Data - if (!_iter->hasNext()) - goto _done; - - id = _iter->next()->protocolNumber(); - btn = bgPayloadProto->button(id); - -_payload: - if (btn && btn->isEnabled()) - btn->click(); - else - goto _otherPayload; - // If more protocol(s) beyond payload ... if (_iter->hasNext()) - goto _otherPayload; + { + i = ProtoPayload; + goto _other; + } goto _done; -_otherL1: - bgL1Proto->button(ButtonIdOther)->setChecked(true); - updateL1Protocol(ButtonIdOther); -_otherL2: - bgL2Proto->button(ButtonIdOther)->setChecked(true); - updateFrameTypeProtocol(ButtonIdOther); -_otherL3: - bgL3Proto->button(ButtonIdOther)->setChecked(true); - updateL3Protocol(ButtonIdOther); -_otherL4: - bgL4Proto->button(ButtonIdOther)->setChecked(true); - updateL4Protocol(ButtonIdOther); -_otherPayload: - bgPayloadProto->button(ButtonIdOther)->setChecked(true); - updatePayloadProtocol(ButtonIdOther); +_other: + for (int j = i; j < ProtoMax; j++) + { + // VLAN doesn't have a "Other" button + if (j == ProtoVlan) + continue; + + bgProto[j]->button(ButtonIdOther)->setChecked(true); + __updateProtocol(j, ButtonIdOther); + } _done: isUpdateInProgress = false; - - return; } void StreamConfigDialog::LoadCurrentStream() diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 4b774f7..5909e8e 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -28,11 +28,25 @@ public: private: - QButtonGroup *bgFrameType; - QButtonGroup *bgVlan; - QButtonGroup *bgL3Proto; - QButtonGroup *bgL4Proto; - QButtonGroup *bgPayloadProto; + enum ButtonId + { + ButtonIdNone = 0, + ButtonIdOther = -2 + }; + + enum ProtoButtonGroup + { + ProtoMin, + ProtoL1 = 0, + ProtoVlan = 1, + ProtoL2 = 2, + ProtoL3 = 3, + ProtoL4 = 4, + ProtoPayload = 5, + ProtoMax + }; + + QButtonGroup *bgProto[ProtoMax]; QStringListModel *mpAvailableProtocolsModel; QStringListModel *mpSelectedProtocolsModel; @@ -68,11 +82,11 @@ private slots: // "Simple" Protocol Selection related bool skipProtocols(int layer); - void updateFrameTypeProtocol(int id); - void updateVlanProtocol(int id); - void updateL3Protocol(int id); - void updateL4Protocol(int id); - void updatePayloadProtocol(int id); + void disableProtocols(QButtonGroup *protocolGroup, bool checked); + void forceProtocolNone(bool checked); + + void updateProtocol(int newId); + void __updateProtocol(int level, int newId); void updateSelectProtocolsSimpleWidget(); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 6e15d3b..07457e6 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,8 +8,8 @@ 0 0 - 524 - 458 + 569 + 464 @@ -173,7 +173,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff 0 0 - 465 + 527 226 @@ -181,16 +181,58 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff Simple - - + + - Frame Type + L1 + + + + + + None + + + true + + + + + + + Mac + + + false + + + + + + + false + + + Other + + + + + + + + + + true + + + L2 - None (Mac Only) + None true @@ -244,50 +286,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - + + true - - VLAN - - - false - - - false - - - - - - None - - - true - - - - - - - Single Tag - - - - - - - Double Tag - - - - - - - - L3 @@ -348,8 +351,95 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + + + + true + + + Payload + + + + + + None + + + true + + + + + + + Pattern + + + false + + + + + + + false + + + Other + + + + + + + + + + true + + + VLAN + + + false + + + false + + + + + + Untagged + + + true + + + + + + + Tagged + + + + + + + Stacked + + + + + + + + + true + L4 @@ -417,44 +507,15 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - - - Payload - - - - - - Pattern - - - true - - - - - - - false - - - Other - - - - - - - + Qt::Vertical - 107 - 24 + 20 + 21 @@ -1084,7 +1145,6 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff lePktLen lePktLenMin lePktLenMax - rbFtNone rbFtEthernet2 rbFt802Dot3Raw rbFt802Dot3Llc diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 2bac712..24355f2 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -22,9 +22,12 @@ - metaFieldCount() - isMetaField() */ -AbstractProtocol::AbstractProtocol(StreamBase *stream) +AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent) { + //qDebug("%s: &prev = %p &next = %p", __FUNCTION__, &prev, &next); mpStream = stream; + this->parent = parent; + prev = next = NULL; metaCount = -1; protoSize = -1; } @@ -33,7 +36,8 @@ AbstractProtocol::~AbstractProtocol() { } -AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream) +AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { return NULL; } @@ -139,6 +143,7 @@ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int index) const FieldFrameValue, the subclass should handle and return a value for FieldBitSize to prevent endless recrusion - - protocolFrameCksum() + - protocolFramePayloadSize() */ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const @@ -184,17 +189,16 @@ quint32 AbstractProtocol::protocolId(ProtocolIdType type) const quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const { - quint32 id = 0xFFFFFFFF; - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); + quint32 id; - if (iter->findNext(this)) - { - if (iter->hasNext()) - id = iter->next()->protocolId(type); - } - delete iter; + if (next) + id = next->protocolId(type); + else if (parent) + id = parent->payloadProtocolId(type); + else + id = 0xFFFFFFFF; - qDebug("%s: payloadProtocolId = %u", __FUNCTION__, id); + qDebug("%s: payloadProtocolId = 0x%x", __FUNCTION__, id); return id; } @@ -219,17 +223,15 @@ int AbstractProtocol::protocolFrameSize() const int AbstractProtocol::protocolFrameOffset() const { int size = 0; - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); - - if (iter->findNext(this)) + AbstractProtocol *p = prev; + while (p) { - iter->previous(); - while (iter->hasPrevious()) - size += iter->previous()->protocolFrameSize(); + size += p->protocolFrameSize(); + p = p->prev; } - else - return -1; - delete iter; + + if (parent) + size += parent->protocolFrameOffset(); qDebug("%s: ofs = %d", __FUNCTION__, size); return size; @@ -238,17 +240,14 @@ int AbstractProtocol::protocolFrameOffset() const int AbstractProtocol::protocolFramePayloadSize() const { int size = 0; - - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); - - if (iter->findNext(this)) + AbstractProtocol *p = next; + while (p) { - while (iter->hasNext()) - size += iter->next()->protocolFrameSize(); + size += p->protocolFrameSize(); + p = p->next; } - else - return -1; - delete iter; + if (parent) + size += parent->protocolFramePayloadSize(); qDebug("%s: payloadSize = %d", __FUNCTION__, size); return size; @@ -361,7 +360,7 @@ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex, CksumType cksumType) const { static int recursionCount = 0; - quint32 cksum = 0; + quint32 cksum = 0xFFFFFFFF; recursionCount++; Q_ASSERT_X(recursionCount < 10, "protocolFrameCksum", "potential infinite recursion - does a protocol checksum field not implement FieldBitSize?"); @@ -426,19 +425,24 @@ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex, quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, CksumType cksumType) const { - quint32 sum = 0xFFFF; - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); + quint32 sum = 0; + quint16 cksum; + AbstractProtocol *p = prev; Q_ASSERT(cksumType == CksumIpPseudo); - if (iter->findNext(this)) + while (p) { - iter->previous(); - if (iter->hasPrevious()) - sum = iter->previous()->protocolFrameCksum(streamIndex, - CksumIpPseudo); + cksum = p->protocolFrameCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; + p = p->prev; + qDebug("%s: sum = %u, cksum = %u", __FUNCTION__, sum, cksum); + } + if (parent) + { + cksum = parent->protocolFrameHeaderCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; } - delete iter; while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); @@ -451,21 +455,22 @@ quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, { quint32 sum = 0; quint16 cksum; - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); + AbstractProtocol *p = next; Q_ASSERT(cksumType == CksumIp); - if (iter->findNext(this)) + while (p) { - while (iter->hasNext()) - { - cksum = iter->next()->protocolFrameCksum(streamIndex, CksumIp); - sum += (quint16) ~cksum; - } + cksum = p->protocolFrameCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; + p = p->next; + } + + if (parent) + { + cksum = parent->protocolFramePayloadCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; } - else - return 0; - delete iter; while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index aca2d2d..13db703 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -20,16 +20,24 @@ QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) class StreamBase; +class ProtocolListIterator; class AbstractProtocol { + template + friend class ComboProtocol; + friend class ProtocolListIterator; + private: mutable int metaCount; mutable int protoSize; mutable QString protoAbbr; protected: - StreamBase *mpStream; + StreamBase *mpStream; + AbstractProtocol *parent; + AbstractProtocol *prev; + AbstractProtocol *next; public: enum FieldFlag { @@ -61,10 +69,11 @@ public: CksumMax }; - AbstractProtocol(StreamBase *stream); + AbstractProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~AbstractProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const = 0; diff --git a/common/comboprotocol.h b/common/comboprotocol.h index 62828cb..34cba86 100644 --- a/common/comboprotocol.h +++ b/common/comboprotocol.h @@ -3,7 +3,7 @@ #include "abstractprotocol.h" -template +template class ComboProtocol : public AbstractProtocol { private: @@ -12,36 +12,67 @@ private: QWidget *configForm; public: - ComboProtocol(StreamBase *stream) + ComboProtocol(StreamBase *stream, AbstractProtocol *parent = 0) + : AbstractProtocol(stream, parent) { - protoA = new ProtoA(stream); - protoB = new ProtoB(stream); + protoA = new ProtoA(stream, this); + protoB = new ProtoB(stream, this); + protoA->next = protoB; + protoB->prev = protoA; configForm = NULL; - } - virtual ~ComboProtocol() - { - delete protoA; - delete protoB; - delete configForm; + + qDebug("%s: protoNumber = %d, %p <--> %p", __FUNCTION__, + protoNumber, protoA, protoB); } - static ComboProtocol* createInstance(StreamBase *stream) + virtual ~ComboProtocol() { - return new ComboProtocol(stream); + if (configForm) + { + protoA->configWidget()->setParent(0); + protoB->configWidget()->setParent(0); + delete configForm; + } + delete protoA; + delete protoB; + } + + static ComboProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent) + { + return new ComboProtocol(stream, parent); } virtual quint32 protocolNumber() const { - return 0; //FIXME + return protoNumber; } virtual void protoDataCopyInto(OstProto::Protocol &protocol) const { - // FIXME + protoA->protoDataCopyInto(protocol); + protoB->protoDataCopyInto(protocol); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) { - // FIXME + if (protocol.protocol_id().id() == protocolNumber()) + { + OstProto::Protocol proto; + + // NOTE: To use protoX->protoDataCopyFrom() we need to arrange + // so that it sees its own protocolNumber() - but since the + // input param 'protocol' is 'const', we make a copy first + + proto.CopyFrom(protocol); + + proto.mutable_protocol_id()->set_id(protoA->protocolNumber()); + protoA->protoDataCopyFrom(proto); + + proto.mutable_protocol_id()->set_id(protoB->protocolNumber()); + protoB->protoDataCopyFrom(proto); + } } virtual QString name() const @@ -68,26 +99,32 @@ public: virtual FieldFlags fieldFlags(int index) const { - if (index < protoA->fieldCount()) + int cnt = protoA->fieldCount(); + + if (index < cnt) return protoA->fieldFlags(index); else - return protoB->fieldFlags(index); + return protoB->fieldFlags(index - cnt); } virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const { - if (index < protoA->fieldCount()) - return protoA->fieldData(index); + int cnt = protoA->fieldCount(); + + if (index < cnt) + return protoA->fieldData(index, attrib, streamIndex); else - return protoB->fieldData(index); + return protoB->fieldData(index - cnt, attrib, streamIndex); } virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue) { - if (index < protoA->fieldCount()) - return protoA->fieldData(index); + int cnt = protoA->fieldCount(); + + if (index < cnt) + return protoA->setFieldData(index, value, attrib); else - return protoB->fieldData(index); + return protoB->setFieldData(index - cnt, value, attrib); } #if 0 @@ -109,11 +146,13 @@ public: { if (configForm == NULL) { - QVBoxLayout *layout = new VBoxLayout; + QVBoxLayout *layout = new QVBoxLayout; configForm = new QWidget; layout->addWidget(protoA->configWidget()); layout->addWidget(protoB->configWidget()); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); configForm->setLayout(layout); } return configForm; diff --git a/common/dot2llc.h b/common/dot2llc.h new file mode 100644 index 0000000..1553549 --- /dev/null +++ b/common/dot2llc.h @@ -0,0 +1,11 @@ +#ifndef _DOT2_LLC_H +#define _DOT2_LLC_H + +#include "comboprotocol.h" +#include "dot3.h" +#include "llc.h" + +typedef ComboProtocol Dot2LlcProtocol; + +#endif diff --git a/common/dot2llc.proto b/common/dot2llc.proto new file mode 100644 index 0000000..3aa1ca4 --- /dev/null +++ b/common/dot2llc.proto @@ -0,0 +1,14 @@ +import "protocol.proto"; +import "dot3.proto"; +import "llc.proto"; + +package OstProto; + +// 802.2 LLC +message Dot2Llc { + // Empty since this is a 'combo' protocol +} + +extend Protocol { + optional Dot2Llc dot2Llc = 127; +} diff --git a/common/dot2snap.h b/common/dot2snap.h new file mode 100644 index 0000000..3eee505 --- /dev/null +++ b/common/dot2snap.h @@ -0,0 +1,11 @@ +#ifndef _DOT2_SNAP_H +#define _DOT2_SNAP_H + +#include "comboprotocol.h" +#include "dot2llc.h" +#include "snap.h" + +typedef ComboProtocol Dot2SnapProtocol; + +#endif diff --git a/common/dot2snap.proto b/common/dot2snap.proto new file mode 100644 index 0000000..b9a03f5 --- /dev/null +++ b/common/dot2snap.proto @@ -0,0 +1,12 @@ +import "protocol.proto"; + +package OstProto; + +// 802.2 SNAP +message Dot2Snap { + // Empty since this is a 'combo' protocol +} + +extend Protocol { + optional Dot2Snap dot2Snap = 128; +} diff --git a/common/dot3.cpp b/common/dot3.cpp index f020b6e..cae0012 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -12,8 +12,8 @@ Dot3ConfigForm::Dot3ConfigForm(QWidget *parent) setupUi(this); } -Dot3Protocol::Dot3Protocol(StreamBase *stream) - : AbstractProtocol(stream) +Dot3Protocol::Dot3Protocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -23,9 +23,10 @@ Dot3Protocol::~Dot3Protocol() delete configForm; } -AbstractProtocol* Dot3Protocol::createInstance(StreamBase *stream) +AbstractProtocol* Dot3Protocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new Dot3Protocol(stream); + return new Dot3Protocol(stream, parent); } quint32 Dot3Protocol::protocolNumber() const @@ -75,14 +76,16 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, { quint16 len; - len = mpStream->frameLen() - SZ_FCS; + //len = mpStream->frameLen() - SZ_FCS; + len = protocolFramePayloadSize(); return len; } case FieldTextValue: { quint16 len; - len = mpStream->frameLen() - SZ_FCS; + //len = mpStream->frameLen() - SZ_FCS; + len = protocolFramePayloadSize(); return QString("%1").arg(len); } case FieldFrameValue: @@ -90,11 +93,14 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, quint16 len; QByteArray fv; - len = mpStream->frameLen() - SZ_FCS; + //len = mpStream->frameLen() - SZ_FCS; + len = protocolFramePayloadSize(); fv.resize(2); qToBigEndian(len, (uchar*) fv.data()); return fv; } + case FieldBitSize: + return 16; default: break; } diff --git a/common/dot3.h b/common/dot3.h index 268e61d..def1031 100644 --- a/common/dot3.h +++ b/common/dot3.h @@ -26,10 +26,11 @@ private: }; public: - Dot3Protocol(StreamBase *stream); + Dot3Protocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~Dot3Protocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/eth2.cpp b/common/eth2.cpp index d1c4b9c..7a6f7b5 100644 --- a/common/eth2.cpp +++ b/common/eth2.cpp @@ -9,8 +9,8 @@ Eth2ConfigForm::Eth2ConfigForm(QWidget *parent) setupUi(this); } -Eth2Protocol::Eth2Protocol(StreamBase *stream) - : AbstractProtocol(stream) +Eth2Protocol::Eth2Protocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ Eth2Protocol::~Eth2Protocol() delete configForm; } -AbstractProtocol* Eth2Protocol::createInstance(StreamBase *stream) +AbstractProtocol* Eth2Protocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new Eth2Protocol(stream); + return new Eth2Protocol(stream, parent); } quint32 Eth2Protocol::protocolNumber() const diff --git a/common/eth2.h b/common/eth2.h index a99efbf..0555d65 100644 --- a/common/eth2.h +++ b/common/eth2.h @@ -26,10 +26,11 @@ private: }; public: - Eth2Protocol(StreamBase *stream); + Eth2Protocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~Eth2Protocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/ip4.cpp b/common/ip4.cpp index 296f09b..4fd594b 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -49,8 +49,8 @@ void Ip4ConfigForm::on_cmbIpDstAddrMode_currentIndexChanged(int index) } } -Ip4Protocol::Ip4Protocol(StreamBase *stream) - : AbstractProtocol(stream) +Ip4Protocol::Ip4Protocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -60,9 +60,10 @@ Ip4Protocol::~Ip4Protocol() delete configForm; } -AbstractProtocol* Ip4Protocol::createInstance(StreamBase *stream) +AbstractProtocol* Ip4Protocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new Ip4Protocol(stream); + return new Ip4Protocol(stream, parent); } quint32 Ip4Protocol::protocolNumber() const @@ -592,7 +593,7 @@ quint32 Ip4Protocol::protocolFrameCksum(int streamIndex, // Above calculation done assuming 'big endian' // - so convert to host order //return qFromBigEndian(sum); - return sum; + return ~sum; } default: break; diff --git a/common/ip4.h b/common/ip4.h index a539e71..e378755 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -59,10 +59,11 @@ private: }; public: - Ip4Protocol(StreamBase *stream); + Ip4Protocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~Ip4Protocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/llc.cpp b/common/llc.cpp index 8fe57af..b352cab 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -9,8 +9,8 @@ LlcConfigForm::LlcConfigForm(QWidget *parent) setupUi(this); } -LlcProtocol::LlcProtocol(StreamBase *stream) - : AbstractProtocol(stream) +LlcProtocol::LlcProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ LlcProtocol::~LlcProtocol() delete configForm; } -AbstractProtocol* LlcProtocol::createInstance(StreamBase *stream) +AbstractProtocol* LlcProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new LlcProtocol(stream); + return new LlcProtocol(stream, parent); } quint32 LlcProtocol::protocolNumber() const diff --git a/common/llc.h b/common/llc.h index 9fe5d28..3555e92 100644 --- a/common/llc.h +++ b/common/llc.h @@ -31,10 +31,11 @@ private: }; public: - LlcProtocol(StreamBase *stream); + LlcProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~LlcProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/mac.cpp b/common/mac.cpp index 7f87a5b..ae80905 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -49,8 +49,8 @@ void MacConfigForm::on_cmbSrcMacMode_currentIndexChanged(int index) } -MacProtocol::MacProtocol(StreamBase *stream) - : AbstractProtocol(stream) +MacProtocol::MacProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -60,9 +60,10 @@ MacProtocol::~MacProtocol() delete configForm; } -AbstractProtocol* MacProtocol::createInstance(StreamBase *stream) +AbstractProtocol* MacProtocol::createInstance(StreamBase *stream + , AbstractProtocol *parent) { - return new MacProtocol(stream); + return new MacProtocol(stream, parent); } quint32 MacProtocol::protocolNumber() const diff --git a/common/mac.h b/common/mac.h index a71e7cc..a493bd6 100644 --- a/common/mac.h +++ b/common/mac.h @@ -40,10 +40,11 @@ private: }; public: - MacProtocol(StreamBase *stream); + MacProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~MacProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/ostproto.pro b/common/ostproto.pro index 0e095a1..9945212 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -22,7 +22,10 @@ PROTOS += \ dot3.proto \ llc.proto \ snap.proto \ + dot2llc.proto \ + dot2snap.proto \ vlan.proto \ + vlanstack.proto \ ip4.proto \ tcp.proto \ udp.proto @@ -39,7 +42,10 @@ HEADERS += \ dot3.h \ llc.h \ snap.h \ + dot2llc.h \ + dot2snap.h \ vlan.h \ + vlanstack.h \ ip4.h \ tcp.h \ udp.h diff --git a/common/payload.cpp b/common/payload.cpp index 6c93cb3..a83817c 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -30,8 +30,8 @@ void PayloadConfigForm::on_cmbPatternMode_currentIndexChanged(int index) } } -PayloadProtocol::PayloadProtocol(StreamBase *stream) - : AbstractProtocol(stream) +PayloadProtocol::PayloadProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -41,9 +41,10 @@ PayloadProtocol::~PayloadProtocol() delete configForm; } -AbstractProtocol* PayloadProtocol::createInstance(StreamBase *stream) +AbstractProtocol* PayloadProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new PayloadProtocol(stream); + return new PayloadProtocol(stream, parent); } quint32 PayloadProtocol::protocolNumber() const diff --git a/common/payload.h b/common/payload.h index 46c1d70..cb93006 100644 --- a/common/payload.h +++ b/common/payload.h @@ -31,10 +31,11 @@ private: }; public: - PayloadProtocol(StreamBase *stream); + PayloadProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~PayloadProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/protocol.proto b/common/protocol.proto index 9788735..372ad54 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -81,8 +81,12 @@ message Protocol { kLlcFieldNumber = 123; kSnapFieldNumber = 124; + kVlanStackFieldNumber = 125; kVlanFieldNumber = 126; + kDot2LlcFieldNumber = 127; + kDot2SnapFieldNumber = 128; + kIp4FieldNumber = 130; kArpFieldNumber = 131; diff --git a/common/protocollistiterator.cpp b/common/protocollistiterator.cpp index 20a08ec..268e2d6 100644 --- a/common/protocollistiterator.cpp +++ b/common/protocollistiterator.cpp @@ -1,5 +1,6 @@ #include "protocollistiterator.h" #include "protocollist.h" +#include "abstractprotocol.h" ProtocolListIterator::ProtocolListIterator(ProtocolList &list) { @@ -31,8 +32,24 @@ bool ProtocolListIterator::hasPrevious() const return _iter->hasPrevious(); } -void ProtocolListIterator::insert(const AbstractProtocol* value) +void ProtocolListIterator::insert(AbstractProtocol* value) { + if (_iter->hasPrevious()) + { + value->prev = _iter->peekPrevious(); + value->prev->next = value; + } + else + value->prev = NULL; + + if (_iter->hasNext()) + { + value->next = _iter->peekNext(); + value->next->prev = value; + } + else + value->next = NULL; + _iter->insert((AbstractProtocol*)((uint)value)); } @@ -58,11 +75,21 @@ AbstractProtocol* ProtocolListIterator::previous() void ProtocolListIterator::remove() { + if (_iter->value()->prev) + _iter->value()->prev->next = _iter->value()->next; + if (_iter->value()->next) + _iter->value()->next->prev = _iter->value()->prev; _iter->remove(); } -void ProtocolListIterator::setValue(const AbstractProtocol* value) const +void ProtocolListIterator::setValue(AbstractProtocol* value) const { + if (_iter->value()->prev) + _iter->value()->prev->next = value; + if (_iter->value()->next) + _iter->value()->next->prev = value; + value->prev = _iter->value()->prev; + value->next = _iter->value()->next; _iter->setValue((AbstractProtocol*)((uint)value)); } diff --git a/common/protocollistiterator.h b/common/protocollistiterator.h index c2dffd3..8ad4168 100644 --- a/common/protocollistiterator.h +++ b/common/protocollistiterator.h @@ -15,13 +15,13 @@ public: bool findPrevious(const AbstractProtocol* value); bool hasNext() const; bool hasPrevious() const; - void insert(const AbstractProtocol* value); + void insert(AbstractProtocol* value); AbstractProtocol* next(); AbstractProtocol* peekNext() const; AbstractProtocol* peekPrevious() const; AbstractProtocol* previous(); void remove(); - void setValue(const AbstractProtocol* value) const; + void setValue(AbstractProtocol* value) const; void toBack(); void toFront(); const AbstractProtocol* value() const; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index a353796..9010354 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -11,7 +11,10 @@ #include "dot3.h" #include "llc.h" #include "snap.h" +#include "dot2llc.h" +#include "dot2snap.h" #include "vlan.h" +#include "vlanstack.h" #include "ip4.h" #include "tcp.h" #include "udp.h" @@ -20,16 +23,32 @@ ProtocolManager OstProtocolManager; ProtocolManager::ProtocolManager() { - registerProtocol(51, QString("mac"), (void*) MacProtocol::createInstance); - registerProtocol(52, QString("payload"), (void*) PayloadProtocol::createInstance); - registerProtocol(121, QString("eth2"), (void*) Eth2Protocol::createInstance); - registerProtocol(122, QString("dot3"), (void*) Dot3Protocol::createInstance); - registerProtocol(123, QString("llc"), (void*) LlcProtocol::createInstance); - registerProtocol(124, QString("snap"), (void*) SnapProtocol::createInstance); - registerProtocol(126, QString("vlan"), (void*) VlanProtocol::createInstance); - registerProtocol(130, QString("ip4"), (void*) Ip4Protocol::createInstance); - registerProtocol(140, QString("tcp"), (void*) TcpProtocol::createInstance); - registerProtocol(141, QString("udp"), (void*) UdpProtocol::createInstance); + registerProtocol(OstProto::Protocol::kMacFieldNumber, + QString("mac"), (void*) MacProtocol::createInstance); + registerProtocol(OstProto::Protocol::kPayloadFieldNumber, + QString("payload"), (void*) PayloadProtocol::createInstance); + registerProtocol(OstProto::Protocol::kEth2FieldNumber, + QString("eth2"), (void*) Eth2Protocol::createInstance); + registerProtocol(OstProto::Protocol::kDot3FieldNumber, + QString("dot3"), (void*) Dot3Protocol::createInstance); + registerProtocol(OstProto::Protocol::kLlcFieldNumber, + QString("llc"), (void*) LlcProtocol::createInstance); + registerProtocol(OstProto::Protocol::kSnapFieldNumber, + QString("snap"), (void*) SnapProtocol::createInstance); + registerProtocol(OstProto::Protocol::kDot2LlcFieldNumber, + QString("dot2Llc"), (void*) Dot2LlcProtocol::createInstance); + registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber, + QString("dot2Snap"), (void*) Dot2SnapProtocol::createInstance); + registerProtocol(OstProto::Protocol::kVlanFieldNumber, + QString("vlan"), (void*) VlanProtocol::createInstance); + registerProtocol(OstProto::Protocol::kVlanStackFieldNumber, + QString("vlanstack"), (void*) VlanStackProtocol::createInstance); + registerProtocol(OstProto::Protocol::kIp4FieldNumber, + QString("ip4"), (void*) Ip4Protocol::createInstance); + registerProtocol(OstProto::Protocol::kTcpFieldNumber, + QString("tcp"), (void*) TcpProtocol::createInstance); + registerProtocol(OstProto::Protocol::kUdpFieldNumber, + QString("udp"), (void*) UdpProtocol::createInstance); } void ProtocolManager::registerProtocol(int protoNumber, QString protoName, @@ -42,25 +61,25 @@ void ProtocolManager::registerProtocol(int protoNumber, QString protoName, } AbstractProtocol* ProtocolManager::createProtocol(int protoNumber, - StreamBase *stream) + StreamBase *stream, AbstractProtocol *parent) { - AbstractProtocol* (*pc)(StreamBase*); + AbstractProtocol* (*pc)(StreamBase*, AbstractProtocol*); AbstractProtocol* p; - pc = (AbstractProtocol* (*)(StreamBase*)) + pc = (AbstractProtocol* (*)(StreamBase*, AbstractProtocol*)) factory.value(protoNumber); Q_ASSERT(pc != NULL); - p = (*pc)(stream); + p = (*pc)(stream, parent); return p; } AbstractProtocol* ProtocolManager::createProtocol(QString protoName, - StreamBase *stream) + StreamBase *stream, AbstractProtocol *parent) { - return createProtocol(nameToNumberMap.value(protoName), stream); + return createProtocol(nameToNumberMap.value(protoName), stream, parent); } QStringList ProtocolManager::protocolDatabase() diff --git a/common/protocolmanager.h b/common/protocolmanager.h index ef0a605..985253b 100644 --- a/common/protocolmanager.h +++ b/common/protocolmanager.h @@ -19,8 +19,10 @@ public: void registerProtocol(int protoNumber, QString protoName, void *protoCreator); - AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream); - AbstractProtocol* createProtocol(QString protoName, StreamBase *stream); + AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream, + AbstractProtocol *parent = 0); + AbstractProtocol* createProtocol(QString protoName, StreamBase *stream, + AbstractProtocol *parent = 0); QStringList protocolDatabase(); }; diff --git a/common/sample.cpp b/common/sample.cpp index 9dbb81e..3076e6c 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -9,8 +9,8 @@ SampleConfigForm::SampleConfigForm(QWidget *parent) setupUi(this); } -SampleProtocol::SampleProtocol(StreamBase *stream); - : AbstractProtocol(stream) +SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent); + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ SampleProtocol::~SampleProtocol() delete configForm; } -AbstractProtocol* SampleProtocol::createInstance(StreamBase *stream) +AbstractProtocol* SampleProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new SampleProtocol(frameProtoList, streamCore); + return new SampleProtocol(stream, parent); } quint32 SampleProtocol::protocolNumber() const diff --git a/common/sample.h b/common/sample.h index e02b6bc..6075262 100644 --- a/common/sample.h +++ b/common/sample.h @@ -26,10 +26,11 @@ private: }; public: - SampleProtocol(StreamBase *stream); + SampleProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~SampleProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/snap.cpp b/common/snap.cpp index 26f5c6c..c651bb1 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -9,8 +9,8 @@ SnapConfigForm::SnapConfigForm(QWidget *parent) setupUi(this); } -SnapProtocol::SnapProtocol(StreamBase *stream) - : AbstractProtocol(stream) +SnapProtocol::SnapProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ SnapProtocol::~SnapProtocol() delete configForm; } -AbstractProtocol* SnapProtocol::createInstance(StreamBase *stream) +AbstractProtocol* SnapProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new SnapProtocol(stream); + return new SnapProtocol(stream, parent); } quint32 SnapProtocol::protocolNumber() const diff --git a/common/snap.h b/common/snap.h index 79e2780..a2531f6 100644 --- a/common/snap.h +++ b/common/snap.h @@ -27,10 +27,11 @@ private: }; public: - SnapProtocol(StreamBase *stream); + SnapProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~SnapProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/streambase.cpp b/common/streambase.cpp index b98c6c6..ecfc07c 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -12,22 +12,23 @@ StreamBase::StreamBase() : mControl(new OstProto::StreamControl) { AbstractProtocol *proto; + ProtocolListIterator *iter; mStreamId->set_id(0xFFFFFFFF); currentFrameProtocols = new ProtocolList; + iter = createProtocolListIterator(); // By default newly created streams have the mac and payload protocols proto = OstProtocolManager.createProtocol("mac", this); - currentFrameProtocols->append(proto); + iter->insert(proto); qDebug("stream: mac = %p", proto); proto = OstProtocolManager.createProtocol("payload", this); - currentFrameProtocols->append(proto); + iter->insert(proto); qDebug("stream: payload = %p", proto); { - ProtocolListIterator *iter = createProtocolListIterator(); iter->toFront(); while (iter->hasNext()) { @@ -40,8 +41,9 @@ StreamBase::StreamBase() : qDebug("{[%d]}", iter->next()->protocolNumber()); // qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber()); } - delete iter; } + + delete iter; } StreamBase::~StreamBase() @@ -53,20 +55,24 @@ StreamBase::~StreamBase() void StreamBase::protoDataCopyFrom(const OstProto::Stream &stream) { - AbstractProtocol *proto; + AbstractProtocol *proto; + ProtocolListIterator *iter; mStreamId->CopyFrom(stream.stream_id()); mCore->CopyFrom(stream.core()); mControl->CopyFrom(stream.control()); currentFrameProtocols->destroy(); + iter = createProtocolListIterator(); for (int i=0; i < stream.protocol_size(); i++) { proto = OstProtocolManager.createProtocol( stream.protocol(i).protocol_id().id(), this); proto->protoDataCopyFrom(stream.protocol(i)); - currentFrameProtocols->append(proto); + iter->insert(proto); } + + delete iter; } void StreamBase::protoDataCopyInto(OstProto::Stream &stream) const diff --git a/common/tcp.cpp b/common/tcp.cpp index 279efc1..dc461b6 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -9,8 +9,8 @@ TcpConfigForm::TcpConfigForm(QWidget *parent) setupUi(this); } -TcpProtocol::TcpProtocol(StreamBase *stream) - : AbstractProtocol(stream) +TcpProtocol::TcpProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ TcpProtocol::~TcpProtocol() delete configForm; } -AbstractProtocol* TcpProtocol::createInstance(StreamBase *stream) +AbstractProtocol* TcpProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new TcpProtocol(stream); + return new TcpProtocol(stream, parent); } quint32 TcpProtocol::protocolNumber() const diff --git a/common/tcp.h b/common/tcp.h index 36edba8..cfd43a6 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -45,10 +45,11 @@ private: }; public: - TcpProtocol(StreamBase *stream); + TcpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~TcpProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/udp.cpp b/common/udp.cpp index 7564d2a..c722b54 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -9,8 +9,8 @@ UdpConfigForm::UdpConfigForm(QWidget *parent) setupUi(this); } -UdpProtocol::UdpProtocol(StreamBase *stream) - : AbstractProtocol(stream) +UdpProtocol::UdpProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ UdpProtocol::~UdpProtocol() delete configForm; } -AbstractProtocol* UdpProtocol::createInstance(StreamBase *stream) +AbstractProtocol* UdpProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new UdpProtocol(stream); + return new UdpProtocol(stream, parent); } quint32 UdpProtocol::protocolNumber() const diff --git a/common/udp.h b/common/udp.h index a2abbed..278809a 100644 --- a/common/udp.h +++ b/common/udp.h @@ -32,10 +32,11 @@ private: }; public: - UdpProtocol(StreamBase *stream); + UdpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~UdpProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/vlan.cpp b/common/vlan.cpp index 2f60601..49b9a27 100644 --- a/common/vlan.cpp +++ b/common/vlan.cpp @@ -8,8 +8,8 @@ VlanConfigForm::VlanConfigForm(QWidget *parent) setupUi(this); } -VlanProtocol::VlanProtocol(StreamBase *stream) - : AbstractProtocol(stream) +VlanProtocol::VlanProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -19,9 +19,10 @@ VlanProtocol::~VlanProtocol() delete configForm; } -AbstractProtocol* VlanProtocol::createInstance(StreamBase *stream) +AbstractProtocol* VlanProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { - return new VlanProtocol(stream); + return new VlanProtocol(stream, parent); } quint32 VlanProtocol::protocolNumber() const diff --git a/common/vlan.h b/common/vlan.h index fedf315..c5655da 100644 --- a/common/vlan.h +++ b/common/vlan.h @@ -32,10 +32,11 @@ private: }; public: - VlanProtocol(StreamBase *stream); + VlanProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~VlanProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/vlanstack.h b/common/vlanstack.h new file mode 100644 index 0000000..5202729 --- /dev/null +++ b/common/vlanstack.h @@ -0,0 +1,10 @@ +#ifndef _VLAN_STACK_H +#define _VLAN_STACK_H + +#include "comboprotocol.h" +#include "vlan.h" + +typedef ComboProtocol VlanStackProtocol; + +#endif diff --git a/common/vlanstack.proto b/common/vlanstack.proto new file mode 100644 index 0000000..4c3d06d --- /dev/null +++ b/common/vlanstack.proto @@ -0,0 +1,12 @@ +import "protocol.proto"; + +package OstProto; + +// Stacked VLAN (2 tags) +message VlanStack { + // Empty since this is a 'combo' protocol +} + +extend Protocol { + optional VlanStack vlanStack = 125; +} diff --git a/server/myservice.cpp b/server/myservice.cpp index 6d9d2ae..ff01e17 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -2,6 +2,7 @@ #include #include #include "qdebug.h" +#include #include "myservice.h" #include "../common/protocollist.h" @@ -86,7 +87,7 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) // ------------------ PortInfo -------------------- // PortInfo::PortInfo(uint id, pcap_if_t *dev) - : monitorRx(this), monitorTx(this), transmitter(this) + : monitorRx(this), monitorTx(this), transmitter(this), capturer(this) { char errbuf[PCAP_ERRBUF_SIZE]; @@ -333,6 +334,21 @@ void PortInfo::stopTransmit() transmitter.stop(); } +void PortInfo::startCapture() +{ + capturer.start(); +} + +void PortInfo::stopCapture() +{ + capturer.stop(); +} + +void PortInfo::viewCapture() +{ + capturer.view(); +} + void PortInfo::resetStats() { memcpy((void*) &epochStats, (void*) &stats, sizeof(stats)); @@ -714,6 +730,59 @@ void PortInfo::PortTransmitter::stop() m_stop = 1; } +/*--------------- PortCapture ---------------*/ + +PortInfo::PortCapture::PortCapture(PortInfo *port) +{ + this->port = port; + capHandle = NULL; + dumpHandle = NULL; +} + +void PortInfo::PortCapture::run() +{ + if (capHandle == NULL) + { + char errbuf[PCAP_ERRBUF_SIZE]; + + capHandle = pcap_open_live(port->dev->name, 0, + PCAP_OPENFLAG_PROMISCUOUS, 1000 /*ms*/, errbuf); + if (capHandle == NULL) + { + qDebug("Error opening port %s: %s\n", + port->dev->name, pcap_geterr(capHandle)); + } + } + if (!capFile.isOpen()) + { + if (!capFile.open()) + qFatal("Unable to open temp cap file"); + qDebug("cap file = %s", capFile.fileName().toAscii().constData()); + } + dumpHandle = pcap_dump_open(capHandle, + capFile.fileName().toAscii().constData()); + + pcap_loop(capHandle, -1, pcap_dump, (uchar*) dumpHandle); +} + +void PortInfo::PortCapture::stop() +{ + pcap_breakloop(capHandle); + if (dumpHandle) + { + pcap_dump_flush(dumpHandle); + pcap_dump_close(dumpHandle); + dumpHandle = NULL; + } +} + +void PortInfo::PortCapture::view() +{ + // FIXME: hack - when correcting this remove the include also + QProcess::execute("C:/Program Files/Wireshark/wireshark.exe", + QStringList() << capFile.fileName()); +} + /*--------------- MyService ---------------*/ @@ -1067,7 +1136,18 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); - controller->SetFailed("Not Implemented"); + + for (int i=0; i < request->port_id_size(); i++) + { + uint portIdx; + + portIdx = request->port_id(i).id(); + if (portIdx >= numPorts) + continue; // TODO(LOW): partial RPC? + + portInfo[portIdx]->startCapture(); + } + done->Run(); } @@ -1077,7 +1157,17 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); - controller->SetFailed("Not Implemented"); + for (int i=0; i < request->port_id_size(); i++) + { + uint portIdx; + + portIdx = request->port_id(i).id(); + if (portIdx >= numPorts) + continue; // TODO(LOW): partial RPC? + + portInfo[portIdx]->stopCapture(); + } + done->Run(); } @@ -1087,6 +1177,19 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); + + // FIXME: BAD BAD VERY BAD !!!!!! + for (int i=0; i < request->port_id_size(); i++) + { + uint portIdx; + + portIdx = request->port_id(i).id(); + if (portIdx >= numPorts) + continue; // TODO(LOW): partial RPC? + + portInfo[portIdx]->viewCapture(); + } + controller->SetFailed("Not Implemented"); done->Run(); } diff --git a/server/myservice.h b/server/myservice.h index 7a4f331..270bfba 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "../rpc/pbhelper.h" #include "pcapextra.h" @@ -92,6 +93,22 @@ class PortInfo void run(); void stop(); }; + + class PortCapture: public QThread + { + friend class PortInfo; + + PortInfo *port; + pcap_t *capHandle; + pcap_dumper_t *dumpHandle; + QTemporaryFile capFile; + + public: + PortCapture(PortInfo *port); + void run(); + void stop(); + void view(); + }; OstProto::Port d; @@ -136,6 +153,7 @@ class PortInfo PortMonitorRx monitorRx; PortMonitorTx monitorTx; PortTransmitter transmitter; + PortCapture capturer; struct PortStats epochStats; struct PortStats stats; @@ -153,6 +171,9 @@ public: void update(); void startTransmit(); void stopTransmit(); + void startCapture(); + void stopCapture(); + void viewCapture(); void resetStats(); }; From 84c7fe1e060964cdbd5cecc9675f723c3ed1e5c5 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Tue, 3 Nov 2009 14:02:09 +0000 Subject: [PATCH 27/98] Features - Added support for retrieving the packet capture buffer from server to client (does not work consistently however - needs investigation) - getCaptureBuffer() Rpc signature changed - RPC: Added support in Rpc Channel (client) to queue calls - RPC: Added support for transferring arbitrary binary data from server to client (used to get packet capture files) - Rpc header changed - length is now 4 bytes instead of 2; there is no rsvd field any longer Fixes - RPC: Fix for the case when a msg is not received all at once over the socket - StreamConfigDialog: fixed display issue in packet view for combo protocols containing meta fields - Fixed issue with Stacked Vlan not retaining data for both CVlan and SVlan - Fixed incorrect payload size issue with increment/decrement frame length modes Refactoring, Cleanup etc. - RPC: Minor code and TODOs cleanup - Server: Minor code and TODOs cleanup - Server: Removed unused file(s): rxtx.cpp, rxtx.h - Server: Replaced direct use of ProtocolList with the ProtocolListIterator - Common: Minor code and TODOs cleanup - StreamBase::frameLen() now returns the length based on the mode/min/max and the passed in streamIndex - AbstractProtocol interface changed for methods - protocolFrameSize(), protocolFrameOffset(), protocolFramePayloadSize() : all of them now take streamIndex as an optional param with 0 as the default value - Protocols implementing the above methods changed accordingly --- client/packetmodel.cpp | 26 +- client/portgroup.cpp | 129 +++++---- client/portgroup.h | 7 +- common/abstractprotocol.cpp | 33 ++- common/abstractprotocol.h | 6 +- common/dot3.cpp | 7 +- common/ip4.cpp | 7 +- common/ip4.proto | 3 +- common/llc.cpp | 1 - common/mac.cpp | 1 - common/ostproto.pro | 3 + common/payload.cpp | 17 +- common/payload.h | 2 +- common/protocol.proto | 14 +- common/protocolmanager.cpp | 12 +- common/sample.cpp | 22 +- common/snap.cpp | 1 - common/streambase.cpp | 35 ++- common/streambase.h | 6 +- common/svlan.cpp | 49 ++++ common/svlan.h | 23 ++ common/svlan.proto | 8 + common/tcp.cpp | 1 - common/udp.cpp | 8 +- common/vlan.cpp | 1 - common/vlan.h | 4 +- common/vlanstack.h | 3 +- common/vlanstack.proto | 2 +- rpc/pbhelper.h | 3 + rpc/pbrpcchannel.cpp | 216 ++++++++++----- rpc/pbrpcchannel.h | 15 +- rpc/pbrpccommon.h | 17 +- rpc/pbrpccontroller.h | 13 +- rpc/rpcserver.cpp | 110 +++++--- rpc/rpcserver.h | 2 +- server/drone.cpp | 79 +----- server/drone.h | 23 +- server/drone_main.cpp | 4 - server/myservice.cpp | 185 +++++++------ server/myservice.h | 9 +- server/pcapextra.cpp | 4 +- server/rxtx.cpp | 514 ------------------------------------ server/rxtx.h | 84 ------ 43 files changed, 664 insertions(+), 1045 deletions(-) create mode 100644 common/svlan.cpp create mode 100644 common/svlan.h create mode 100644 common/svlan.proto delete mode 100644 server/rxtx.cpp delete mode 100644 server/rxtx.h diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 908de63..6b7b834 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -132,13 +132,29 @@ _exit: QVariant PacketModel::data(const QModelIndex &index, int role) const { - IndexId id; + IndexId id; + int fieldIdx = 0; if (!index.isValid()) return QVariant(); id.w = index.internalId(); + if (id.ws.type == ITYP_FIELD) + { + const AbstractProtocol *p = mSelectedProtocols.at(id.ws.protocol); + int n = index.row() + 1; + + while (n) + { + if (!(p->fieldFlags(fieldIdx).testFlag( + AbstractProtocol::FieldIsMeta))) + n--; + fieldIdx++; + } + fieldIdx--; + } + // FIXME(HI): Relook at this completely if (role == Qt::UserRole) { @@ -151,7 +167,7 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const case ITYP_FIELD: return mSelectedProtocols.at(id.ws.protocol)->fieldData( - index.row(), AbstractProtocol::FieldFrameValue); + fieldIdx, AbstractProtocol::FieldFrameValue); default: qWarning("%s: Unhandled ItemType", __FUNCTION__); @@ -170,7 +186,7 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const case ITYP_FIELD: return mSelectedProtocols.at(id.ws.protocol)->fieldData( - index.row(), AbstractProtocol::FieldBitSize); + fieldIdx, AbstractProtocol::FieldBitSize); default: qWarning("%s: Unhandled ItemType", __FUNCTION__); @@ -189,9 +205,9 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const .arg(mSelectedProtocols.at(id.ws.protocol)->name()); case ITYP_FIELD: - return mSelectedProtocols.at(id.ws.protocol)->fieldData(index.row(), + return mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, AbstractProtocol::FieldName).toString() + QString(" : ") + - mSelectedProtocols.at(id.ws.protocol)->fieldData(index.row(), + mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, AbstractProtocol::FieldTextValue).toString(); default: diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 4614528..76888f3 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -1,6 +1,8 @@ +#include +#include + #include "portgroup.h" -#include quint32 PortGroup::mPortGroupAllocId = 0; @@ -10,7 +12,15 @@ PortGroup::PortGroup(QHostAddress ip, quint16 port) mPortGroupId = PortGroup::mPortGroupAllocId++; rpcChannel = new PbRpcChannel(ip, port); - rpcController = new PbRpcController(); + + /*! + \todo (HIGH) RPC Controller should be allocated and deleted for each RPC invocation + as implemented currently, if a RPC is invoked before the previous completes, + rpc controller is overwritten due to the Reset() call - maybe we need to pass the + pointer to the controller to the callback function also? + */ + rpcController = new PbRpcController; + rpcControllerStats = new PbRpcController; serviceStub = new OstProto::OstService::Stub(rpcChannel, OstProto::OstService::STUB_OWNS_CHANNEL); @@ -458,21 +468,21 @@ void PortGroup::stopTx(QList *portList) qDebug("In %s", __FUNCTION__); if (state() != QAbstractSocket::ConnectedState) - return; + goto _exit; + + if ((portList == NULL) || (portList->size() == 0)) + goto _exit; ack = new OstProto::Ack; - if (portList == NULL) - goto _exit; - else + + for (int i = 0; i < portList->size(); i++) { - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); } + rpcController->Reset(); serviceStub->stopTx(rpcController, &portIdList, ack, NewCallback(this, &PortGroup::processStopTxAck, ack)); _exit: @@ -489,19 +499,19 @@ void PortGroup::startCapture(QList *portList) if (state() != QAbstractSocket::ConnectedState) return; - ack = new OstProto::Ack; - if (portList == NULL) + if ((portList == NULL) || (portList->size() == 0)) goto _exit; - else + + ack = new OstProto::Ack; + + for (int i = 0; i < portList->size(); i++) { - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); } + rpcController->Reset(); serviceStub->startCapture(rpcController, &portIdList, ack, NewCallback(this, &PortGroup::processStartCaptureAck, ack)); _exit: @@ -518,19 +528,18 @@ void PortGroup::stopCapture(QList *portList) if (state() != QAbstractSocket::ConnectedState) return; - ack = new OstProto::Ack; - if (portList == NULL) + if ((portList == NULL) || (portList->size() == 0)) goto _exit; - else + + ack = new OstProto::Ack; + for (int i = 0; i < portList->size(); i++) { - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); } + rpcController->Reset(); serviceStub->stopCapture(rpcController, &portIdList, ack, NewCallback(this, &PortGroup::processStopCaptureAck, ack)); _exit: @@ -539,29 +548,38 @@ _exit: void PortGroup::viewCapture(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::CaptureBufferList *bufList; + static QTemporaryFile *capFile = NULL; qDebug("In %s", __FUNCTION__); if (state() != QAbstractSocket::ConnectedState) - return; - - bufList = new OstProto::CaptureBufferList; - if (portList == NULL) goto _exit; - else - { - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } - } - serviceStub->getCaptureBuffer(rpcController, &portIdList, bufList, - NewCallback(this, &PortGroup::processViewCaptureAck, bufList)); + if ((portList == NULL) || (portList->size() != 1)) + goto _exit; + + if (capFile) + delete capFile; + + /*! \todo (MED) unable to reuse the same file 'coz capFile->resize(0) is + not working - it fails everytime */ + capFile = new QTemporaryFile(); + capFile->open(); + qDebug("Temp CapFile = %s", capFile->fileName().toAscii().constData()); + + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId portId; + OstProto::CaptureBuffer *buf; + + portId.set_id(portList->at(i)); + + buf = new OstProto::CaptureBuffer; + rpcController->Reset(); + rpcController->setBinaryBlob(capFile); + serviceStub->getCaptureBuffer(rpcController, &portId, buf, + NewCallback(this, &PortGroup::processViewCaptureAck, buf, (QFile*) capFile)); + } _exit: return; } @@ -594,11 +612,18 @@ void PortGroup::processStopCaptureAck(OstProto::Ack *ack) delete ack; } -void PortGroup::processViewCaptureAck(OstProto::CaptureBufferList *bufList) +void PortGroup::processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile) { qDebug("In %s", __FUNCTION__); - delete bufList; + capFile->flush(); + capFile->close(); + + if (!QProcess::startDetached("C:/Program Files/Wireshark/wireshark.exe", + QStringList() << capFile->fileName())) + qDebug("Failed starting Wireshark"); + + delete buf; } void PortGroup::getPortStats() @@ -611,7 +636,8 @@ void PortGroup::getPortStats() return; portStatsList = new OstProto::PortStatsList; - serviceStub->getStats(rpcController, &portIdList, portStatsList, + rpcControllerStats->Reset(); + serviceStub->getStats(rpcControllerStats, &portIdList, portStatsList, NewCallback(this, &PortGroup::processPortStatsList, portStatsList)); } @@ -619,7 +645,7 @@ void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList) { //qDebug("In %s", __FUNCTION__); - if (rpcController->Failed()) + if (rpcControllerStats->Failed()) { qDebug("%s: rpc failed", __FUNCTION__); goto _error_exit; @@ -664,6 +690,7 @@ void PortGroup::clearPortStats(QList *portList) } } + rpcController->Reset(); serviceStub->clearStats(rpcController, &portIdList, ack, NewCallback(this, &PortGroup::processClearStatsAck, ack)); } diff --git a/client/portgroup.h b/client/portgroup.h index c297674..c74640a 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -17,6 +17,8 @@ LOW #define DEFAULT_SERVER_PORT 7878 +class QFile; + class PortGroup : public QObject { Q_OBJECT @@ -30,7 +32,8 @@ private: quint16 mServerPort; #endif PbRpcChannel *rpcChannel; - ::google::protobuf::RpcController *rpcController; + PbRpcController *rpcController; + PbRpcController *rpcControllerStats; ::OstProto::OstService::Stub *serviceStub; ::OstProto::PortIdList portIdList; @@ -80,7 +83,7 @@ public: void stopCapture(QList *portList = NULL); void processStopCaptureAck(OstProto::Ack *ack); void viewCapture(QList *portList = NULL); - void processViewCaptureAck(OstProto::CaptureBufferList *bufList); + void processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile); void getPortStats(); void processPortStatsList(OstProto::PortStatsList *portStatsList); diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 24355f2..10678fb 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -7,7 +7,7 @@ /*! \class AbstractProtocol - // FIXME - update this text + \todo (MED) update AbstractProtocol documentation Bare Minimum set of methods that a subclass needs to reimplement - protoDataCopyInto() [pure virtual] - protoDataCopyFrom() [pure virtual] @@ -58,7 +58,7 @@ quint32 AbstractProtocol::protocolNumber() const /* \fn virtual void protoDataCopyFrom(const OstProto::OstProto::StreamCore &stream) = 0; - FIXME */ + */ /*! Returns the full name of the protocol \n The default implementation returns a null string */ @@ -137,7 +137,18 @@ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int index) const The FieldTextValue attribute may include additional information about the field's value e.g. a checksum field may include "(correct)" or "(incorrect)" alongwith the actual checksum value. \n - The default implementation returns FIXME + + The default implementation returns a empty string for FieldName and + FieldTextValue; empty byte array of size 0 for FieldFrameValue; 0 for + FieldValue; subclasses are expected to return meaning values for all + these attributes. The only exception is the 'FieldBitSize' attribute - + the default implementation takes the (byte) size of FieldFrameValue, + multiplies it with 8 and returns the result - this can be used by + subclasses for fields which are an integral multiple of bytes; for + fields whose size are a non-integral multiple of bytes or smaller than + a byte, subclasses should return the correct value. Also for fields + which represent checksums, subclasses should return a value for + FieldBitSize - even if it is an integral multiple of bytes \note If a subclass uses any of the below functions to derive FieldFrameValue, the subclass should handle and return a value for @@ -202,7 +213,7 @@ quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const return id; } -int AbstractProtocol::protocolFrameSize() const +int AbstractProtocol::protocolFrameSize(int streamIndex) const { if (protoSize < 0) { @@ -211,7 +222,7 @@ int AbstractProtocol::protocolFrameSize() const for (int i = 0; i < fieldCount(); i++) { if (!fieldFlags(i).testFlag(FieldIsMeta)) - bitsize += fieldData(i, FieldBitSize).toUInt(); + bitsize += fieldData(i, FieldBitSize, streamIndex).toUInt(); } protoSize = (bitsize+7)/8; } @@ -220,34 +231,34 @@ int AbstractProtocol::protocolFrameSize() const return protoSize; } -int AbstractProtocol::protocolFrameOffset() const +int AbstractProtocol::protocolFrameOffset(int streamIndex) const { int size = 0; AbstractProtocol *p = prev; while (p) { - size += p->protocolFrameSize(); + size += p->protocolFrameSize(streamIndex); p = p->prev; } if (parent) - size += parent->protocolFrameOffset(); + size += parent->protocolFrameOffset(streamIndex); qDebug("%s: ofs = %d", __FUNCTION__, size); return size; } -int AbstractProtocol::protocolFramePayloadSize() const +int AbstractProtocol::protocolFramePayloadSize(int streamIndex) const { int size = 0; AbstractProtocol *p = next; while (p) { - size += p->protocolFrameSize(); + size += p->protocolFrameSize(streamIndex); p = p->next; } if (parent) - size += parent->protocolFramePayloadSize(); + size += parent->protocolFramePayloadSize(streamIndex); qDebug("%s: payloadSize = %d", __FUNCTION__, size); return size; diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index 13db703..3e1dc12 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -97,9 +97,9 @@ public: QByteArray protocolFrameValue(int streamIndex = 0, bool forCksum = false) const; - virtual int protocolFrameSize() const; - int protocolFrameOffset() const; - int protocolFramePayloadSize() const; + virtual int protocolFrameSize(int streamIndex = 0) const; + int protocolFrameOffset(int streamIndex = 0) const; + int protocolFramePayloadSize(int streamIndex = 0) const; virtual quint32 protocolFrameCksum(int streamIndex = 0, CksumType cksumType = CksumIp) const; diff --git a/common/dot3.cpp b/common/dot3.cpp index cae0012..0a88d50 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -77,7 +77,7 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, quint16 len; //len = mpStream->frameLen() - SZ_FCS; - len = protocolFramePayloadSize(); + len = protocolFramePayloadSize(streamIndex); return len; } case FieldTextValue: @@ -85,7 +85,7 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, quint16 len; //len = mpStream->frameLen() - SZ_FCS; - len = protocolFramePayloadSize(); + len = protocolFramePayloadSize(streamIndex); return QString("%1").arg(len); } case FieldFrameValue: @@ -94,7 +94,7 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, QByteArray fv; //len = mpStream->frameLen() - SZ_FCS; - len = protocolFramePayloadSize(); + len = protocolFramePayloadSize(streamIndex); fv.resize(2); qToBigEndian(len, (uchar*) fv.data()); return fv; @@ -116,7 +116,6 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, bool Dot3Protocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { - // FIXME return false; } diff --git a/common/ip4.cpp b/common/ip4.cpp index 4fd594b..c929872 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -236,7 +236,7 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, { int totlen; totlen = data.is_override_totlen() ? data.totlen() : - (protocolFramePayloadSize() + 20); + (protocolFramePayloadSize(streamIndex) + 20); return totlen; } case FieldFrameValue: @@ -244,7 +244,7 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, QByteArray fv; int totlen; totlen = data.is_override_totlen() ? data.totlen() : - (protocolFramePayloadSize() + 20); + (protocolFramePayloadSize(streamIndex) + 20); fv.resize(2); qToBigEndian((quint16) totlen, (uchar*) fv.data()); return fv; @@ -253,7 +253,7 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, { int totlen; totlen = data.is_override_totlen() ? data.totlen() : - (protocolFramePayloadSize() + 20); + (protocolFramePayloadSize(streamIndex) + 20); return QString("%1").arg(totlen); } case FieldBitSize: @@ -320,7 +320,6 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, case FieldFrameValue: { QByteArray fv; - // FIXME need to shift for 13 bits fv.resize(2); qToBigEndian((quint16) (data.frag_ofs()), (uchar*) fv.data()); diff --git a/common/ip4.proto b/common/ip4.proto index c17ec75..84fcbf4 100644 --- a/common/ip4.proto +++ b/common/ip4.proto @@ -20,7 +20,6 @@ message Ip4 { optional uint32 tos = 6; optional uint32 totlen = 7; optional uint32 id = 8 [default = 1234]; - // TODO: rename flags to frag_flags optional uint32 flags = 9; optional uint32 frag_ofs = 10; optional uint32 ttl = 11 [default = 127]; @@ -39,7 +38,7 @@ message Ip4 { optional uint32 dst_ip_count = 20 [default = 16]; optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFF00]; - // TODO: Options + //! \todo (LOW) IPv4 Options } extend Protocol { diff --git a/common/llc.cpp b/common/llc.cpp index b352cab..e949e08 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -128,7 +128,6 @@ QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib, bool LlcProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { - // FIXME return false; } diff --git a/common/mac.cpp b/common/mac.cpp index ae80905..8e468a3 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -236,7 +236,6 @@ QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, bool MacProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { - // FIXME return false; } diff --git a/common/ostproto.pro b/common/ostproto.pro index 9945212..8ae7f99 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -25,6 +25,7 @@ PROTOS += \ dot2llc.proto \ dot2snap.proto \ vlan.proto \ + svlan.proto \ vlanstack.proto \ ip4.proto \ tcp.proto \ @@ -45,6 +46,7 @@ HEADERS += \ dot2llc.h \ dot2snap.h \ vlan.h \ + svlan.h \ vlanstack.h \ ip4.h \ tcp.h \ @@ -62,6 +64,7 @@ SOURCES += \ llc.cpp \ snap.cpp \ vlan.cpp \ + svlan.cpp \ ip4.cpp \ tcp.cpp \ udp.cpp diff --git a/common/payload.cpp b/common/payload.cpp index a83817c..1125b73 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -75,9 +75,16 @@ QString PayloadProtocol::shortName() const return QString("DATA"); } -int PayloadProtocol::protocolFrameSize() const +int PayloadProtocol::protocolFrameSize(int streamIndex) const { - return (mpStream->frameLen() - protocolFrameOffset() - SZ_FCS); + int len; + + len = mpStream->frameLen(streamIndex) - protocolFrameOffset(streamIndex) + - SZ_FCS; + + qDebug("%s: this = %p, streamIndex = %d, len = %d", __FUNCTION__, this, + streamIndex, len); + return len; } int PayloadProtocol::fieldCount() const @@ -125,8 +132,7 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, QByteArray fv; int dataLen; - dataLen = mpStream->frameLen() - protocolFrameOffset(); - dataLen -= SZ_FCS; + dataLen = protocolFrameSize(streamIndex); // FIXME: Hack! Bad! Bad! Very Bad!!! if (dataLen <= 0) @@ -149,7 +155,7 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, fv[i] = 0xFF - (i % (0xFF + 1)); break; case OstProto::Payload::e_dp_random: - //! \todo cksum will be incorrect for random pattern + //! \todo (HIGH) cksum is incorrect for random pattern for (int i = 0; i < dataLen; i++) fv[i] = qrand() % (0xFF + 1); break; @@ -178,7 +184,6 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, bool PayloadProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { - // FIXME return false; } diff --git a/common/payload.h b/common/payload.h index cb93006..c2d5f4d 100644 --- a/common/payload.h +++ b/common/payload.h @@ -44,7 +44,7 @@ public: virtual QString name() const; virtual QString shortName() const; - virtual int protocolFrameSize() const; + virtual int protocolFrameSize(int streamIndex = 0) const; virtual int fieldCount() const; diff --git a/common/protocol.proto b/common/protocol.proto index 372ad54..1f3c0a5 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -1,7 +1,5 @@ // stream.proto -// FIXME: Re-evaluate Tag Values - package OstProto; message StreamId { @@ -56,9 +54,6 @@ message StreamControl { optional NextWhat next = 6 [default = e_nw_goto_next]; optional uint32 packets_per_sec = 7 [default = 1]; optional uint32 bursts_per_sec = 8 [default = 1]; - - // TODO: Gaps? - } message ProtocolId { @@ -81,11 +76,12 @@ message Protocol { kLlcFieldNumber = 123; kSnapFieldNumber = 124; - kVlanStackFieldNumber = 125; + kSvlanFieldNumber = 125; kVlanFieldNumber = 126; kDot2LlcFieldNumber = 127; kDot2SnapFieldNumber = 128; + kVlanStackFieldNumber = 129; kIp4FieldNumber = 130; kArpFieldNumber = 131; @@ -111,7 +107,7 @@ message Void { } message Ack { - // TODO + //! \todo (LOW) do we need any fields in 'Ack' } message PortId { @@ -146,7 +142,7 @@ message StreamConfigList { } message CaptureBuffer { - // TODO + //! \todo (HIGH) define CaptureBuffer } message CaptureBufferList { @@ -190,7 +186,7 @@ service OstService { rpc startCapture(PortIdList) returns (Ack); rpc stopCapture(PortIdList) returns (Ack); - rpc getCaptureBuffer(PortIdList) returns (CaptureBufferList); + rpc getCaptureBuffer(PortId) returns (CaptureBuffer); rpc getStats(PortIdList) returns (PortStatsList); rpc clearStats(PortIdList) returns (Ack); diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 9010354..56c1912 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -1,12 +1,9 @@ #include "protocolmanager.h" - -// FIXME(HI): remove -#include "protocol.pb.h" #include "abstractprotocol.h" +#include "protocol.pb.h" #include "mac.h" #include "payload.h" - #include "eth2.h" #include "dot3.h" #include "llc.h" @@ -23,6 +20,9 @@ ProtocolManager OstProtocolManager; ProtocolManager::ProtocolManager() { + /*! \todo (LOW) calls to registerProtocol() should be done by the protocols + themselves (once this is done remove the #includes for all the protocols) + */ registerProtocol(OstProto::Protocol::kMacFieldNumber, QString("mac"), (void*) MacProtocol::createInstance); registerProtocol(OstProto::Protocol::kPayloadFieldNumber, @@ -39,6 +39,8 @@ ProtocolManager::ProtocolManager() QString("dot2Llc"), (void*) Dot2LlcProtocol::createInstance); registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber, QString("dot2Snap"), (void*) Dot2SnapProtocol::createInstance); + registerProtocol(OstProto::Protocol::kSvlanFieldNumber, + QString("svlan"), (void*) VlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanFieldNumber, QString("vlan"), (void*) VlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanStackFieldNumber, @@ -54,7 +56,7 @@ ProtocolManager::ProtocolManager() void ProtocolManager::registerProtocol(int protoNumber, QString protoName, void *protoInstanceCreator) { - // TODO: validate incoming params for duplicates with existing + //! \todo (MED) validate incoming params for duplicates with existing nameToNumberMap.insert(protoName, protoNumber); numberToNameMap.insert(protoNumber, protoName); factory.insert(protoNumber, protoInstanceCreator); diff --git a/common/sample.cpp b/common/sample.cpp index 3076e6c..63aaa7e 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -3,6 +3,10 @@ #include "sample.h" +/*! \todo (MED) Complete the "sample" protocol and make it compilable so that + it can be used as an example for new protocols + */ + SampleConfigForm::SampleConfigForm(QWidget *parent) : QWidget(parent) { @@ -90,18 +94,18 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, { switch (index) { - case sample_FIXME: + case sample_one: { switch(attrib) { case FieldName: - return QString("FIXME"); + return QString("ONE"); case FieldValue: - return data.FIXME(); + return data.one(); case FieldTextValue: - return QString("%1").arg(data.FIXME()); + return QString("%1").arg(data.one()); case FieldFrameValue: - return QByteArray(1, (char)(data.FIXME() & 0xF0)); + return QByteArray(1, (char)(data.one() & 0xF0)); case FieldBitSize: return 4; default: @@ -110,16 +114,16 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, break; } - case sample_FIXME: + case sample_two: { switch(attrib) { case FieldName: - return QString("FIXME"); + return QString("TWO"); case FieldValue: - return FIXME; + return data.two(); case FieldTextValue: - return QString("%1").arg(FIXME); + return QString("%1").arg(data.two()); case FieldFrameValue: { QByteArray fv; diff --git a/common/snap.cpp b/common/snap.cpp index c651bb1..3dfd7e4 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -133,7 +133,6 @@ QVariant SnapProtocol::fieldData(int index, FieldAttrib attrib, bool SnapProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { - // FIXME return false; } diff --git a/common/streambase.cpp b/common/streambase.cpp index ecfc07c..1ed8d7f 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -169,9 +169,40 @@ bool StreamBase::setLenMode(FrameLengthMode lenMode) return true; } -quint16 StreamBase::frameLen() +quint16 StreamBase::frameLen(int streamIndex) { - return mCore->frame_len(); + int pktLen; + + // Decide a frame length based on length mode + switch(lenMode()) + { + case OstProto::StreamCore::e_fl_fixed: + pktLen = mCore->frame_len(); + break; + case OstProto::StreamCore::e_fl_inc: + pktLen = frameLenMin() + (streamIndex % + (frameLenMax() - frameLenMin() + 1)); + break; + case OstProto::StreamCore::e_fl_dec: + pktLen = frameLenMax() - (streamIndex % + (frameLenMax() - frameLenMin() + 1)); + break; + case OstProto::StreamCore::e_fl_random: + //! \todo (MED) This 'random' sequence is same across iterations + qsrand(((uint) this)); + for (int i = 0; i <= streamIndex; i++) + pktLen = qrand(); + pktLen = frameLenMin() + (pktLen % + (frameLenMax() - frameLenMin() + 1)); + break; + default: + qWarning("Unhandled len mode %d. Using default 64", + lenMode()); + pktLen = 64; + break; + } + + return pktLen; } bool StreamBase::setFrameLen(quint16 frameLen) diff --git a/common/streambase.h b/common/streambase.h index 99838d9..878b2d7 100644 --- a/common/streambase.h +++ b/common/streambase.h @@ -17,8 +17,6 @@ private: OstProto::StreamCore *mCore; OstProto::StreamControl *mControl; -protected: - //! \todo TODO: Make ProtocolList a private member of StreamBase? ProtocolList *currentFrameProtocols; public: @@ -30,7 +28,7 @@ public: ProtocolListIterator* createProtocolListIterator(); - // TODO: make a copy constructor + //! \todo (LOW) should we have a copy constructor?? public: enum FrameLengthMode { @@ -81,7 +79,7 @@ public: FrameLengthMode lenMode(); bool setLenMode(FrameLengthMode lenMode); - quint16 frameLen(); + quint16 frameLen(int streamIndex = 0); bool setFrameLen(quint16 frameLen); quint16 frameLenMin(); diff --git a/common/svlan.cpp b/common/svlan.cpp new file mode 100644 index 0000000..55ef836 --- /dev/null +++ b/common/svlan.cpp @@ -0,0 +1,49 @@ +#include + +#include "svlan.h" +#include "svlan.pb.h" + +SVlanProtocol::SVlanProtocol(StreamBase *stream, AbstractProtocol *parent) + : VlanProtocol(stream, parent) +{ + data.set_tpid(0x88a8); + data.set_is_override_tpid(true); +} + +SVlanProtocol::~SVlanProtocol() +{ +} + +AbstractProtocol* SVlanProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) +{ + return new SVlanProtocol(stream, parent); +} + +quint32 SVlanProtocol::protocolNumber() const +{ + return OstProto::Protocol::kSvlanFieldNumber; +} + +void SVlanProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const +{ + protocol.MutableExtension(OstProto::svlan)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void SVlanProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::svlan)) + data.MergeFrom(protocol.GetExtension(OstProto::svlan)); +} + +QString SVlanProtocol::name() const +{ + return QString("SVlan"); +} + +QString SVlanProtocol::shortName() const +{ + return QString("SVlan"); +} diff --git a/common/svlan.h b/common/svlan.h new file mode 100644 index 0000000..0fb4b97 --- /dev/null +++ b/common/svlan.h @@ -0,0 +1,23 @@ +#ifndef _SVLAN_H +#define _SVLAN_H + +#include "vlan.h" + +class SVlanProtocol : public VlanProtocol +{ +public: + SVlanProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~SVlanProtocol(); + + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + + virtual QString name() const; + virtual QString shortName() const; +}; + +#endif diff --git a/common/svlan.proto b/common/svlan.proto new file mode 100644 index 0000000..72e4557 --- /dev/null +++ b/common/svlan.proto @@ -0,0 +1,8 @@ +import "protocol.proto"; +import "vlan.proto"; + +package OstProto; + +extend Protocol { + optional Vlan svlan = 125; +} diff --git a/common/tcp.cpp b/common/tcp.cpp index dc461b6..be16120 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -377,7 +377,6 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, bool TcpProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { - // FIXME return false; } diff --git a/common/udp.cpp b/common/udp.cpp index c722b54..0d5b772 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -159,7 +159,7 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, totlen = data.is_override_totlen() ? data.totlen() : - (protocolFramePayloadSize() + 8); + (protocolFramePayloadSize(streamIndex) + 8); return totlen; } case FieldFrameValue: @@ -168,7 +168,7 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, int totlen; totlen = data.is_override_totlen() ? data.totlen() : - (protocolFramePayloadSize() + 8); + (protocolFramePayloadSize(streamIndex) + 8); fv.resize(2); qToBigEndian((quint16) totlen, (uchar*) fv.data()); return fv; @@ -178,7 +178,7 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, int totlen; totlen = data.is_override_totlen() ? data.totlen() : - (protocolFramePayloadSize() + 8); + (protocolFramePayloadSize(streamIndex) + 8); return QString("%1").arg(totlen); } case FieldBitSize: @@ -254,7 +254,7 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, bool UdpProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { - // FIXME + //! implement UdpProtocol::setFieldData() return false; } diff --git a/common/vlan.cpp b/common/vlan.cpp index 49b9a27..244a473 100644 --- a/common/vlan.cpp +++ b/common/vlan.cpp @@ -196,7 +196,6 @@ QVariant VlanProtocol::fieldData(int index, FieldAttrib attrib, bool VlanProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { - // FIXME return false; } diff --git a/common/vlan.h b/common/vlan.h index c5655da..5e5d7de 100644 --- a/common/vlan.h +++ b/common/vlan.h @@ -16,7 +16,6 @@ public: class VlanProtocol : public AbstractProtocol { private: - OstProto::Vlan data; VlanConfigForm *configForm; enum Vlanfield { @@ -31,6 +30,9 @@ private: vlan_fieldCount }; +protected: + OstProto::Vlan data; + public: VlanProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~VlanProtocol(); diff --git a/common/vlanstack.h b/common/vlanstack.h index 5202729..f74aaed 100644 --- a/common/vlanstack.h +++ b/common/vlanstack.h @@ -2,9 +2,10 @@ #define _VLAN_STACK_H #include "comboprotocol.h" +#include "svlan.h" #include "vlan.h" typedef ComboProtocol VlanStackProtocol; + SVlanProtocol, VlanProtocol> VlanStackProtocol; #endif diff --git a/common/vlanstack.proto b/common/vlanstack.proto index 4c3d06d..a54f11f 100644 --- a/common/vlanstack.proto +++ b/common/vlanstack.proto @@ -8,5 +8,5 @@ message VlanStack { } extend Protocol { - optional VlanStack vlanStack = 125; + optional VlanStack vlanStack = 129; } diff --git a/rpc/pbhelper.h b/rpc/pbhelper.h index e3d85b0..7a70c75 100644 --- a/rpc/pbhelper.h +++ b/rpc/pbhelper.h @@ -6,9 +6,11 @@ #include +#if 0 // not reqd. any longer? class PbHelper { public: + // FIXME: Change msg from * to & void ForceSetSingularDefault(::google::protobuf::Message *msg) { @@ -146,3 +148,4 @@ public: } }; #endif +#endif diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index ed60d2f..9d5be05 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -1,7 +1,5 @@ #include "pbrpcchannel.h" -//#include "../common/protocol.pb.h" - PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) { isPending = false; @@ -65,17 +63,36 @@ void PbRpcChannel::CallMethod( ::google::protobuf::Message *response, ::google::protobuf::Closure* done) { - char msg[4096]; // FIXME: hardcoding - char *p = (char *)&msg; + char msg[MSGBUF_SIZE]; int len; + bool ret; - //qDebug("In %s", __FUNCTION__); + if (isPending) + { + RpcCall call; + qDebug("RpcChannel: queueing method %d since %d is pending", + method->index(), pendingMethodId); + + call.method = method; + call.controller = controller; + call.request = req; + call.response = response; + call.done = done; + + pendingCallList.append(call); + + Q_ASSERT(pendingCallList.size() < 100); + + return; + } if (!req->IsInitialized()) { - qDebug("RpcChannel: missing required fields in request"); + qWarning("RpcChannel: missing required fields in request"); qDebug(req->InitializationErrorString().c_str()); + qFatal("exiting"); + controller->SetFailed("Required fields missing"); done->Run(); return; @@ -87,103 +104,172 @@ void PbRpcChannel::CallMethod( this->response=response; isPending = true; - *((quint16*)(p+0)) = HTONS(PB_MSG_TYPE_REQUEST); // type - //qDebug("CLi:GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)), - //PB_MSG_TYPE_REQUEST); - *((quint16*)(p+2)) = HTONS(method->index()); // method id - // (p+4) len later after serialization - *((quint16*)(p+6)) = HTONS(0); // rsvd - - // SerialData is at offset 8 - req->SerializeToArray((void*) (p+8), sizeof(msg)); + ret = req->SerializeToArray((void*) (&msg[PB_HDR_SIZE]), sizeof(msg)); + Q_ASSERT(ret == true); len = req->ByteSize(); - *((quint16*)(p+4)) = HTONS(len); // len + *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_REQUEST); // type + *((quint16*)(&msg[2])) = HTONS(method->index()); // method id + *((quint32*)(&msg[4])) = HTONL(len); // len // Avoid printing stats since it happens every couple of seconds if (pendingMethodId != 12) { - qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, len+8, - req->DebugString().c_str()); - BUFDUMP(msg, len+8); + qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, + PB_HDR_SIZE + len, req->DebugString().c_str()); + BUFDUMP(msg, PB_HDR_SIZE + len); } - mpSocket->write(msg, len + 8); + mpSocket->write(msg, PB_HDR_SIZE + len); } void PbRpcChannel::on_mpSocket_readyRead() { - char msg[4096]; // FIXME: hardcoding; + char msg[MSGBUF_SIZE]; char *p = (char*)&msg; int msgLen; - quint16 type, method, len, rsvd; - PbRpcController *controller; + static bool parsing = false; + static quint16 type, method; + static quint32 len; - //qDebug("In %s", __FUNCTION__); - - msgLen = mpSocket->read(msg, sizeof(msg)); + //qDebug("%s: bytesAvail = %d", __FUNCTION__, mpSocket->bytesAvailable()); - //qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); - //BUFDUMP(msg, msgLen); - - type = NTOHS(GET16(p+0)); - method = NTOHS(GET16(p+2)); - len = NTOHS(GET16(p+4)); - rsvd = NTOHS(GET16(p+6)); - - if (!isPending) + if (!parsing) { - qDebug("not waiting for response"); - - goto _error_exit; + // Do we have an entire header? If not, we'll wait ... + if (mpSocket->bytesAvailable() < PB_HDR_SIZE) + { + qDebug("client: not enough data available for a complete header"); + return; + } + + msgLen = mpSocket->read(msg, PB_HDR_SIZE); + + Q_ASSERT(msgLen == PB_HDR_SIZE); + + type = NTOHS(GET16(p+0)); + method = NTOHS(GET16(p+2)); + len = NTOHL(GET32(p+4)); + + //BUFDUMP(msg, PB_HDR_SIZE); + //qDebug("type = %hu, method = %hu, len = %u", type, method, len); + + parsing = true; } - if (type != PB_MSG_TYPE_RESPONSE) + switch (type) { - qDebug("invalid msgType %d (expected = %d)", type, - PB_MSG_TYPE_RESPONSE); - - goto _error_exit; - } + case PB_MSG_TYPE_BINBLOB: + { + static quint32 cumLen = 0; + QIODevice *blob; - if (pendingMethodId != method) - { - qDebug("invalid method id %d (expected = %d)", method, - pendingMethodId); - - goto _error_exit; - } + blob = static_cast(controller)->binaryBlob(); + Q_ASSERT(blob != NULL); + while ((cumLen < len) && mpSocket->bytesAvailable()) + { + int l; - // Serialized data starts from offset 8 - response->ParseFromArray((void*) &msg[8], len); + l = mpSocket->read(msg, sizeof(msg)); + blob->write(msg, l); + cumLen += l; + } - // Avoid printing stats - if (method != 12) - { - qDebug("client(%s): Parsed as %s", __FUNCTION__, - response->DebugString().c_str()); - } + qDebug("%s: bin blob rcvd %d/%d", __PRETTY_FUNCTION__, cumLen, len); - if (!response->IsInitialized()) - { - qDebug("RpcChannel: missing required fields in response"); - qDebug(response->InitializationErrorString().c_str()); + if (cumLen < len) + return; - controller->SetFailed("Required fields missing"); + cumLen = 0; + + if (!isPending) + { + qDebug("not waiting for response"); + goto _error_exit; + } + + if (pendingMethodId != method) + { + qDebug("invalid method id %d (expected = %d)", method, + pendingMethodId); + goto _error_exit; + } + + break; + } + + case PB_MSG_TYPE_RESPONSE: + // Wait till we have the entire message + if (mpSocket->bytesAvailable() < len) + { + qDebug("client: not enough data available for a complete msg"); + return; + } + + msgLen = mpSocket->read(msg, sizeof(msg)); + + Q_ASSERT((unsigned) msgLen == len); + + //qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); + //BUFDUMP(msg, msgLen); + + if (!isPending) + { + qDebug("not waiting for response"); + goto _error_exit; + } + + if (pendingMethodId != method) + { + qDebug("invalid method id %d (expected = %d)", method, + pendingMethodId); + goto _error_exit; + } + + response->ParseFromArray((void*) msg, len); + + // Avoid printing stats + if (method != 12) + { + qDebug("client(%s): Parsed as %s", __FUNCTION__, + response->DebugString().c_str()); + } + + if (!response->IsInitialized()) + { + qWarning("RpcChannel: missing required fields in response"); + qDebug(response->InitializationErrorString().c_str()); + + controller->SetFailed("Required fields missing"); + } + break; + + default: + qFatal("%s: unexpected type %d", __PRETTY_FUNCTION__, type); + goto _error_exit; + } pendingMethodId = -1; controller = NULL; - //done = NULL; response = NULL; isPending = false; + parsing = false; done->Run(); + if (pendingCallList.size()) + { + RpcCall call = pendingCallList.takeFirst(); + CallMethod(call.method, call.controller, call.request, call.response, + call.done); + } + return; _error_exit: + parsing = false; qDebug("client(%s) discarding received msg", __FUNCTION__); return; } diff --git a/rpc/pbrpcchannel.h b/rpc/pbrpcchannel.h index 657b095..17f287a 100644 --- a/rpc/pbrpcchannel.h +++ b/rpc/pbrpcchannel.h @@ -25,13 +25,22 @@ class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel // passed by the stub to CallMethod(). They are reset to NULL when // we get a response back from the server in on_mpSocket_readyRead() // after calling done->Run(). - // - // TODO(?): change controller, done and response to references - // instead of pointers? + + /*! \todo (MED) : change controller, done and response to references + instead of pointers? */ ::google::protobuf::RpcController *controller; ::google::protobuf::Closure *done; ::google::protobuf::Message *response; + typedef struct _RpcCall { + const ::google::protobuf::MethodDescriptor *method; + ::google::protobuf::RpcController *controller; + const ::google::protobuf::Message *request; + ::google::protobuf::Message *response; + ::google::protobuf::Closure *done; + } RpcCall; + QList pendingCallList; + QHostAddress mServerAddress; quint16 mServerPort; QTcpSocket *mpSocket; diff --git a/rpc/pbrpccommon.h b/rpc/pbrpccommon.h index 5407602..ef4b1ee 100644 --- a/rpc/pbrpccommon.h +++ b/rpc/pbrpccommon.h @@ -1,7 +1,7 @@ #ifndef _PB_RPC_COMMON_H #define _PB_RPC_COMMON_H -// FIXME: check which one is right - wrong one seems to be working!!!!! +//! \todo (LOW) check which one is right - wrong one seems to be working!!!!! #if 0 #define GET16(p) (quint16)( \ (*((quint8*)(p)+0) << 8 ) \ @@ -10,6 +10,11 @@ #define GET16(p) (quint16)( \ (*((quint8*)(p)+1) << 8 ) \ | (*((quint8*)(p)+0))) +#define GET32(p) (quint32)( \ + (*((quint8*)(p)+3) << 24) \ + | (*((quint8*)(p)+2) << 16) \ + | (*((quint8*)(p)+1) << 8 ) \ + | (*((quint8*)(p)+0))) #endif #define BYTESWAP4(x) \ @@ -22,7 +27,7 @@ (((x & 0xFF00) >> 8) | \ ((x & 0x00FF) << 8)) -// TODO: portability +//! \todo (LOW) : portability #if 1 #define HTONL(x) BYTESWAP4(x) #define NTOHL(x) BYTESWAP4(x) @@ -43,10 +48,14 @@ ** RPC Header (8) ** - MSG_TYPE (2) ** - METHOD_ID (2) -** - LEN (2) [not including this header] -** - RSVD (2) +** - LEN (4) [not including this header] */ +#define PB_HDR_SIZE 8 + #define PB_MSG_TYPE_REQUEST 1 #define PB_MSG_TYPE_RESPONSE 2 +#define PB_MSG_TYPE_BINBLOB 3 + +#define MSGBUF_SIZE 4096 #endif diff --git a/rpc/pbrpccontroller.h b/rpc/pbrpccontroller.h index 0b67ded..acc9520 100644 --- a/rpc/pbrpccontroller.h +++ b/rpc/pbrpccontroller.h @@ -6,22 +6,27 @@ class PbRpcController : public ::google::protobuf::RpcController { bool failed; + QIODevice *blob; std::string errStr; public: - PbRpcController() { failed = false; } + PbRpcController() { Reset(); } // Client Side Methods - void Reset() { failed=false;} + void Reset() { failed=false; blob = NULL; } bool Failed() const { return failed; } - void StartCancel() { /* TODO */} + void StartCancel() { /*! \todo (MED) */} std::string ErrorText() const { return errStr; } // Server Side Methods void SetFailed(const std::string &reason) { failed = true; errStr = reason; } bool IsCanceled() const { return false; }; - void NotifyOnCancel(::google::protobuf::Closure *callback) { /*TODO*/ } + void NotifyOnCancel(::google::protobuf::Closure *callback) { /*! \todo (MED) */ } + + // srivatsp added + QIODevice* binaryBlob() { return blob; }; + void setBinaryBlob(QIODevice *binaryBlob) { blob = binaryBlob; }; }; #endif diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index a3978cb..039fc83 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -1,4 +1,4 @@ -#include "pbhelper.h" +//#include "pbhelper.h" #include "rpcserver.h" RpcServer::RpcServer() @@ -37,45 +37,68 @@ bool RpcServer::registerService(::google::protobuf::Service *service, void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController) { - char msg[4096]; // FIXME: hardcoding - char *p = (char *)&msg; + QIODevice *blob; + char msg[MSGBUF_SIZE]; int len; //qDebug("In RpcServer::done"); - // TODO: check PbRpcController to see if method failed if (PbRpcController->Failed()) { qDebug("rpc failed"); goto _exit; } - if (!resp->IsInitialized()) + blob = PbRpcController->binaryBlob(); + if (blob) { - qDebug("response missing required fields!!"); - qDebug(resp->InitializationErrorString().c_str()); + len = blob->size(); + qDebug("is binary blob of len %d", len); + + *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_BINBLOB); // type + *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method + (*(quint32*)(&msg[4])) = HTONL(len); // len + + clientSock->write(msg, PB_HDR_SIZE); + + blob->seek(0); + while (!blob->atEnd()) + { + int l; + + len = blob->read(msg, sizeof(msg)); + l = clientSock->write(msg, len); + Q_ASSERT(l == len); + } + goto _exit; } - *((quint16*)(p+0)) = HTONS(PB_MSG_TYPE_RESPONSE); // type TODO:RESPONSE - *((quint16*)(p+2)) = HTONS(pendingMethodId); // method - *((quint16*)(p+6)) = HTONS(0); // rsvd + if (!resp->IsInitialized()) + { + qWarning("response missing required fields!!"); + qDebug(resp->InitializationErrorString().c_str()); + qFatal("exiting"); + goto _exit; + } - // SerialData is at offset 8 - resp->SerializeToArray((void*) (p+8), sizeof(msg)); + resp->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg)); len = resp->ByteSize(); - (*(quint16*)(p+4)) = HTONS(len); // len + + *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_RESPONSE); // type + *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method + *((quint32*)(&msg[4])) = HTONL(len); // len // Avoid printing stats since it happens once every couple of seconds if (pendingMethodId != 12) { qDebug("Server(%s): sending %d bytes to client encoding <%s>", - __FUNCTION__, len + 8, resp->DebugString().c_str()); + __FUNCTION__, len + PB_HDR_SIZE, resp->DebugString().c_str()); //BUFDUMP(msg, len + 8); } - clientSock->write(msg, len + 8); + clientSock->write(msg, PB_HDR_SIZE + len); _exit: delete PbRpcController; @@ -91,7 +114,7 @@ void RpcServer::when_newConnection() LogInt(tr("already connected, no new connections will be accepted\n")); // Accept and close connection - // TODO: Send reason msg to client + //! \todo (MED) Send reason msg to client sock = server->nextPendingConnection(); sock->disconnectFromHost(); sock->deleteLater(); @@ -127,26 +150,37 @@ void RpcServer::when_error(QAbstractSocket::SocketError socketError) void RpcServer::when_dataAvail() { - char msg[4096]; // FIXME: hardcoding; + char msg[MSGBUF_SIZE]; int msgLen; - char *p = (char*) &msg; - quint16 type, method, len, rsvd; + static bool parsing = false; + static quint16 type, method; + static quint32 len; const ::google::protobuf::MethodDescriptor *methodDesc; ::google::protobuf::Message *req, *resp; PbRpcController *controller; - + + if (!parsing) + { + if (clientSock->bytesAvailable() < PB_HDR_SIZE) + return; + + msgLen = clientSock->read(msg, PB_HDR_SIZE); + + Q_ASSERT(msgLen == PB_HDR_SIZE); + + type = NTOHS(GET16(&msg[0])); + method = NTOHS(GET16(&msg[2])); + len = NTOHL(GET32(&msg[4])); + //qDebug("type = %d, method = %d, len = %d", type, method, len); + + parsing = true; + } + + if (clientSock->bytesAvailable() < len) + return; + msgLen = clientSock->read(msg, sizeof(msg)); - //LogInt(QString(QByteArray(msg, msgLen).toHex())); - - //qDebug("Server %s: rcvd %d bytes", __FUNCTION__, msgLen); - //BUFDUMP(msg, msgLen); - - type = NTOHS(GET16(p+0)); - method = NTOHS(GET16(p+2)); - len = NTOHS(GET16(p+4)); - rsvd = NTOHS(GET16(p+6)); - //qDebug("type = %d, method = %d, len = %d, rsvd = %d", - //type, method, len, rsvd); + Q_ASSERT((unsigned) msgLen == len); if (type != PB_MSG_TYPE_REQUEST) { @@ -154,19 +188,18 @@ void RpcServer::when_dataAvail() type, PB_MSG_TYPE_REQUEST); goto _error_exit; } - methodDesc = service->GetDescriptor()->method(method); if (!methodDesc) { qDebug("server(%s): invalid method id %d", __FUNCTION__, method); - goto _error_exit; // TODO: Return Error to client + goto _error_exit; //! \todo Return Error to client } if (isPending) { qDebug("server(%s): rpc pending, try again", __FUNCTION__); - goto _error_exit; // TODO: Return Error to client + goto _error_exit; //! \todo Return Error to client } pendingMethodId = method; @@ -175,12 +208,12 @@ void RpcServer::when_dataAvail() req = service->GetRequestPrototype(methodDesc).New(); resp = service->GetResponsePrototype(methodDesc).New(); - // Serialized data starts from offset 8 - req->ParseFromArray((void*) (msg+8), len); + req->ParseFromArray((void*)msg, len); if (!req->IsInitialized()) { - qDebug("Missing required fields in request"); + qWarning("Missing required fields in request"); qDebug(req->InitializationErrorString().c_str()); + qFatal("exiting"); delete req; delete resp; @@ -196,9 +229,12 @@ void RpcServer::when_dataAvail() service->CallMethod(methodDesc, controller, req, resp, NewCallback(this, &RpcServer::done, resp, controller)); + parsing = false; + return; _error_exit: + parsing = false; qDebug("server(%s): discarding msg from client", __FUNCTION__); return; } diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h index 9e21587..d93b08a 100644 --- a/rpc/rpcserver.h +++ b/rpc/rpcserver.h @@ -27,7 +27,7 @@ class RpcServer : public QObject void LogInt (QString log) {qDebug("%s", log.toAscii().data());} public: - RpcServer(); // TODO: use 'parent' param + RpcServer(); //! \todo (LOW) use 'parent' param virtual ~RpcServer(); bool registerService(::google::protobuf::Service *service, diff --git a/server/drone.cpp b/server/drone.cpp index 98300ee..1f94d7e 100644 --- a/server/drone.cpp +++ b/server/drone.cpp @@ -1,33 +1,15 @@ #include "drone.h" -extern int myport; // FIXME(HIGH) +extern int myport; Drone::Drone(QDialog *parent) : QDialog(parent) { ui.setupUi(this); -#if 0 // PB - rxtx = new RxTx(this); -#endif + rpcServer = new RpcServer(); service = new MyService(this); - rpcServer->registerService(service, myport?myport:7878); - -#if 0 // PB - serverPortNum = DRONE_PORT; - clientSock = NULL; - - if (myport) - serverPortNum = myport); - - server = new QTcpServer(this); - connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); - //if (!server->listen(QHostAddress("10.0.0.1"), serverPortNum)) - if (!server->listen(QHostAddress::Any, serverPortNum)) - LogInt(tr("Unable to start the server: %1").arg(server->errorString())); - else - LogInt(tr("The server is running on %1:%2").arg(server->serverAddress().toString()).arg(server->serverPort())); -#endif + rpcServer->registerService(service, myport ? myport : 7878); } void Drone::Log(const char* str) @@ -35,62 +17,7 @@ void Drone::Log(const char* str) ui.teLog->append(QString(str)); } -#if 0 // PB -int Drone::SendMsg(const void* msg, int size) -{ - qDebug("Inside SendMsg\n"); - clientSock->write((char*) msg, size); -} -#endif - void Drone::LogInt(const QString &str) { ui.teLog->append(str); } - -#if 0 // PB -void Drone::when_newConnection() -{ - if (clientSock) - { - QTcpSocket *sock; - - LogInt(tr("already connected, no new connections will be accepted\n")); - sock = server->nextPendingConnection(); - // TODO: Send reason msg to client - sock->disconnectFromHost(); - goto _exit; - } - clientSock = server->nextPendingConnection(); - LogInt(tr("accepting new connection from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); - connect(clientSock, SIGNAL(readyRead()), - this, SLOT(when_dataAvail())); - connect(clientSock, SIGNAL(disconnected()), - this, SLOT(when_disconnected())); - connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(when_error(QAbstractSocket::SocketError))); - - -_exit: - return; -} - -void Drone::when_disconnected() -{ - LogInt(tr("closing connection from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); - clientSock->deleteLater(); - clientSock = NULL; -} - -void Drone::when_dataAvail() -{ - QByteArray msg = clientSock->read(1024); // FIXME: hardcoding - LogInt(QString(msg.toHex())); - rxtx->ProcessMsg(msg.constData(), msg.size()); -} - -void Drone::when_error(QAbstractSocket::SocketError socketError) -{ - LogInt(clientSock->errorString()); -} -#endif diff --git a/server/drone.h b/server/drone.h index 3c4adba..31574a6 100644 --- a/server/drone.h +++ b/server/drone.h @@ -3,15 +3,12 @@ #include #include + #include "ui_drone.h" #include "abstracthost.h" -#if 0 // PB -#include "rxtx.h" -#endif #include "rpcserver.h" #include "myservice.h" - class Drone : public QDialog, AbstractHost { Q_OBJECT @@ -20,28 +17,10 @@ class Drone : public QDialog, AbstractHost Ui::Drone ui; Drone(QDialog *parent = 0); void Log(const char *msg); -#if 0 // PB - int SendMsg(const void* msg, int msgLen); -#endif private: -#if 0 // PB - RxTx *rxtx; -#endif RpcServer *rpcServer; OstProto::OstService *service; void LogInt(const QString &msg); -#if 0 // PB - QTcpServer *server; - QTcpSocket *clientSock; -#define DRONE_PORT 7878 - quint16 serverPortNum; - - private slots: - void when_newConnection(); - void when_disconnected(); - void when_dataAvail(); - void when_error(QAbstractSocket::SocketError socketError); -#endif }; #endif diff --git a/server/drone_main.cpp b/server/drone_main.cpp index 5a66b6a..007f1af 100644 --- a/server/drone_main.cpp +++ b/server/drone_main.cpp @@ -2,20 +2,16 @@ Drone *drone; -//void FindDevList(void); - int myport; int main(int argc, char *argv[]) { QApplication app(argc, argv); - // FIXME(HIGH) if (argc > 1) myport = atoi(argv[1]); drone = new Drone; - //FindDevList(); drone->show(); return app.exec(); } diff --git a/server/myservice.cpp b/server/myservice.cpp index ff01e17..cb9a2db 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -2,12 +2,12 @@ #include #include #include "qdebug.h" -#include #include "myservice.h" -#include "../common/protocollist.h" +#include "../common/protocollistiterator.h" #include "../common/abstractprotocol.h" +#include "../rpc/pbrpccontroller.h" #if 0 #include @@ -19,12 +19,6 @@ StreamInfo::StreamInfo() { -#if 0 - PbHelper pbh; - - pbh.ForceSetSingularDefault(mCore); - pbh.ForceSetSingularDefault(mControl); -#endif } StreamInfo::~StreamInfo() @@ -35,30 +29,7 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) { int pktLen, len = 0; - // Decide a frame length based on length mode - switch(lenMode()) - { - case OstProto::StreamCore::e_fl_fixed: - pktLen = frameLen(); - break; - case OstProto::StreamCore::e_fl_inc: - pktLen = frameLenMin() + (n % - (frameLenMax() - frameLenMin() + 1)); - break; - case OstProto::StreamCore::e_fl_dec: - pktLen = frameLenMax() - (n % - (frameLenMax() - frameLenMin() + 1)); - break; - case OstProto::StreamCore::e_fl_random: - pktLen = frameLenMin() + (qrand() % - (frameLenMax() - frameLenMin() + 1)); - break; - default: - qWarning("Unhandled len mode %d. Using default 64", - lenMode()); - pktLen = 64; - break; - } + pktLen = frameLen(n); // pktLen is adjusted for CRC/FCS which will be added by the NIC pktLen -= 4; @@ -66,18 +37,22 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) if ((pktLen < 0) || (pktLen > bufMaxSize)) return 0; - // FIXME: Calculated pktLen is an input to Payload Protocol - foreach(const AbstractProtocol* proto, *currentFrameProtocols) - { - QByteArray ba; + ProtocolListIterator *iter; + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol *proto; + QByteArray ba; + + proto = iter->next(); ba = proto->protocolFrameValue(n); + if (len + ba.size() < bufMaxSize) - { memcpy(buf+len, ba.constData(), ba.size()); - } len += ba.size(); } + delete iter; return pktLen; } @@ -155,9 +130,9 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) if (dev->description) d.set_description(dev->description); - d.set_is_enabled(true); // FIXME(MED):check - d.set_is_oper_up(true); // FIXME(MED):check - d.set_is_exclusive_control(false); // FIXME(MED): check + d.set_is_enabled(true); //! \todo (LOW) admin enable/disable of port + d.set_is_oper_up(true); //! \todo (HIGH) oper up/down of port + d.set_is_exclusive_control(false); //! \todo (HIGH) port exclusive control memset((void*) &stats, 0, sizeof(stats)); resetStats(); @@ -190,7 +165,7 @@ void PortInfo::update() sendQueueList.clear(); returnToQIdx = -1; - // TODO(LOW): calculate sendqueue size + //! \todo (LOW): calculate sendqueue size sendQ.sendQueue = pcap_sendqueue_alloc(1*MB); sendQ.sendQueueCumLen.clear(); @@ -254,7 +229,7 @@ void PortInfo::update() { sendQueueList.append(sendQ); - // TODO(LOW): calculate sendqueue size + //! \todo (LOW): calculate sendqueue size sendQ.sendQueue = pcap_sendqueue_alloc(1*MB); sendQ.sendQueueCumLen.clear(); @@ -291,16 +266,17 @@ void PortInfo::update() goto _stop_no_more_pkts; case ::OstProto::StreamControl::e_nw_goto_id: - // TODO(MED): define and use - // streamList[i].d.control().goto_stream_id(); + /*! \todo (MED): define and use + streamList[i].d.control().goto_stream_id(); */ - // TODO(MED): assumes goto Id is less than current!!!! - // To support goto to any id, do - // if goto_id > curr_id then - // i = goto_id; - // goto restart; - // else - // returnToQIdx = 0; + /*! \todo (MED): assumes goto Id is less than current!!!! + To support goto to any id, do + if goto_id > curr_id then + i = goto_id; + goto restart; + else + returnToQIdx = 0; + */ returnToQIdx=0; goto _stop_no_more_pkts; @@ -344,9 +320,9 @@ void PortInfo::stopCapture() capturer.stop(); } -void PortInfo::viewCapture() +QFile* PortInfo::captureFile() { - capturer.view(); + return capturer.captureFile(); } void PortInfo::resetStats() @@ -550,7 +526,7 @@ void PortInfo::PortMonitorRx::callbackRx(u_char *state, // Update RxStats and RxRates using PCAP data usec = (header->ts.tv_sec - port->lastTsRx.tv_sec) * 1000000 + (header->ts.tv_usec - port->lastTsRx.tv_usec); - // TODO(rate) + //! \todo support Rx Pkt/Bit rate on Linux (libpcap callback) #if 0 port->stats.rxPps = (pkts * 1000000) / usec; port->stats.rxBps = (bytes * 1000000) / usec; @@ -581,7 +557,7 @@ void PortInfo::PortMonitorTx::callbackTx(u_char *state, // Update TxStats and TxRates using PCAP data usec = (header->ts.tv_sec - port->lastTsTx.tv_sec) * 1000000 + (header->ts.tv_usec - port->lastTsTx.tv_usec); - // TODO(rate) + //! \todo support Tx Pkt/Bit rate on Linux (libpcap callback) #if 0 port->stats.txPps = (pkts * 1000000) / usec; port->stats.txBps = (bytes * 1000000) / usec; @@ -703,7 +679,7 @@ PortInfo::PortTransmitter::PortTransmitter(PortInfo *port) void PortInfo::PortTransmitter::run() { - // TODO(HI): Stream Mode - one pass/continuous + //! \todo (MED) Stream Mode - continuous: define before implement // NOTE1: We can't use pcap_sendqueue_transmit() directly even on Win32 // 'coz of 2 reasons - there's no way of stopping it before all packets @@ -739,14 +715,20 @@ PortInfo::PortCapture::PortCapture(PortInfo *port) dumpHandle = NULL; } +PortInfo::PortCapture::~PortCapture() +{ +} + void PortInfo::PortCapture::run() { + int ret; + if (capHandle == NULL) { char errbuf[PCAP_ERRBUF_SIZE]; - capHandle = pcap_open_live(port->dev->name, 0, - PCAP_OPENFLAG_PROMISCUOUS, 1000 /*ms*/, errbuf); + capHandle = pcap_open_live(port->dev->name, 65535, + PCAP_OPENFLAG_PROMISCUOUS, -1, errbuf); if (capHandle == NULL) { qDebug("Error opening port %s: %s\n", @@ -757,12 +739,27 @@ void PortInfo::PortCapture::run() { if (!capFile.open()) qFatal("Unable to open temp cap file"); - qDebug("cap file = %s", capFile.fileName().toAscii().constData()); } + + qDebug("cap file = %s", capFile.fileName().toAscii().constData()); dumpHandle = pcap_dump_open(capHandle, capFile.fileName().toAscii().constData()); - pcap_loop(capHandle, -1, pcap_dump, (uchar*) dumpHandle); + ret = pcap_loop(capHandle, -1, pcap_dump, (uchar*) dumpHandle); + switch (ret) + { + case -2: + qDebug("%s: breakloop called %d", __PRETTY_FUNCTION__, ret); + break; + + case -1: + case 0: + qFatal("%s: unexpected break from loop (%d): %s", + __PRETTY_FUNCTION__, ret, pcap_geterr(capHandle)); + break; + default: + qFatal("%s: Unexpected return value %d", __PRETTY_FUNCTION__, ret); + } } void PortInfo::PortCapture::stop() @@ -776,11 +773,9 @@ void PortInfo::PortCapture::stop() } } -void PortInfo::PortCapture::view() +QFile* PortInfo::PortCapture::captureFile() { - // FIXME: hack - when correcting this remove the include also - QProcess::execute("C:/Program Files/Wireshark/wireshark.exe", - QStringList() << capFile.fileName()); + return &capFile; } @@ -914,7 +909,7 @@ const ::OstProto::PortId* request, { qDebug("%s: Invalid port id %d", __PRETTY_FUNCTION__, portIdx); controller->SetFailed("Invalid Port Id"); - goto _exit; // TODO(LOW): Partial status of RPC + goto _exit; //! \todo (LOW): Partial status of RPC } response->mutable_port_id()->set_id(portIdx); @@ -954,7 +949,7 @@ const ::OstProto::StreamIdList* request, streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); if (streamIndex < 0) - continue; // TODO(LOW): Partial status of RPC + continue; //! \todo(LOW): Partial status of RPC s = response->add_stream(); @@ -989,7 +984,7 @@ const ::OstProto::StreamIdList* request, // If stream with same id as in request exists already ==> error!! streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); if (streamIndex >= 0) - continue; // TODO(LOW): Partial status of RPC + continue; //! \todo (LOW): Partial status of RPC // Append a new "default" stream - actual contents of the new stream is // expected in a subsequent "modifyStream" request - set the stream id @@ -997,7 +992,7 @@ const ::OstProto::StreamIdList* request, s->mStreamId.CopyFrom(request->stream_id(i)); portInfo[portIdx]->streamList.append(s); - // TODO(LOW): fill-in response "Ack"???? + //! \todo (LOW): fill-in response "Ack"???? } portInfo[portIdx]->setDirty(true); _exit: @@ -1027,11 +1022,11 @@ const ::OstProto::StreamIdList* request, streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); if (streamIndex < 0) - continue; // TODO(LOW): Partial status of RPC + continue; //! \todo (LOW): Partial status of RPC delete portInfo[portIdx]->streamList.takeAt(streamIndex); - // TODO(LOW): fill-in response "Ack"???? + //! \todo (LOW): fill-in response "Ack"???? } portInfo[portIdx]->setDirty(true); _exit: @@ -1061,12 +1056,12 @@ const ::OstProto::StreamConfigList* request, streamIndex = getStreamIndex(portIdx, request->stream(i).stream_id().id()); if (streamIndex < 0) - continue; // TODO(LOW): Partial status of RPC + continue; //! \todo (LOW): Partial status of RPC portInfo[portIdx]->streamList[streamIndex]->protoDataCopyFrom( request->stream(i)); - // TODO(LOW): fill-in response "Ack"???? + //! \todo(LOW): fill-in response "Ack"???? } portInfo[portIdx]->setDirty(true); _exit: @@ -1087,7 +1082,7 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // TODO(LOW): partial RPC? + continue; //! \todo (LOW): partial RPC? if (portInfo[portIdx]->isDirty()) portInfo[portIdx]->update(); @@ -1099,12 +1094,12 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // TODO(LOW): partial RPC? + continue; //! \todo (LOW): partial RPC? portInfo[portIdx]->startTransmit(); } - // TODO(LOW): fill-in response "Ack"???? + //! \todo (LOW): fill-in response "Ack"???? done->Run(); } @@ -1122,11 +1117,11 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // TODO(LOW): partial RPC? + continue; //! \todo (LOW): partial RPC? portInfo[portIdx]->stopTransmit(); } - // TODO(LOW): fill-in response "Ack"???? + //! \todo (LOW): fill-in response "Ack"???? done->Run(); } @@ -1143,7 +1138,7 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // TODO(LOW): partial RPC? + continue; //! \todo (LOW): partial RPC? portInfo[portIdx]->startCapture(); } @@ -1163,7 +1158,7 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // TODO(LOW): partial RPC? + continue; //! \todo (LOW): partial RPC? portInfo[portIdx]->stopCapture(); } @@ -1172,25 +1167,25 @@ const ::OstProto::PortIdList* request, } void MyService::getCaptureBuffer(::google::protobuf::RpcController* controller, -const ::OstProto::PortIdList* request, -::OstProto::CaptureBufferList* response, +const ::OstProto::PortId* request, +::OstProto::CaptureBuffer* response, ::google::protobuf::Closure* done) { + uint portIdx; qDebug("In %s", __PRETTY_FUNCTION__); - // FIXME: BAD BAD VERY BAD !!!!!! - for (int i=0; i < request->port_id_size(); i++) + portIdx = request->id(); + if (portIdx >= numPorts) { - uint portIdx; - - portIdx = request->port_id(i).id(); - if (portIdx >= numPorts) - continue; // TODO(LOW): partial RPC? - - portInfo[portIdx]->viewCapture(); + controller->SetFailed("invalid portid"); + goto _exit; } - controller->SetFailed("Not Implemented"); + portInfo[portIdx]->stopCapture(); + static_cast(controller)->setBinaryBlob( + portInfo[portIdx]->captureFile()); + +_exit: done->Run(); } @@ -1208,7 +1203,7 @@ const ::OstProto::PortIdList* request, portidx = request->port_id(i).id(); if (portidx >= numPorts) - continue; // TODO(LOW): partial rpc? + continue; //! \todo(LOW): partial rpc? s = response->add_port_stats(); s->mutable_port_id()->set_id(request->port_id(i).id()); @@ -1260,11 +1255,11 @@ const ::OstProto::PortIdList* request, portIdx = request->port_id(i).id(); if (portIdx >= numPorts) - continue; // TODO(LOW): partial RPC? + continue; //! \todo (LOW): partial RPC? portInfo[portIdx]->resetStats(); } - // TODO(LOW): fill-in response "Ack"???? + //! \todo (LOW): fill-in response "Ack"???? done->Run(); } diff --git a/server/myservice.h b/server/myservice.h index 270bfba..fb55283 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -105,9 +105,10 @@ class PortInfo public: PortCapture(PortInfo *port); + ~PortCapture(); void run(); void stop(); - void view(); + QFile* captureFile(); }; OstProto::Port d; @@ -173,7 +174,7 @@ public: void stopTransmit(); void startCapture(); void stopCapture(); - void viewCapture(); + QFile* captureFile(); void resetStats(); }; @@ -241,8 +242,8 @@ public: ::OstProto::Ack* response, ::google::protobuf::Closure* done); virtual void getCaptureBuffer(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::CaptureBufferList* response, + const ::OstProto::PortId* request, + ::OstProto::CaptureBuffer* response, ::google::protobuf::Closure* done); virtual void getStats(::google::protobuf::RpcController* controller, const ::OstProto::PortIdList* request, diff --git a/server/pcapextra.cpp b/server/pcapextra.cpp index 4ad8a51..197e83b 100644 --- a/server/pcapextra.cpp +++ b/server/pcapextra.cpp @@ -79,14 +79,14 @@ _restart: if (*p_stop) return ret; - // TODO(HI): Timing between subsequent sendQueues + //! \todo (HIGH): Timing between subsequent sendQueues } if (returnToQIdx >= 0) { i = returnToQIdx; - // FIXME: 1s fixed; Change this to ipg of last stream + //! \todo (HIGH) 1s fixed; Change this to ipg of last stream (*pf_usleep)(1000000); goto _restart; } diff --git a/server/rxtx.cpp b/server/rxtx.cpp deleted file mode 100644 index 11789f1..0000000 --- a/server/rxtx.cpp +++ /dev/null @@ -1,514 +0,0 @@ - -FIXME(HI): File Not used anymore - -#if 0 -#include "qtglobal" // FIXME: needed only for qdebug -#include "rxtx.h" -#if 0 // PB -#include "../common/protocol.h" -#endif - - - -//#define LOG(...) drone->ui.teLOG->append(QString().sprintf( __VA_ARGS__)) -//#define LOG(...) drone->LOG(QString().sprintf( __VA_ARGS__)) -#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} - - -RxTx::RxTx(AbstractHost *host) -{ - pcap_if_t *d; - int i=0; - char errbuf[PCAP_ERRBUF_SIZE]; - - // Init Data - RxTx::host = host; - numPorts = 0; - alldevs = NULL; - - LOG("Retrieving the device list from the local machine\n"); - if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) - { - LOG("Error in pcap_findalldevs_ex: %s\n", errbuf); - goto _fail; - } - - /* Count number of local ports */ - for(d = alldevs; d != NULL; d = d->next) - numPorts++; - - portInfo = new PortInfo[numPorts]; - - /* Print the list */ - for(i=0, d=alldevs; d!=NULL; i++, d=d->next) - { - portInfo[i].portId = i; - portInfo[i].dev = d; - portInfo[i].streamHead = NULL; - portInfo[i].streamTail = NULL; -#if 1 - LOG("%d. %s", i, d->name); - if (d->description) - { - LOG(" (%s)\n", d->description); - } - else - LOG(" (No description available)\n"); -#endif - } - - if (i == 0) - { - LOG("\nNo interfaces found! Make sure WinPcap is installed.\n"); - goto _fail; - } - -_fail: - return; -} - -#if 0 -RxTx::LOG(char* fmt, ...) -{ - sprintf(logStr, fmt, _VA_ARGS_); - host->LOG(logStr); -} -#endif - -RxTx::~RxTx() -{ - unsigned int i; - - for (i = 0; i < numPorts; i++) - DeleteAllStreams(i); - pcap_freealldevs(alldevs); -} - -void RxTx::ProcessMsg(const char* msg, int len) -{ - tCommHdr *hdr; - // TODO: For now assuming we'll get a complete msg - // but need to fix this as this is a TCP stream - - hdr = (tCommHdr*) msg; - - if (hdr->ver != 1) // FIXME:hardcoding - { - LOG("Rcvd msg with invalid version %d\n", hdr->ver); - goto _exit; - } - - qDebug("msgType - %x: %x\n", hdr->msgType, NTOHS(hdr->msgType)); - switch (NTOHS(hdr->msgType)) - { - case e_MT_GetCapability: - SendCapabilityInfo(); - break; - case e_MT_ChangePortConfig: - ProcessPortConfig(msg+sizeof(tCommHdr), len - sizeof(tCommHdr)); - break; - case e_MT_GetPortConfig: - SendPortInfo(0); // FIXME - break; - - default: - LOG("Rcvd msg with unrecognized msgType %d\n", NTOHS(hdr->msgType)); - } - -_exit: - return; -} - -void RxTx::SendCapabilityInfo(void) -{ - unsigned char *msg, *p; - unsigned int i, msgLen; - - p = msg = (unsigned char*) pktBuff; - ((tCommHdr*)(p))->ver = 1; - ((tCommHdr*)(p))->msgType = HTONS(e_MT_CapabilityInfo); - p += sizeof(tCommHdr); - - for (i = 0; i < numPorts; i++) - { - // TLV: Port Capability - ((tTlvPortCapability*)(p))->tlvType = HTONS(e_TT_PortCapability); - ((tTlvPortCapability*)(p))->tlvLen = HTONS(sizeof(tTlvPortCapability)); - ((tTlvPortCapability*)(p))->portId = HTONL(portInfo[i].portId); - ((tTlvPortCapability*)(p))->portSpeed = 0; // TODO -#if 0 - strncpy(((tTlvPortCapability*)(p))->name, - portInfo[i].dev->name, TLV_MAX_PORT_NAME); - ((tTlvPortCapability*)(p))->name[TLV_MAX_PORT_NAME-1] = 0; -#else - strcpy(((tTlvPortCapability*)(p))->portName, "eth"); - //strcat(((tTlvPortCapability*)(p))->name, itoa(portInfo[i].portId, NULL, 10)); - itoa(portInfo[i].portId, &(((tTlvPortCapability*)(p))->portName[3]), 10); -#endif - strncpy(((tTlvPortCapability*)(p))->portDesc, - portInfo[i].dev->description, TLV_MAX_PORT_DESC); - ((tTlvPortCapability*)(p))->portDesc[TLV_MAX_PORT_DESC -1] = 0; - p += sizeof(tTlvPortCapability); - } - msgLen = (p - msg); - ((tCommHdr*)(msg))->msgLen = HTONS(msgLen); - - logStr[0] = 0; - for (i = 0; i < msgLen >> 2; i++) - { - char word[10]; - - sprintf(word, "%08X ", HTONL(((unsigned int *)(msg))[i])); - strcat(logStr, word); - } - host->Log("Sending msg\n"); - host->Log(logStr); -#if 0 // PB - host->SendMsg(pktBuff, msgLen); -#endif -} - -void RxTx::ProcessPortConfig(const char* msg, int len) -{ - // ASSUMPTION: msg points to start of first TLV - UINT8 *p = (UINT8*) msg; - uTlvStream u; - Stream *s; - - // Extract and process each TLV - while (len) - { - if (len < 12) - { - LOG("Length (%d) Error - not enough to fit a TLV", len); - goto _exit; - } - - u.tlv.tlvType = NTOHS(GET16(p)); - u.tlv.tlvLen = NTOHS(GET16(p+2)); - u.tlv.portId = NTOHL(GET32(p+4)); - u.tlv.streamId = NTOHL(GET32(p+8)); - - p += 12; - len -= 12; - - // Locate the correct node for processing - if (u.tlv.portId >= numPorts) - goto _next_tlv; - - s = GetStream(u.tlv.portId, u.tlv.streamId); - if ((s == NULL) && (u.tlv.tlvType!= e_TT_StreamOper)) - { - LOG("Unrecognized stream Id %d\n", u.tlv.streamId); - goto _next_tlv; - } - - switch(u.tlv.tlvType) - { - case e_TT_StreamOper: - u.oper.streamOper = NTOHS(GET16(p+2)); - switch (u.oper.streamOper) - { - case TLV_STREAM_OPER_DELETE: - if (!DeleteStream(u.tlv.portId, u.tlv.streamId)) - { - LOG("No Stream with id %d currently in list\n", - u.tlv.streamId); - goto _next_tlv; - } - break; - case TLV_STREAM_OPER_INSERT_HEAD: - s = new Stream; - s->id = u.tlv.streamId; - - InsertStreamAtHead(u.tlv.portId, s); - break; - case TLV_STREAM_OPER_INSERT_TAIL: - s = new Stream; - s->id = u.tlv.streamId; - - InsertStreamAtTail(u.tlv.portId, s); - break; - case TLV_STREAM_OPER_INSERT_BEFORE: - { - UINT32 nextStreamId; - - s = new Stream; - s->id = u.tlv.streamId; - - nextStreamId = NTOHS(GET32(p+4)); - - if (!InsertStreamBefore(u.tlv.portId, s, nextStreamId)) - { - LOG("List Empty or No stream with id %d " - "currently in list\n", nextStreamId); - goto _next_tlv; - } - break; - } - default: - LOG("Unrecognized Stream Oper %d\n", - u.oper.streamOper); - goto _next_tlv; - } - break; - case e_TT_StreamName: - strncpy(s->name, (char*) p, MAX_STREAM_NAME_SIZE); - break; - - case e_TT_StreamStatus: - u.status.streamStatus = NTOHL(GET32(p)); - if (u.status.streamStatus == TLV_STREAM_STATUS_DISABLED) - s->flags |= STREAM_FLAG_VALUE_STATUS_DISABLED; // FIXME - else if (u.status.streamStatus == TLV_STREAM_STATUS_ENABLED) - s->flags |= STREAM_FLAG_VALUE_STATUS_ENABLED; // FIXME - else - goto _next_tlv; - break; - - case e_TT_StreamFrameLength: - u.frameLen.frameLenMode = NTOHS(GET16(p)); - u.frameLen.frameLen = NTOHS(GET16(p+2)); - u.frameLen.frameLenMin = NTOHS(GET16(p+4)); - u.frameLen.frameLenMax = NTOHS(GET16(p+6)); - - s->pktLen = u.frameLen.frameLen; - - // FIXME: other frameLen params - break; - - case e_TT_StreamDataPattern: - u.dataPattern.dataPatternMode = NTOHS(GET16(p)); - u.dataPattern.dataPattern = NTOHS(GET32(p+4)); - - s->dataPattern = u.dataPattern.dataPattern; - - // FIXME: other dataPattern params - break; - - case e_TT_StreamHeaderData: - u.headerData.headerLen = NTOHS(GET16(p+2)); - - s->hdrLen = u.headerData.headerLen; - memcpy(s->pktHdr, p+4, u.headerData.headerLen); - break; - - default: - LOG("Unrecognizeed/Unexpected TLV %d\n", u.tlv.tlvType); - } - -_next_tlv: - p += u.tlv.tlvLen; - len -= u.tlv.tlvLen; - } - -_exit: - return; -} - -void RxTx::SendPortInfo(unsigned int port) -{ - // FIXME -} - -/* -** --------------------- STREAM LIST OPERATIONS ------------------------- -*/ - -void RxTx::InsertStreamAtHead(unsigned int port, Stream *s) -{ - if (portInfo[port].streamHead == NULL) - { - // list empty - first entry being added - s->next = NULL; - portInfo[port].streamHead = portInfo[port].streamTail = s; - } - else - { - // at least one entry in list, so tail does not change - s->next = portInfo[port].streamHead; - portInfo[port].streamHead = s; - } -} - -void RxTx::InsertStreamAtTail(unsigned int port, Stream *s) -{ - s->next = NULL; - if (portInfo[port].streamHead == NULL) - { - // list empty - first entry being added - portInfo[port].streamHead = portInfo[port].streamTail = s; - } - else - { - // at least one entry in list, so head does not change - portInfo[port].streamTail->next = s; - portInfo[port].streamTail = s; - } -} - -bool RxTx::InsertStreamBefore(unsigned int port, Stream *s, - unsigned int nextStreamId) -{ - Stream *q, *r; - - // For an "Insert Before", list cannot be empty - if (portInfo[port].streamHead == NULL) - { - LOG("Cannot 'insert before' in an empty list"); - return false; - } - - // Traverse with 'r' and keep track of previous with 'q' - q = NULL; - r = portInfo[port].streamHead; - while (r != NULL) - { - if (r->id == nextStreamId) - { - if (r == portInfo[port].streamHead) - { - // Insert at Head - s->next = portInfo[port].streamHead; - portInfo[port].streamHead = s; - } - else if (r == portInfo[port].streamTail) - { - // Insert one before Tail - s->next = portInfo[port].streamTail; - q->next = s; - } - else - { - s->next = r; - q->next = s; - } - - break; - } - q = r; - r = r->next; - } - - if (r == NULL) - return false; - else - return true; -} - -bool RxTx::DeleteStream(unsigned int port, Stream *s) -{ - Stream *q, *r; - - // Traverse with 'r' and keep track of prev with 'q' - q = NULL; - r = portInfo[port].streamHead; - while (r != NULL) - { - if (r == s) - { - if (r == portInfo[port].streamHead) - { - if (portInfo[port].streamHead == portInfo[port].streamTail) - { - portInfo[port].streamHead = NULL; - portInfo[port].streamTail = NULL; - } - else - portInfo[port].streamHead = portInfo[port].streamHead->next; - } - else if (r == portInfo[port].streamTail) - { - q->next = NULL; - portInfo[port].streamTail = q; - } - else - { - q->next = r->next; - } - - delete r; - break; - } - q = r; - r = r->next; - } - - if (r == NULL) - return false; - else - return true; -} - -bool RxTx::DeleteStream(unsigned int port, unsigned int streamId) -{ - Stream *q, *r; - - // Traverse with 'r' and keep track of prev with 'q' - q = NULL; - r = portInfo[port].streamHead; - while (r != NULL) - { - if (r->id == streamId) - { - if (r == portInfo[port].streamHead) - { - if (portInfo[port].streamHead == portInfo[port].streamTail) - { - portInfo[port].streamHead = NULL; - portInfo[port].streamTail = NULL; - } - else - portInfo[port].streamHead = portInfo[port].streamHead->next; - } - else if (r == portInfo[port].streamTail) - { - q->next = NULL; - portInfo[port].streamTail = q; - } - else - { - q->next = r->next; - } - - delete r; - break; - } - q = r; - r = r->next; - } - - if (r == NULL) - return false; - else - return true; -} - -void RxTx::DeleteAllStreams(unsigned int port) -{ - Stream *r, *q; - - r = portInfo[port].streamHead; - while (r != NULL) - { - q = r; - r = r->next; - delete q; - } -} - -Stream* RxTx::GetStream(unsigned int port, unsigned int streamId) -{ - Stream *r; - - r = portInfo[port].streamHead; - while (r != NULL) - { - if (r->id == streamId) - return r; - r = r->next; - } - - return NULL; -} -#endif diff --git a/server/rxtx.h b/server/rxtx.h deleted file mode 100644 index 7b86991..0000000 --- a/server/rxtx.h +++ /dev/null @@ -1,84 +0,0 @@ - -FIXME(HI): File not used anymore - -#if 0 - -#ifndef _RXTX_H -#define _RXTX_H - -#include "pcap.h" -#include "abstracthost.h" - -#include "../common/protocol.h" - -#define GET16(x) (UINT16)( \ - (*((UINT8*)x+0) << 16 ) \ - | (*((UINT8*)x+1))) - -#define GET32(x) (UINT32)( \ - (*((UINT8*)x+0) << 24) \ - | (*((UINT8*)x+1) << 16) \ - | (*((UINT8*)x+2) << 8 ) \ - | (*((UINT8*)x+3))) - -#define MAX_PKT_HDR_SIZE 1536 -#define MAX_STREAM_NAME_SIZE 64 - -typedef struct _Stream -{ - unsigned int id; - char name[MAX_STREAM_NAME_SIZE]; - unsigned char pktHdr[MAX_PKT_HDR_SIZE]; - unsigned short hdrLen; - unsigned short pktLen; - unsigned int dataPattern; - unsigned int flags; -#define STREAM_FLAG_MASK_STATUS 0x00000001 -#define STREAM_FLAG_VALUE_STATUS_DISABLED 0x00000000 -#define STREAM_FLAG_VALUE_STATUS_ENABLED 0x00000001 - - struct _Stream *next; -} Stream; - -typedef struct -{ - unsigned int portId; - pcap_if_t *dev; - Stream *streamHead; - Stream *streamTail; -} PortInfo; - -class RxTx -{ - public: - RxTx(AbstractHost* host); - ~RxTx(); - void ProcessMsg(const char* msg, int len); - - private: - AbstractHost *host; - char logStr[1024]; - -#define MAX_PKT_SIZE 1024 - unsigned char pktBuff[MAX_PKT_SIZE]; - unsigned numPorts; - PortInfo *portInfo; - pcap_if_t *alldevs; - - void InsertStreamAtHead(unsigned int port, Stream *s); - void InsertStreamAtTail(unsigned int port, Stream *s); - bool InsertStreamBefore(unsigned int port, Stream *s, - unsigned int nextStreamId); - bool DeleteStream(unsigned int port, Stream *s); - bool DeleteStream(unsigned int port, unsigned int streamId); - void DeleteAllStreams(unsigned int port); - Stream* GetStream(unsigned int port, unsigned int streamId); - - //void Log(char *fmt, ...); - void SendCapabilityInfo(void); - void SendPortInfo(unsigned int port); - void ProcessPortConfig(const char* msg, int len); -}; - -#endif -#endif From ade8c119d9d171f79bcefe798a0cf411d7de4962 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 8 Nov 2009 08:20:34 +0000 Subject: [PATCH 28/98] Features - Port State (Link/Transmit/Capture) now updated alongwith port stats - On link state change, the port window is not updated - partial changes have been done under #if 0; needs refactoring of Port Class implementation/usage before a signal/slot for the same can be implemented Fixes - Fixed crash in client when connection to server is broken - Packet Capture and Capture Buffer Retrieval now works correctly and consistently (I think!) Others - Minor visual changes in Ports Window - Port Stats Window now has 'right' alignment for stats data and 'center' for state data --- client/icons/bullet_white.png | Bin 0 -> 201 bytes client/ostinato.qrc | 1 + client/port.cpp | 7 ++ client/port.h | 11 +++- client/portgroup.h | 2 +- client/portgrouplist.cpp | 4 +- client/portmodel.cpp | 18 +++++- client/portmodel.h | 2 +- client/portstatsmodel.cpp | 26 +++++++- client/portstatsmodel.h | 32 ++++++++- client/portswindow.cpp | 9 ++- client/portswindow.h | 1 + client/portswindow.ui | 43 ++++++++++++- common/protocol.proto | 16 ++++- server/myservice.cpp | 118 +++++++++++++++++++++++++--------- server/myservice.h | 13 ++++ 16 files changed, 257 insertions(+), 46 deletions(-) create mode 100644 client/icons/bullet_white.png diff --git a/client/icons/bullet_white.png b/client/icons/bullet_white.png new file mode 100644 index 0000000000000000000000000000000000000000..a9af8d44bf3c001adc41e3774f526bd1d1448b1f GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%M_H=O!(Kvthf+1gnf`Cilxr3SC zCq+y2HhAz(;&}R`x^q^&(wiOs&2u-u^*?dO$=Q}CfYva0y85}Sb4q9e0M-pfO8@`> literal 0 HcmV?d00001 diff --git a/client/ostinato.qrc b/client/ostinato.qrc index 48ab66a..1b09036 100644 --- a/client/ostinato.qrc +++ b/client/ostinato.qrc @@ -7,6 +7,7 @@ icons/bullet_green.png icons/bullet_orange.png icons/bullet_red.png + icons/bullet_white.png icons/bullet_yellow.png icons/control_play.png icons/control_stop.png diff --git a/client/port.cpp b/client/port.cpp index 291b1b5..d7e2b4c 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -183,6 +183,13 @@ void Port::when_syncComplete() void Port::updateStats(OstProto::PortStats *portStats) { + OstProto::PortState oldState; + + oldState = stats.state(); stats.MergeFrom(*portStats); +#if 0 + if (oldState.link_state() != stats.state().link_state()) + emit portDataChanged(mPortGroupId, mPortId); +#endif } diff --git a/client/port.h b/client/port.h index 126b28d..bdafdb9 100644 --- a/client/port.h +++ b/client/port.h @@ -30,7 +30,6 @@ private: void reorderStreamsByOrdinals(); public: enum AdminStatus { AdminDisable, AdminEnable }; - enum OperStatus { OperDown, OperUp }; enum ControlMode { ControlShared, ControlExclusive }; // FIXME(HIGH): default args is a hack for QList operations on Port @@ -48,8 +47,6 @@ public: { return QString().fromStdString(d.description()); } AdminStatus adminStatus() { return (d.is_enabled()?AdminEnable:AdminDisable); } - OperStatus operStatus() - { return (d.is_oper_up()?OperUp:OperDown); } ControlMode controlMode() { return (d.is_exclusive_control()?ControlExclusive:ControlShared); } @@ -70,6 +67,9 @@ public: Q_ASSERT(index < mStreams.size()); return mStreams[index]; } + OstProto::LinkState linkState() + { return stats.state().link_state(); } + OstProto::PortStats getStats() { return stats; } // FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal @@ -97,6 +97,11 @@ public: void updateStats(OstProto::PortStats *portStats); +#if 0 +signals: + void portDataChanged(int portGroupId, int portId); +#endif + }; #endif diff --git a/client/portgroup.h b/client/portgroup.h index c74640a..81363cc 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -91,7 +91,7 @@ public: void processClearStatsAck(OstProto::Ack *ack); signals: - void portGroupDataChanged(PortGroup* portGroup); + void portGroupDataChanged(PortGroup* portGroup, int portId = 0xFFFF); void portListAboutToBeChanged(quint32 portGroupId); void portListChanged(quint32 portGroupId); void statsChanged(quint32 portGroupId); diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index a503449..4387aee 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -60,8 +60,8 @@ void PortGroupList::addPortGroup(PortGroup &portGroup) { mPortGroupListModel.portGroupAboutToBeAppended(); - connect(&portGroup, SIGNAL(portGroupDataChanged(PortGroup*)), - &mPortGroupListModel, SLOT(when_portGroupDataChanged(PortGroup*))); + connect(&portGroup, SIGNAL(portGroupDataChanged(PortGroup*, int)), + &mPortGroupListModel, SLOT(when_portGroupDataChanged(PortGroup*, int))); #if 0 connect(&portGroup, SIGNAL(portListAboutToBeChanged(quint32)), &mPortGroupListModel, SLOT(triggerLayoutAboutToBeChanged())); diff --git a/client/portmodel.cpp b/client/portmodel.cpp index 61f9be8..9397cc1 100644 --- a/client/portmodel.cpp +++ b/client/portmodel.cpp @@ -144,7 +144,17 @@ QVariant PortModel::data(const QModelIndex &index, int role) const DBG0("Exit PortModel data 5\n"); if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) return QVariant(); - return QIcon(":/icons/bullet_green.png"); + switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()].linkState()) + { + case OstProto::LinkStateUnknown: + return QIcon(":/icons/bullet_white.png"); + case OstProto::LinkStateDown: + return QIcon(":/icons/bullet_red.png"); + case OstProto::LinkStateUp: + return QIcon(":/icons/bullet_green.png"); + default: + qFatal("unexpected/unimplemented port oper state"); + } } else { @@ -152,6 +162,8 @@ QVariant PortModel::data(const QModelIndex &index, int role) const return QVariant(); } } + + return QVariant(); } QVariant PortModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -252,7 +264,7 @@ quint32 PortModel::portId(const QModelIndex& index) // ---------------------------------------------- // Slots // ---------------------------------------------- -void PortModel::when_portGroupDataChanged(PortGroup* portGroup) +void PortModel::when_portGroupDataChanged(PortGroup* portGroup, int portId) { QModelIndex index; @@ -266,7 +278,7 @@ void PortModel::when_portGroupDataChanged(PortGroup* portGroup) qDebug("when_portGroupDataChanged idx = %d", pgl->mPortGroups.indexOf(portGroup)); index = createIndex(pgl->mPortGroups.indexOf(portGroup), 0, - (portGroup->id() << 16) | 0xFFFF); + (portGroup->id() << 16) | portId); emit dataChanged(index, index); } diff --git a/client/portmodel.h b/client/portmodel.h index b68acdc..de2b140 100644 --- a/client/portmodel.h +++ b/client/portmodel.h @@ -32,7 +32,7 @@ class PortModel : public QAbstractItemModel private slots: - void when_portGroupDataChanged(PortGroup *portGroup); + void when_portGroupDataChanged(PortGroup *portGroup, int portId); void portGroupAboutToBeAppended(); void portGroupAppended(); diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 9961e12..6d77945 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -67,13 +67,15 @@ void PortStatsModel::getDomainIndexes(const QModelIndex &index, QVariant PortStatsModel::data(const QModelIndex &index, int role) const { uint pgidx, pidx; + int row; // Check for a valid index if (!index.isValid()) return QVariant(); // Check for row/column limits - if (index.row() >= e_STAT_MAX) + row = index.row(); + if (row >= e_STAT_MAX) return QVariant(); if (numPorts.isEmpty()) @@ -91,8 +93,19 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx].getStats(); - switch(index.row()) + switch(row) { + // States + case e_LINK_STATE: + return LinkStateName.at(stats.state().link_state()); + + case e_TRANSMIT_STATE: + return BoolStateName.at(stats.state().is_transmit_on()); + + case e_CAPTURE_STATE: + return BoolStateName.at(stats.state().is_capture_on()); + + // Statistics case e_STAT_FRAMES_RCVD: return stats.rx_pkts(); @@ -136,6 +149,15 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const return 0; } } + else if (role == Qt::TextAlignmentRole) + { + if (row >= e_STATE_START && row <= e_STATE_END) + return Qt::AlignHCenter; + else if (row >= e_STATISTICS_START && row <= e_STATISTICS_END) + return Qt::AlignRight; + else + return QVariant(); + } else return QVariant(); diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h index de1c585..02f02dd 100644 --- a/client/portstatsmodel.h +++ b/client/portstatsmodel.h @@ -5,7 +5,19 @@ #include typedef enum { - e_STAT_FRAMES_RCVD = 0, + // State + e_STATE_START = 0, + + e_LINK_STATE = e_STATE_START, + e_TRANSMIT_STATE, + e_CAPTURE_STATE, + + e_STATE_END = e_CAPTURE_STATE, + + // Statistics + e_STATISTICS_START, + + e_STAT_FRAMES_RCVD = e_STATISTICS_START, e_STAT_FRAMES_SENT, e_STAT_FRAME_SEND_RATE, e_STAT_FRAME_RECV_RATE, @@ -19,10 +31,17 @@ typedef enum { e_STAT_BYTES_RCVD_NIC, e_STAT_BYTES_SENT_NIC, #endif + + e_STATISTICS_END = e_STAT_BYTE_RECV_RATE, + e_STAT_MAX } PortStat; static QStringList PortStatName = (QStringList() + << "Link State" + << "Transmit State" + << "Capture State" + << "Frames Received" << "Frames Sent" << "Frame Send Rate (fps)" @@ -39,6 +58,17 @@ static QStringList PortStatName = (QStringList() #endif ); +static QStringList LinkStateName = (QStringList() + << "Unknown" + << "Down" + << "Up" +); + +static QStringList BoolStateName = (QStringList() + << "Off" + << "On" +); + class PortGroupList; class PortStatsModel : public QAbstractTableModel diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 8b75b65..7d9bbc4 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -36,6 +36,9 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) this, SLOT(when_portModel_dataChanged(const QModelIndex&, const QModelIndex&))); + connect(plm->getPortModel(), SIGNAL(modelReset()), + SLOT(when_portModel_reset())); + connect( tvPortList->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(when_portView_currentChanged(const QModelIndex&, @@ -139,7 +142,11 @@ void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft, { updatePortViewActions(tvPortList->currentIndex()); } - +} + +void PortsWindow::when_portModel_reset() +{ + when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex()); } #if 0 diff --git a/client/portswindow.h b/client/portswindow.h index a5bc562..b291f91 100644 --- a/client/portswindow.h +++ b/client/portswindow.h @@ -40,6 +40,7 @@ private slots: void when_streamView_selectionChanged(); void when_portModel_dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); + void when_portModel_reset(); void on_pbApply_clicked(); diff --git a/client/portswindow.ui b/client/portswindow.ui index b58c356..1ed9485 100644 --- a/client/portswindow.ui +++ b/client/portswindow.ui @@ -6,7 +6,7 @@ 0 0 689 - 389 + 254 @@ -28,10 +28,28 @@ - 1 + 0 + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + 6 + @@ -118,11 +136,32 @@ Control + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + Qt::ActionsContextMenu + + QFrame::NoFrame + + + 0 + QAbstractItemView::ExtendedSelection diff --git a/common/protocol.proto b/common/protocol.proto index 1f3c0a5..6557dbb 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -128,7 +128,6 @@ message Port { optional string name = 2; optional string description = 3; optional bool is_enabled = 4; - optional bool is_oper_up = 5; optional bool is_exclusive_control = 6; } @@ -149,9 +148,24 @@ message CaptureBufferList { repeated CaptureBuffer list = 1; } +enum LinkState { + LinkStateUnknown = 0; + LinkStateDown = 1; + LinkStateUp = 2; +} + +message PortState { + optional LinkState link_state = 1 [default = LinkStateUnknown]; + optional bool is_transmit_on = 2 [default = false]; + optional bool is_capture_on = 3 [default = false]; +} + message PortStats { + required PortId port_id = 1; + optional PortState state = 2; + optional uint64 rx_pkts = 11; optional uint64 rx_bytes = 12; optional uint64 rx_pkts_nic = 13; diff --git a/server/myservice.cpp b/server/myservice.cpp index cb9a2db..54b0895 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -68,6 +68,20 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) this->dev = dev; +#ifdef Q_OS_WIN32 + adapter = PacketOpenAdapter(dev->name); + if (!adapter) + qFatal("Unable to open adapter %s", dev->name); + oidData = (PPACKET_OID_DATA) malloc(sizeof(PACKET_OID_DATA) + sizeof(uint)); + if (oidData) + { + memset(oidData, 0, sizeof(PACKET_OID_DATA) + sizeof(uint)); + oidData->Length=sizeof(uint); + } + else + qFatal("failed to alloc oidData"); +#endif + /* * Get 2 device handles - one for rx and one for tx. If we use only * one handle for both rx and tx anythin that we tx using the single @@ -131,12 +145,13 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) if (dev->description) d.set_description(dev->description); d.set_is_enabled(true); //! \todo (LOW) admin enable/disable of port - d.set_is_oper_up(true); //! \todo (HIGH) oper up/down of port d.set_is_exclusive_control(false); //! \todo (HIGH) port exclusive control memset((void*) &stats, 0, sizeof(stats)); resetStats(); + linkState = OstProto::LinkStateUnknown; + // We'll create sendqueue later when required sendQueueList.clear(); returnToQIdx = -1; @@ -149,6 +164,35 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev) monitorTx.start(); } +void PortInfo::updateLinkState() +{ +#ifdef Q_OS_WIN32 + OstProto::LinkState newLinkState + = OstProto::LinkStateUnknown; + + memset(oidData, 0, sizeof(PACKET_OID_DATA) + sizeof(uint)); + oidData->Oid = OID_GEN_MEDIA_CONNECT_STATUS; + oidData->Length = sizeof(uint); + if (PacketRequest(adapter, 0, oidData)) + { + uint state; + + if (oidData->Length == sizeof(state)) + { + memcpy((void*)&state, (void*)oidData->Data, oidData->Length); + if (state == 0) + newLinkState = OstProto::LinkStateUp; + else if (state == 1) + newLinkState = OstProto::LinkStateDown; + } + } + + linkState = newLinkState; +#elif defined(Q_OS_LINUX) + //! \todo (HI) implement link state for linux - get from /proc maybe? +#endif +} + void PortInfo::update() { uchar pktBuf[2000]; @@ -211,6 +255,9 @@ void PortInfo::update() { int len; + /*! \todo (HIGH) if pkt contents do not change across + pkts then don't call makePacket(), rather reuse the + previous */ len = streamList[i]->makePacket(pktBuf, sizeof(pktBuf), j * numPackets + k); if (len > 0) @@ -722,55 +769,60 @@ PortInfo::PortCapture::~PortCapture() void PortInfo::PortCapture::run() { int ret; + char errbuf[PCAP_ERRBUF_SIZE]; + capHandle = pcap_open_live(port->dev->name, 65535, + PCAP_OPENFLAG_PROMISCUOUS, 1000 /* ms */, errbuf); if (capHandle == NULL) { - char errbuf[PCAP_ERRBUF_SIZE]; - - capHandle = pcap_open_live(port->dev->name, 65535, - PCAP_OPENFLAG_PROMISCUOUS, -1, errbuf); - if (capHandle == NULL) - { - qDebug("Error opening port %s: %s\n", - port->dev->name, pcap_geterr(capHandle)); - } + qDebug("Error opening port %s: %s\n", + port->dev->name, pcap_geterr(capHandle)); + return; } + if (!capFile.isOpen()) { if (!capFile.open()) qFatal("Unable to open temp cap file"); + return; } qDebug("cap file = %s", capFile.fileName().toAscii().constData()); dumpHandle = pcap_dump_open(capHandle, capFile.fileName().toAscii().constData()); - ret = pcap_loop(capHandle, -1, pcap_dump, (uchar*) dumpHandle); - switch (ret) + m_stop = 0; + while (m_stop == 0) { - case -2: - qDebug("%s: breakloop called %d", __PRETTY_FUNCTION__, ret); - break; + struct pcap_pkthdr *hdr; + const uchar *data; - case -1: - case 0: - qFatal("%s: unexpected break from loop (%d): %s", - __PRETTY_FUNCTION__, ret, pcap_geterr(capHandle)); - break; - default: - qFatal("%s: Unexpected return value %d", __PRETTY_FUNCTION__, ret); + ret = pcap_next_ex(capHandle, &hdr, &data); + switch (ret) + { + case 1: + pcap_dump((uchar*) dumpHandle, hdr, data); + case 0: + continue; + case -1: + qWarning("%s: error reading packet (%d): %s", + __PRETTY_FUNCTION__, ret, pcap_geterr(capHandle)); + break; + case -2: + default: + qFatal("%s: Unexpected return value %d", __PRETTY_FUNCTION__, ret); + } } + m_stop = 0; + pcap_dump_close(dumpHandle); + pcap_close(capHandle); + dumpHandle = NULL; + capHandle = NULL; } void PortInfo::PortCapture::stop() { - pcap_breakloop(capHandle); - if (dumpHandle) - { - pcap_dump_flush(dumpHandle); - pcap_dump_close(dumpHandle); - dumpHandle = NULL; - } + m_stop = 1; } QFile* PortInfo::PortCapture::captureFile() @@ -1200,6 +1252,7 @@ const ::OstProto::PortIdList* request, { uint portidx; ::OstProto::PortStats *s; + OstProto::PortState *st; portidx = request->port_id(i).id(); if (portidx >= numPorts) @@ -1216,6 +1269,13 @@ const ::OstProto::PortIdList* request, } #endif + portInfo[portidx]->updateLinkState(); + + st = s->mutable_state(); + st->set_link_state(portInfo[portidx]->linkState); + st->set_is_transmit_on(portInfo[portidx]->transmitter.isRunning()); + st->set_is_capture_on(portInfo[portidx]->capturer.isRunning()); + s->set_rx_pkts(portInfo[portidx]->stats.rxPkts - portInfo[portidx]->epochStats.rxPkts); s->set_rx_bytes(portInfo[portidx]->stats.rxBytes - diff --git a/server/myservice.h b/server/myservice.h index fb55283..ebd1db1 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -22,6 +22,10 @@ #ifdef Q_OS_WIN32 #include #endif + +#ifdef Q_OS_WIN32 +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#endif #define MAX_PKT_HDR_SIZE 1536 #define MAX_STREAM_NAME_SIZE 64 @@ -29,6 +33,7 @@ //! 7 byte Preamble + 1 byte SFD + 4 byte FCS #define ETH_FRAME_HDR_SIZE 12 + class MyService; class StreamInfo : public StreamBase @@ -99,6 +104,7 @@ class PortInfo friend class PortInfo; PortInfo *port; + int m_stop; pcap_t *capHandle; pcap_dumper_t *dumpHandle; QTemporaryFile capFile; @@ -110,8 +116,14 @@ class PortInfo void stop(); QFile* captureFile(); }; + +#ifdef Q_OS_WIN32 + LPADAPTER adapter; + PPACKET_OID_DATA oidData; +#endif OstProto::Port d; + OstProto::LinkState linkState; struct PortStats { @@ -167,6 +179,7 @@ class PortInfo public: PortInfo(uint id, pcap_if_t *dev); uint id() { return d.port_id().id(); } + void updateLinkState(); bool isDirty() { return isSendQueueDirty; } void setDirty(bool dirty) { isSendQueueDirty = dirty; } void update(); From 17792b825357982fa7477aab9033dc1b2b1b80ea Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Fri, 13 Nov 2009 16:00:57 +0000 Subject: [PATCH 29/98] Refactoring, optimization et. al. --------------------------------- - StreamConfigDialog: Valid subsequent protocol choices for a particular protocol in the simple protocol selection widget is no longer hardcoded - ProtocolManager is queried for validitity of each pair of possible protocols; signal-slot connections are made accordingly. This refactoring makes it easier to add a protocol to the simple protocol selection widget - ProtocolManager: populates and maintains a database of valid 'neighbour protocols' and implements a method - isValidNeighbour() to query the same for a pair of protocols - AbstractProtocol: new method protocolIdType() introduced to build the above database (in conjunction with the existing method protocolId(ProtocolIdType)); default implementation returns ProtocolIdNone - Protocols which include a valid/supported ProtocolIdType (eth/llc/ip) reimplement protocolIdType() to return the apporpirate ProtocolIdType. These are viz. - combo - eth - llc - snap - ip - Speed optimization while populating streamqueues if the protocolFrameValue/Size() does not vary across packets - AbstractProtocol: new methods to support the above optimization - isProtocolFrameValueVariable() - isProtocolFrameSizeVariable() - isProtocolFramePayloadValueVariable() - isProtocolFramePayloadSizeVariable() (each of the default implementations returns false indicating that the protocol frame value or frame size is fixed and not variable) - Protocols which support variable values/size (list follows) reimplement the above methods appropriately - combo - mac - dot3 - ip4 - tcp - udp - payload - StreamInfo::makePacket() moved to base class as StreamBase::frameValue() - StreamBase: all 'get' accessor functions made 'const' - class ProtocolManager: while registering a protocol, no need to pass the protocol name; ProtocolManager finds it out internally by using the protocol's shortName() method Fixes ----- - Fixed issue with port capture not starting the first time 'start capture' was clicked --- client/streamconfigdialog.cpp | 104 ++++++++++++++++++---------------- common/abstractprotocol.cpp | 50 +++++++++++++++- common/abstractprotocol.h | 7 +++ common/comboprotocol.h | 19 +++++++ common/dot3.cpp | 4 ++ common/dot3.h | 2 + common/eth2.cpp | 5 ++ common/eth2.h | 2 + common/ip4.cpp | 14 +++++ common/ip4.h | 3 + common/llc.cpp | 5 ++ common/llc.h | 2 + common/mac.cpp | 9 +++ common/mac.h | 2 + common/payload.cpp | 17 ++++++ common/payload.h | 3 + common/protocolmanager.cpp | 69 ++++++++++++++++------ common/protocolmanager.h | 9 ++- common/snap.cpp | 5 ++ common/snap.h | 2 + common/streambase.cpp | 87 +++++++++++++++++++++++----- common/streambase.h | 29 +++++----- common/tcp.cpp | 7 +++ common/tcp.h | 2 + common/udp.cpp | 7 +++ common/udp.h | 2 + server/myservice.cpp | 56 ++++++------------ server/myservice.h | 3 - 28 files changed, 387 insertions(+), 139 deletions(-) diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 30649b3..5201099 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -43,60 +43,60 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // Time to play match the signals and slots! - // If L1/FT = None, force subsequent protocol level(s) also to None - connect(rbL1None, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool))); + // If L1/L2(FT)/L3 = None, force subsequent protocol level(s) also to None + connect(rbL1None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); + connect(rbL3None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); - // Enable/Disable L3 Protocol Choices for FT Ethernet2 - connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); - connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); - - // Force L3 = None if FT = 802.3 Raw - connect(rbFt802Dot3Raw, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool))); - connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); - - // Force L3 = None if FT = 802.3 LLC (to ensure a valid L3 is selected) - connect(rbFt802Dot3Llc, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); - - // Enable/Disable L3 Protocol Choices for FT 802Dot3Llc - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); - connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); - - // Enable/Disable L3 Protocol Choices for FT 802.3 LLC SNAP - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); - connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); - - // Force L3 = Other if FT = Other + // If L1/L2(FT)/L3/L4 = Other, force subsequent protocol to Other and + // disable the subsequent protocol group as well + connect(rbL1Other, SIGNAL(toggled(bool)), rbFtOther, SLOT(setChecked(bool))); + connect(rbL1Other, SIGNAL(toggled(bool)), gbFrameType, SLOT(setDisabled(bool))); connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool))); connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool))); - - // If L3 = None, force subsequent protocol level also to None - connect(rbL3None, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool))); - - // Enable/Disable L4 Protocol Choices for L3 Protocol IPv4 - connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setEnabled(bool))); - connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setEnabled(bool))); - connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setEnabled(bool))); - connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setEnabled(bool))); - - // Enable/Disable L4 Protocol Choices for L3 Protocol ARP - connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool))); - connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool))); - connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool))); - connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool))); - - // Force L4 Protocol = None if L3 Protocol is set to ARP - connect(rbL3Arp, SIGNAL(clicked(bool)), rbL4None, SLOT(click())); - - // Force L4 = Other if L3 = Other connect(rbL3Other, SIGNAL(toggled(bool)), rbL4Other, SLOT(setChecked(bool))); connect(rbL3Other, SIGNAL(toggled(bool)), gbL4Proto, SLOT(setDisabled(bool))); - - // Force Payload = Other if L4 = Other connect(rbL4Other, SIGNAL(toggled(bool)), rbPayloadOther, SLOT(setChecked(bool))); connect(rbL4Other, SIGNAL(toggled(bool)), gbPayloadProto, SLOT(setDisabled(bool))); + // Setup valid subsequent protocols for L2 and L3 protocols + for (int i = ProtoL2; i <= ProtoL3; i++) + { + foreach(QAbstractButton *btn1, bgProto[i]->buttons()) + { + int id1 = bgProto[i]->id(btn1); + + if (id1 != ButtonIdNone && id1 != ButtonIdOther) + { + int validProtocolCount = 0; + + foreach(QAbstractButton *btn2, bgProto[i+1]->buttons()) + { + int id2 = bgProto[i+1]->id(btn2); + + if (id2 != ButtonIdNone && id2 != ButtonIdOther) + { + if (OstProtocolManager.isValidNeighbour(id1, id2)) + { + connect(btn1, SIGNAL(toggled(bool)), + btn2, SLOT(setEnabled(bool))); + validProtocolCount++; + } + else + connect(btn1, SIGNAL(toggled(bool)), + btn2, SLOT(setDisabled(bool))); + } + } + + // If btn1 has no subsequent valid protocols, + // force subsequent Protocol to 'None' + if (validProtocolCount == 0) + connect(btn1, SIGNAL(clicked(bool)), + bgProto[i+1]->button(ButtonIdNone), SLOT(click())); + } + } + } + mpAvailableProtocolsModel = new QStringListModel( OstProtocolManager.protocolDatabase(), this); lvAllProtocols->setModel(mpAvailableProtocolsModel); @@ -729,8 +729,16 @@ void StreamConfigDialog::updateSelectProtocolsSimpleWidget() id = _iter->next()->protocolNumber(); btn = bgProto[i]->button(id); - if (btn && btn->isEnabled()) - btn->click(); + if (btn) + { + if (btn->isEnabled()) + btn->click(); + else + { + btn->setChecked(true); + __updateProtocol(i, id); + } + } else { switch (i) diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 10678fb..3dd58ae 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -44,7 +44,7 @@ AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream, quint32 AbstractProtocol::protocolNumber() const { - qDebug("Something wrong!!!"); + qFatal("Something wrong!!!"); return 0xFFFFFFFF; } @@ -193,6 +193,11 @@ bool AbstractProtocol::setFieldData(int index, const QVariant &value, return false; } +AbstractProtocol::ProtocolIdType AbstractProtocol::protocolIdType() const +{ + return ProtocolIdNone; +} + quint32 AbstractProtocol::protocolId(ProtocolIdType type) const { return 0; @@ -360,6 +365,49 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) return proto; } +bool AbstractProtocol::isProtocolFrameValueVariable() const +{ + return false; +} + +bool AbstractProtocol::isProtocolFrameSizeVariable() const +{ + return false; +} + +bool AbstractProtocol::isProtocolFramePayloadValueVariable() const +{ + AbstractProtocol *p = next; + + while (p) + { + if (p->isProtocolFrameValueVariable()) + return true; + p = p->next; + } + if (parent && parent->isProtocolFramePayloadValueVariable()) + return true; + + return false; +} + +bool AbstractProtocol::isProtocolFramePayloadSizeVariable() const +{ + AbstractProtocol *p = next; + + while (p) + { + if (p->isProtocolFrameSizeVariable()) + return true; + p = p->next; + } + if (parent && parent->isProtocolFramePayloadSizeVariable()) + return true; + + return false; +} + + /*! \note If a subclass uses protocolFrameCksum() from within fieldData() to derive a cksum field, it MUST handle and return the 'FieldBitSize' diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index 3e1dc12..ccf1b12 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -56,6 +56,7 @@ public: }; enum ProtocolIdType { + ProtocolIdNone, ProtocolIdLlc, ProtocolIdEth, ProtocolIdIp, @@ -82,6 +83,7 @@ public: virtual QString name() const; virtual QString shortName() const; + virtual ProtocolIdType protocolIdType() const; virtual quint32 protocolId(ProtocolIdType type) const; quint32 payloadProtocolId(ProtocolIdType type) const; @@ -101,6 +103,11 @@ public: int protocolFrameOffset(int streamIndex = 0) const; int protocolFramePayloadSize(int streamIndex = 0) const; + virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameSizeVariable() const; + bool isProtocolFramePayloadValueVariable() const; + bool isProtocolFramePayloadSizeVariable() const; + virtual quint32 protocolFrameCksum(int streamIndex = 0, CksumType cksumType = CksumIp) const; quint32 protocolFrameHeaderCksum(int streamIndex = 0, diff --git a/common/comboprotocol.h b/common/comboprotocol.h index 34cba86..dbfd682 100644 --- a/common/comboprotocol.h +++ b/common/comboprotocol.h @@ -84,6 +84,11 @@ public: return protoA->shortName() + "/" + protoB->shortName(); } + virtual ProtocolIdType protocolIdType() const + { + return protoB->protocolIdType(); + } + virtual quint32 protocolId(ProtocolIdType type) const { return protoA->protocolId(type); @@ -133,7 +138,21 @@ public: virtual int protocolFrameSize() const; int protocolFrameOffset() const; int protocolFramePayloadSize() const; +#endif + virtual bool isProtocolFrameValueVariable() const + { + return (protoA->isProtocolFrameValueVariable() + || protoB->isProtocolFrameValueVariable()); + } + + virtual bool isProtocolFrameSizeVariable() const + { + return (protoA->isProtocolFrameSizeVariable() + || protoB->isProtocolFrameSizeVariable()); + } + +#if 0 virtual quint32 protocolFrameCksum(int streamIndex = 0, CksumType cksumType = CksumIp) const; quint32 protocolFrameHeaderCksum(int streamIndex = 0, diff --git a/common/dot3.cpp b/common/dot3.cpp index 0a88d50..ac2a878 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -119,6 +119,10 @@ bool Dot3Protocol::setFieldData(int index, const QVariant &value, return false; } +bool Dot3Protocol::isProtocolFrameValueVariable() const +{ + return isProtocolFramePayloadSizeVariable(); +} QWidget* Dot3Protocol::configWidget() { diff --git a/common/dot3.h b/common/dot3.h index def1031..9e0e8c1 100644 --- a/common/dot3.h +++ b/common/dot3.h @@ -46,6 +46,8 @@ public: virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual bool isProtocolFrameValueVariable() const; + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/common/eth2.cpp b/common/eth2.cpp index 7a6f7b5..0028b51 100644 --- a/common/eth2.cpp +++ b/common/eth2.cpp @@ -54,6 +54,11 @@ QString Eth2Protocol::shortName() const return QString("Eth II"); } +AbstractProtocol::ProtocolIdType Eth2Protocol::protocolIdType() const +{ + return ProtocolIdEth; +} + int Eth2Protocol::fieldCount() const { return eth2_fieldCount; diff --git a/common/eth2.h b/common/eth2.h index 0555d65..fcf6b7d 100644 --- a/common/eth2.h +++ b/common/eth2.h @@ -39,6 +39,8 @@ public: virtual QString name() const; virtual QString shortName() const; + virtual ProtocolIdType protocolIdType() const; + virtual int fieldCount() const; virtual QVariant fieldData(int index, FieldAttrib attrib, diff --git a/common/ip4.cpp b/common/ip4.cpp index c929872..4c28bfb 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -94,6 +94,11 @@ QString Ip4Protocol::shortName() const return QString("IPv4"); } +AbstractProtocol::ProtocolIdType Ip4Protocol::protocolIdType() const +{ + return ProtocolIdIp; +} + quint32 Ip4Protocol::protocolId(ProtocolIdType type) const { switch(type) @@ -572,6 +577,15 @@ bool Ip4Protocol::setFieldData(int index, const QVariant &value, return isOk; } +bool Ip4Protocol::isProtocolFrameValueVariable() const +{ + if ((data.src_ip_mode() != OstProto::Ip4::e_im_fixed) + || (data.dst_ip_mode() != OstProto::Ip4::e_im_fixed)) + return true; + else + return false; +} + quint32 Ip4Protocol::protocolFrameCksum(int streamIndex, CksumType cksumType) const { diff --git a/common/ip4.h b/common/ip4.h index e378755..34f4c37 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -71,6 +71,7 @@ public: virtual QString name() const; virtual QString shortName() const; + virtual ProtocolIdType protocolIdType() const; virtual quint32 protocolId(ProtocolIdType type) const; virtual int fieldCount() const; @@ -82,6 +83,8 @@ public: virtual quint32 protocolFrameCksum(int streamIndex = 0, CksumType cksumType = CksumIp) const; + virtual bool isProtocolFrameValueVariable() const; + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/common/llc.cpp b/common/llc.cpp index e949e08..25cc307 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -54,6 +54,11 @@ QString LlcProtocol::shortName() const return QString("LLC"); } +AbstractProtocol::ProtocolIdType LlcProtocol::protocolIdType() const +{ + return ProtocolIdLlc; +} + int LlcProtocol::fieldCount() const { return llc_fieldCount; diff --git a/common/llc.h b/common/llc.h index 3555e92..741f493 100644 --- a/common/llc.h +++ b/common/llc.h @@ -44,6 +44,8 @@ public: virtual QString name() const; virtual QString shortName() const; + virtual ProtocolIdType protocolIdType() const; + virtual int fieldCount() const; virtual QVariant fieldData(int index, FieldAttrib attrib, diff --git a/common/mac.cpp b/common/mac.cpp index 8e468a3..1d7ed87 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -239,6 +239,15 @@ bool MacProtocol::setFieldData(int index, const QVariant &value, return false; } +bool MacProtocol::isProtocolFrameValueVariable() const +{ + if ((data.dst_mac_mode() != OstProto::Mac::e_mm_fixed) || + (data.src_mac_mode() != OstProto::Mac::e_mm_fixed)) + return true; + else + return false; +} + QWidget* MacProtocol::configWidget() { diff --git a/common/mac.h b/common/mac.h index a493bd6..b6165b7 100644 --- a/common/mac.h +++ b/common/mac.h @@ -61,6 +61,8 @@ public: virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual bool isProtocolFrameValueVariable() const; + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/common/payload.cpp b/common/payload.cpp index 1125b73..4bbca2e 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -187,6 +187,23 @@ bool PayloadProtocol::setFieldData(int index, const QVariant &value, return false; } +bool PayloadProtocol::isProtocolFrameValueVariable() const +{ + if (isProtocolFrameSizeVariable() + || data.pattern_mode() == OstProto::Payload::e_dp_random) + return true; + else + return false; +} + +bool PayloadProtocol::isProtocolFrameSizeVariable() const +{ + if (mpStream->lenMode() == StreamBase::e_fl_fixed) + return false; + else + return true; +} + QWidget* PayloadProtocol::configWidget() { diff --git a/common/payload.h b/common/payload.h index c2d5f4d..9437a8c 100644 --- a/common/payload.h +++ b/common/payload.h @@ -54,6 +54,9 @@ public: virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameSizeVariable() const; + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 56c1912..8a9547d 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -24,42 +24,69 @@ ProtocolManager::ProtocolManager() themselves (once this is done remove the #includes for all the protocols) */ registerProtocol(OstProto::Protocol::kMacFieldNumber, - QString("mac"), (void*) MacProtocol::createInstance); + (void*) MacProtocol::createInstance); registerProtocol(OstProto::Protocol::kPayloadFieldNumber, - QString("payload"), (void*) PayloadProtocol::createInstance); + (void*) PayloadProtocol::createInstance); registerProtocol(OstProto::Protocol::kEth2FieldNumber, - QString("eth2"), (void*) Eth2Protocol::createInstance); + (void*) Eth2Protocol::createInstance); registerProtocol(OstProto::Protocol::kDot3FieldNumber, - QString("dot3"), (void*) Dot3Protocol::createInstance); + (void*) Dot3Protocol::createInstance); registerProtocol(OstProto::Protocol::kLlcFieldNumber, - QString("llc"), (void*) LlcProtocol::createInstance); + (void*) LlcProtocol::createInstance); registerProtocol(OstProto::Protocol::kSnapFieldNumber, - QString("snap"), (void*) SnapProtocol::createInstance); + (void*) SnapProtocol::createInstance); registerProtocol(OstProto::Protocol::kDot2LlcFieldNumber, - QString("dot2Llc"), (void*) Dot2LlcProtocol::createInstance); + (void*) Dot2LlcProtocol::createInstance); registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber, - QString("dot2Snap"), (void*) Dot2SnapProtocol::createInstance); + (void*) Dot2SnapProtocol::createInstance); registerProtocol(OstProto::Protocol::kSvlanFieldNumber, - QString("svlan"), (void*) VlanProtocol::createInstance); + (void*) SVlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanFieldNumber, - QString("vlan"), (void*) VlanProtocol::createInstance); + (void*) VlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanStackFieldNumber, - QString("vlanstack"), (void*) VlanStackProtocol::createInstance); + (void*) VlanStackProtocol::createInstance); registerProtocol(OstProto::Protocol::kIp4FieldNumber, - QString("ip4"), (void*) Ip4Protocol::createInstance); + (void*) Ip4Protocol::createInstance); registerProtocol(OstProto::Protocol::kTcpFieldNumber, - QString("tcp"), (void*) TcpProtocol::createInstance); + (void*) TcpProtocol::createInstance); registerProtocol(OstProto::Protocol::kUdpFieldNumber, - QString("udp"), (void*) UdpProtocol::createInstance); + (void*) UdpProtocol::createInstance); + + populateNeighbourProtocols(); } -void ProtocolManager::registerProtocol(int protoNumber, QString protoName, +void ProtocolManager::registerProtocol(int protoNumber, void *protoInstanceCreator) { + AbstractProtocol *p; + //! \todo (MED) validate incoming params for duplicates with existing - nameToNumberMap.insert(protoName, protoNumber); - numberToNameMap.insert(protoNumber, protoName); + factory.insert(protoNumber, protoInstanceCreator); + + p = createProtocol(protoNumber, NULL); + protocolList.append(p); + + numberToNameMap.insert(protoNumber, p->shortName()); + nameToNumberMap.insert(p->shortName(), protoNumber); +} + +void ProtocolManager::populateNeighbourProtocols() +{ + neighbourProtocols.clear(); + + foreach(AbstractProtocol *p, protocolList) + { + if (p->protocolIdType() != AbstractProtocol::ProtocolIdNone) + { + foreach(AbstractProtocol *q, protocolList) + { + if (q->protocolId(p->protocolIdType())) + neighbourProtocols.insert( + p->protocolNumber(), q->protocolNumber()); + } + } + } } AbstractProtocol* ProtocolManager::createProtocol(int protoNumber, @@ -84,6 +111,14 @@ AbstractProtocol* ProtocolManager::createProtocol(QString protoName, return createProtocol(nameToNumberMap.value(protoName), stream, parent); } +bool ProtocolManager::isValidNeighbour(int protoPrefix, int protoSuffix) +{ + if (neighbourProtocols.contains(protoPrefix, protoSuffix)) + return true; + else + return false; +} + QStringList ProtocolManager::protocolDatabase() { return numberToNameMap.values(); diff --git a/common/protocolmanager.h b/common/protocolmanager.h index 985253b..c619099 100644 --- a/common/protocolmanager.h +++ b/common/protocolmanager.h @@ -11,19 +11,24 @@ class ProtocolManager { QMap numberToNameMap; QMap nameToNumberMap; + QMultiMap neighbourProtocols; QMap factory; + QList protocolList; + + void populateNeighbourProtocols(); public: ProtocolManager(); - void registerProtocol(int protoNumber, QString protoName, - void *protoCreator); + void registerProtocol(int protoNumber, void *protoInstanceCreator); AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream, AbstractProtocol *parent = 0); AbstractProtocol* createProtocol(QString protoName, StreamBase *stream, AbstractProtocol *parent = 0); + bool isValidNeighbour(int protoPrefix, int protoSuffix); + QStringList protocolDatabase(); }; diff --git a/common/snap.cpp b/common/snap.cpp index 3dfd7e4..0f7d477 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -54,6 +54,11 @@ QString SnapProtocol::shortName() const return QString("SNAP"); } +AbstractProtocol::ProtocolIdType SnapProtocol::protocolIdType() const +{ + return ProtocolIdEth; +} + quint32 SnapProtocol::protocolId(ProtocolIdType type) const { switch(type) diff --git a/common/snap.h b/common/snap.h index a2531f6..c4018ad 100644 --- a/common/snap.h +++ b/common/snap.h @@ -39,6 +39,8 @@ public: virtual QString name() const; virtual QString shortName() const; + + virtual ProtocolIdType protocolIdType() const; virtual quint32 protocolId(ProtocolIdType type) const; virtual int fieldCount() const; diff --git a/common/streambase.cpp b/common/streambase.cpp index 1ed8d7f..5bd2dcb 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -20,11 +20,13 @@ StreamBase::StreamBase() : iter = createProtocolListIterator(); // By default newly created streams have the mac and payload protocols - proto = OstProtocolManager.createProtocol("mac", this); + proto = OstProtocolManager.createProtocol( + OstProto::Protocol::kMacFieldNumber, this); iter->insert(proto); qDebug("stream: mac = %p", proto); - proto = OstProtocolManager.createProtocol("payload", this); + proto = OstProtocolManager.createProtocol( + OstProto::Protocol::kPayloadFieldNumber, this); iter->insert(proto); qDebug("stream: payload = %p", proto); @@ -104,7 +106,7 @@ void StreamBase::setFrameProtocol(ProtocolList protocolList) } #endif -ProtocolListIterator* StreamBase::createProtocolListIterator() +ProtocolListIterator* StreamBase::createProtocolListIterator() const { return new ProtocolListIterator(*currentFrameProtocols); } @@ -158,7 +160,7 @@ bool StreamBase::setName(QString name) return true; } -StreamBase::FrameLengthMode StreamBase::lenMode() +StreamBase::FrameLengthMode StreamBase::lenMode() const { return (StreamBase::FrameLengthMode) mCore->len_mode(); } @@ -169,7 +171,7 @@ bool StreamBase::setLenMode(FrameLengthMode lenMode) return true; } -quint16 StreamBase::frameLen(int streamIndex) +quint16 StreamBase::frameLen(int streamIndex) const { int pktLen; @@ -211,7 +213,7 @@ bool StreamBase::setFrameLen(quint16 frameLen) return true; } -quint16 StreamBase::frameLenMin() +quint16 StreamBase::frameLenMin() const { return mCore->frame_len_min(); } @@ -222,7 +224,7 @@ bool StreamBase::setFrameLenMin(quint16 frameLenMin) return true; } -quint16 StreamBase::frameLenMax() +quint16 StreamBase::frameLenMax() const { return mCore->frame_len_max(); } @@ -233,17 +235,18 @@ bool StreamBase::setFrameLenMax(quint16 frameLenMax) return true; } -StreamBase::SendUnit StreamBase::sendUnit() +StreamBase::SendUnit StreamBase::sendUnit() const { return (StreamBase::SendUnit) mControl->unit(); } + bool StreamBase::setSendUnit(SendUnit sendUnit) { mControl->set_unit((OstProto::StreamControl::SendUnit) sendUnit); return true; } -StreamBase::SendMode StreamBase::sendMode() +StreamBase::SendMode StreamBase::sendMode() const { return (StreamBase::SendMode) mControl->mode(); } @@ -255,7 +258,7 @@ bool StreamBase::setSendMode(SendMode sendMode) return true; } -StreamBase::NextWhat StreamBase::nextWhat() +StreamBase::NextWhat StreamBase::nextWhat() const { return (StreamBase::NextWhat) mControl->next(); } @@ -266,7 +269,7 @@ bool StreamBase::setNextWhat(NextWhat nextWhat) return true; } -quint32 StreamBase::numPackets() +quint32 StreamBase::numPackets() const { return (quint32) mControl->num_packets(); } @@ -277,7 +280,7 @@ bool StreamBase::setNumPackets(quint32 numPackets) return true; } -quint32 StreamBase::numBursts() +quint32 StreamBase::numBursts() const { return (quint32) mControl->num_bursts(); } @@ -288,7 +291,7 @@ bool StreamBase::setNumBursts(quint32 numBursts) return true; } -quint32 StreamBase::burstSize() +quint32 StreamBase::burstSize() const { return (quint32) mControl->packets_per_burst(); } @@ -299,7 +302,7 @@ bool StreamBase::setBurstSize(quint32 packetsPerBurst) return true; } -quint32 StreamBase::packetRate() +quint32 StreamBase::packetRate() const { return (quint32) mControl->packets_per_sec(); } @@ -310,7 +313,7 @@ bool StreamBase::setPacketRate(quint32 packetsPerSec) return true; } -quint32 StreamBase::burstRate() +quint32 StreamBase::burstRate() const { return (quint32) mControl->bursts_per_sec(); } @@ -320,3 +323,57 @@ bool StreamBase::setBurstRate(quint32 burstsPerSec) mControl->set_bursts_per_sec(burstsPerSec); return true; } + +bool StreamBase::isFrameVariable() const +{ + ProtocolListIterator *iter; + + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol *proto; + + proto = iter->next(); + if (proto->isProtocolFrameValueVariable()) + goto _exit; + } + delete iter; + return false; + +_exit: + delete iter; + return true; +} + +int StreamBase::frameValue(uchar *buf, int bufMaxSize, int n) const +{ + int pktLen, len = 0; + + pktLen = frameLen(n); + + // pktLen is adjusted for CRC/FCS which will be added by the NIC + pktLen -= 4; + + if ((pktLen < 0) || (pktLen > bufMaxSize)) + return 0; + + ProtocolListIterator *iter; + + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol *proto; + QByteArray ba; + + proto = iter->next(); + ba = proto->protocolFrameValue(n); + + if (len + ba.size() < bufMaxSize) + memcpy(buf+len, ba.constData(), ba.size()); + len += ba.size(); + } + delete iter; + + return pktLen; +} + diff --git a/common/streambase.h b/common/streambase.h index 878b2d7..45f0cbb 100644 --- a/common/streambase.h +++ b/common/streambase.h @@ -26,7 +26,7 @@ public: void protoDataCopyFrom(const OstProto::Stream &stream); void protoDataCopyInto(OstProto::Stream &stream) const; - ProtocolListIterator* createProtocolListIterator(); + ProtocolListIterator* createProtocolListIterator() const; //! \todo (LOW) should we have a copy constructor?? @@ -76,41 +76,44 @@ public: bool setName(QString name) ; // Frame Length (includes FCS); - FrameLengthMode lenMode(); + FrameLengthMode lenMode() const; bool setLenMode(FrameLengthMode lenMode); - quint16 frameLen(int streamIndex = 0); + quint16 frameLen(int streamIndex = 0) const; bool setFrameLen(quint16 frameLen); - quint16 frameLenMin(); + quint16 frameLenMin() const; bool setFrameLenMin(quint16 frameLenMin); - quint16 frameLenMax(); + quint16 frameLenMax() const; bool setFrameLenMax(quint16 frameLenMax); - SendUnit sendUnit(); + SendUnit sendUnit() const; bool setSendUnit(SendUnit sendUnit); - SendMode sendMode(); + SendMode sendMode() const; bool setSendMode(SendMode sendMode); - NextWhat nextWhat(); + NextWhat nextWhat() const; bool setNextWhat(NextWhat nextWhat); - quint32 numPackets(); + quint32 numPackets() const; bool setNumPackets(quint32 numPackets); - quint32 numBursts(); + quint32 numBursts() const; bool setNumBursts(quint32 numBursts); - quint32 burstSize(); + quint32 burstSize() const; bool setBurstSize(quint32 packetsPerBurst); - quint32 packetRate(); + quint32 packetRate() const; bool setPacketRate(quint32 packetsPerSec); - quint32 burstRate(); + quint32 burstRate() const; bool setBurstRate(quint32 burstsPerSec); + + bool isFrameVariable() const; + int frameValue(uchar *buf, int bufMaxSize, int n) const; }; #endif diff --git a/common/tcp.cpp b/common/tcp.cpp index be16120..6bbc271 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -380,6 +380,13 @@ bool TcpProtocol::setFieldData(int index, const QVariant &value, return false; } +bool TcpProtocol::isProtocolFrameValueVariable() const +{ + if (data.is_override_cksum()) + return false; + else + return isProtocolFramePayloadValueVariable(); +} QWidget* TcpProtocol::configWidget() { diff --git a/common/tcp.h b/common/tcp.h index cfd43a6..72cfbf8 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -67,6 +67,8 @@ public: virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual bool isProtocolFrameValueVariable() const; + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/common/udp.cpp b/common/udp.cpp index 0d5b772..9cb74ec 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -258,6 +258,13 @@ bool UdpProtocol::setFieldData(int index, const QVariant &value, return false; } +bool UdpProtocol::isProtocolFrameValueVariable() const +{ + if (data.is_override_totlen() && data.is_override_cksum()) + return false; + else + return isProtocolFramePayloadValueVariable(); +} QWidget* UdpProtocol::configWidget() { diff --git a/common/udp.h b/common/udp.h index 278809a..663456b 100644 --- a/common/udp.h +++ b/common/udp.h @@ -54,6 +54,8 @@ public: virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual bool isProtocolFrameValueVariable() const; + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/server/myservice.cpp b/server/myservice.cpp index 54b0895..93afc8b 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -25,39 +25,6 @@ StreamInfo::~StreamInfo() { } -int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) -{ - int pktLen, len = 0; - - pktLen = frameLen(n); - - // pktLen is adjusted for CRC/FCS which will be added by the NIC - pktLen -= 4; - - if ((pktLen < 0) || (pktLen > bufMaxSize)) - return 0; - - ProtocolListIterator *iter; - - iter = createProtocolListIterator(); - while (iter->hasNext()) - { - AbstractProtocol *proto; - QByteArray ba; - - proto = iter->next(); - ba = proto->protocolFrameValue(n); - - if (len + ba.size() < bufMaxSize) - memcpy(buf+len, ba.constData(), ba.size()); - len += ba.size(); - } - delete iter; - - return pktLen; -} - - // // ------------------ PortInfo -------------------- // @@ -195,6 +162,8 @@ void PortInfo::updateLinkState() void PortInfo::update() { + int len; + bool isVariable; uchar pktBuf[2000]; pcap_pkthdr pktHdr; ost_pcap_send_queue sendQ; @@ -249,17 +218,25 @@ void PortInfo::update() numBursts, numPackets); qDebug("ibg = %ld, ipg = %ld\n", ibg, ipg); + if (streamList[i]->isFrameVariable()) + { + isVariable = true; + } + else + { + isVariable = false; + len = streamList[i]->frameValue(pktBuf, sizeof(pktBuf), 0); + } + for (int j = 0; j < numBursts; j++) { for (int k = 0; k < numPackets; k++) { - int len; - - /*! \todo (HIGH) if pkt contents do not change across - pkts then don't call makePacket(), rather reuse the - previous */ - len = streamList[i]->makePacket(pktBuf, sizeof(pktBuf), + if (isVariable) + { + len = streamList[i]->frameValue(pktBuf, sizeof(pktBuf), j * numPackets + k); + } if (len > 0) { pktHdr.caplen = pktHdr.len = len; @@ -784,7 +761,6 @@ void PortInfo::PortCapture::run() { if (!capFile.open()) qFatal("Unable to open temp cap file"); - return; } qDebug("cap file = %s", capFile.fileName().toAscii().constData()); diff --git a/server/myservice.h b/server/myservice.h index ebd1db1..bafe9b9 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -46,9 +46,6 @@ class StreamInfo : public StreamBase public: StreamInfo(); ~StreamInfo(); - -private: - int makePacket(uchar *buf, int bufMaxSize, int n); }; From 3602d24767164745bb930a1c4ca077d5e194fb05 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 14 Nov 2009 15:09:19 +0000 Subject: [PATCH 30/98] Fixes - LinkState is now updated in PortWindow as soon as a change is detected; the required minimal refactoring of the Port class usage has been done - Fixed a compiler warning in portgrouplist.cpp Others - PortStatsFilter: Ui change - added left and right arrow icons --- client/icons/arrow_left.png | Bin 0 -> 345 bytes client/ostinato.qrc | 1 + client/port.cpp | 6 ++-- client/port.h | 17 +++-------- client/portgroup.cpp | 57 ++++++++++++++++++++---------------- client/portgroup.h | 4 +-- client/portgrouplist.cpp | 27 +++++------------ client/portmodel.cpp | 41 ++++++++------------------ client/portmodel.h | 2 +- client/portstatsfilter.ui | 6 ++++ client/portstatsmodel.cpp | 2 +- client/streammodel.cpp | 2 +- 12 files changed, 71 insertions(+), 94 deletions(-) create mode 100644 client/icons/arrow_left.png diff --git a/client/icons/arrow_left.png b/client/icons/arrow_left.png new file mode 100644 index 0000000000000000000000000000000000000000..5dc696781e6135d37b5bf2e98e46fd94f020c48d GIT binary patch literal 345 zcmV-f0jBq$gGR5;6H z{Qv(y10{fofkH6I3@AO3$p*x`Nil#0jeqs;pT9Ds7{CaN1)$9r#n~kE{`~pF@bLXZ zhF?E_GyM7i!oL`P0x_8Wj$ni2F7#hzWPxfvDaI icons/arrow_down.png + icons/arrow_left.png icons/arrow_right.png icons/arrow_up.png icons/bullet_error.png diff --git a/client/port.cpp b/client/port.cpp index d7e2b4c..87f0e07 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -187,9 +187,11 @@ void Port::updateStats(OstProto::PortStats *portStats) oldState = stats.state(); stats.MergeFrom(*portStats); -#if 0 + if (oldState.link_state() != stats.state().link_state()) + { + qDebug("portstate changed"); emit portDataChanged(mPortGroupId, mPortId); -#endif + } } diff --git a/client/port.h b/client/port.h index bdafdb9..9be12ed 100644 --- a/client/port.h +++ b/client/port.h @@ -1,18 +1,17 @@ #ifndef _PORT_H #define _PORT_H -#include +#include #include #include #include "stream.h" //class StreamModel; -class Port { +class Port : public QObject { - //friend class StreamModel; + Q_OBJECT -private: static uint mAllocStreamId; OstProto::Port d; OstProto::PortStats stats; @@ -28,6 +27,7 @@ private: uint newStreamId(); void updateStreamOrdinalsFromIndex(); void reorderStreamsByOrdinals(); + public: enum AdminStatus { AdminDisable, AdminEnable }; enum ControlMode { ControlShared, ControlExclusive }; @@ -50,13 +50,6 @@ public: ControlMode controlMode() { return (d.is_exclusive_control()?ControlExclusive:ControlShared); } -#if 0 - void setName(QString &name) { d.name; } - void setName(const char* name) { mName = QString(name); } - void setDescription(QString &description) { mDescription = description; } - void setDescription(const char *description) - { mDescription = QString(description); } -#endif //void setAdminEnable(AdminStatus status) { mAdminStatus = status; } void setAlias(QString &alias) { mUserAlias = alias; } //void setExclusive(bool flag); @@ -97,10 +90,8 @@ public: void updateStats(OstProto::PortStats *portStats); -#if 0 signals: void portDataChanged(int portGroupId, int portId); -#endif }; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 76888f3..9e17ae8 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -51,7 +51,7 @@ PortGroup::~PortGroup() void PortGroup::on_rpcChannel_stateChanged() { qDebug("state changed"); - emit portGroupDataChanged(this); + emit portGroupDataChanged(mPortGroupId); } void PortGroup::on_rpcChannel_connected() @@ -60,7 +60,7 @@ void PortGroup::on_rpcChannel_connected() OstProto::PortIdList *portIdList; qDebug("connected\n"); - emit portGroupDataChanged(this); + emit portGroupDataChanged(mPortGroupId); qDebug("requesting portlist ..."); portIdList = new OstProto::PortIdList(); @@ -73,15 +73,18 @@ void PortGroup::on_rpcChannel_disconnected() { qDebug("disconnected\n"); emit portListAboutToBeChanged(mPortGroupId); - mPorts.clear(); + + while (!mPorts.isEmpty()) + delete mPorts.takeFirst(); + emit portListChanged(mPortGroupId); - emit portGroupDataChanged(this); + emit portGroupDataChanged(mPortGroupId); } void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) { qDebug("error\n"); - emit portGroupDataChanged(this); + emit portGroupDataChanged(mPortGroupId); } void PortGroup::when_configApply(int portIndex, uint *cookie) @@ -124,8 +127,8 @@ void PortGroup::when_configApply(int portIndex, uint *cookie) qDebug("applying 'deleted streams' ..."); - streamIdList.mutable_port_id()->set_id(mPorts[portIndex].id()); - mPorts[portIndex].getDeletedStreamsSinceLastSync(streamIdList); + streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getDeletedStreamsSinceLastSync(streamIdList); (*op)++; rpcController->Reset(); @@ -140,8 +143,8 @@ void PortGroup::when_configApply(int portIndex, uint *cookie) qDebug("applying 'new streams' ..."); - streamIdList.mutable_port_id()->set_id(mPorts[portIndex].id()); - mPorts[portIndex].getNewStreamsSinceLastSync(streamIdList); + streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getNewStreamsSinceLastSync(streamIdList); (*op)++; rpcController->Reset(); @@ -156,8 +159,8 @@ void PortGroup::when_configApply(int portIndex, uint *cookie) qDebug("applying 'modified streams' ..."); - streamConfigList.mutable_port_id()->set_id(mPorts[portIndex].id()); - mPorts[portIndex].getModifiedStreamsSinceLastSync(streamConfigList); + streamConfigList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getModifiedStreamsSinceLastSync(streamConfigList); (*op)++; rpcController->Reset(); @@ -168,7 +171,7 @@ void PortGroup::when_configApply(int portIndex, uint *cookie) case 3: qDebug("apply completed"); - mPorts[portIndex].when_syncComplete(); + mPorts[portIndex]->when_syncComplete(); delete cookie; break; @@ -195,8 +198,10 @@ void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) Port *p; p = new Port(portIdList->port_id(i).id(), mPortGroupId); + connect(p, SIGNAL(portDataChanged(int, int)), + this, SIGNAL(portGroupDataChanged(int, int))); qDebug("before port append\n"); - mPorts.append(*p); + mPorts.append(p); } emit portListChanged(mPortGroupId); @@ -240,7 +245,7 @@ void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) id = portConfigList->port(i).port_id().id(); // FIXME: don't mix port id & index into mPorts[] - mPorts[id].updatePortConfig(portConfigList->mutable_port(i)); + mPorts[id]->updatePortConfig(portConfigList->mutable_port(i)); } emit portListChanged(mPortGroupId); @@ -284,10 +289,10 @@ void PortGroup::getStreamIdList(int portIndex, Q_ASSERT(portIndex < numPorts()); - if (streamIdList->port_id().id() != mPorts[portIndex].id()) + if (streamIdList->port_id().id() != mPorts[portIndex]->id()) { qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", - __FUNCTION__, streamIdList->port_id().id(), mPorts[portIndex].id(), + __FUNCTION__, streamIdList->port_id().id(), mPorts[portIndex]->id(), portIndex); goto _next_port; // FIXME(MED): Partial RPC } @@ -298,14 +303,14 @@ void PortGroup::getStreamIdList(int portIndex, uint streamId; streamId = streamIdList->stream_id(i).id(); - mPorts[portIndex].insertStream(streamId); + mPorts[portIndex]->insertStream(streamId); } _next_port: // FIXME(HI): ideally we shd use signals/slots but this means // we will have to use Port* instead of Port with QList<> - // need to find a way for this - mPorts[portIndex].when_syncComplete(); + mPorts[portIndex]->when_syncComplete(); portIndex++; if (portIndex >= numPorts()) { @@ -322,7 +327,7 @@ _next_port: } _request: - portId.set_id(mPorts[portIndex].id()); + portId.set_id(mPorts[portIndex]->id()); streamIdList->Clear(); rpcController->Reset(); @@ -368,11 +373,11 @@ void PortGroup::getStreamConfigList(int portIndex, Q_ASSERT(portIndex < numPorts()); - if (streamConfigList->port_id().id() != mPorts[portIndex].id()) + if (streamConfigList->port_id().id() != mPorts[portIndex]->id()) { qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", __FUNCTION__, streamConfigList->port_id().id(), - mPorts[portIndex].id(), portIndex); + mPorts[portIndex]->id(), portIndex); goto _next_port; // FIXME(MED): Partial RPC } @@ -382,7 +387,7 @@ void PortGroup::getStreamConfigList(int portIndex, uint streamId; streamId = streamConfigList->stream(i).stream_id().id(); - mPorts[portIndex].updateStream(streamId, + mPorts[portIndex]->updateStream(streamId, streamConfigList->mutable_stream(i)); } @@ -403,13 +408,13 @@ _request: qDebug("requesting stream config list ..."); streamIdList.Clear(); - streamIdList.mutable_port_id()->set_id(mPorts[portIndex].id()); - for (int j = 0; j < mPorts[portIndex].numStreams(); j++) + streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + for (int j = 0; j < mPorts[portIndex]->numStreams(); j++) { OstProto::StreamId *s; s = streamIdList.add_stream_id(); - s->set_id(mPorts[portIndex].streamByIndex(j)->id()); + s->set_id(mPorts[portIndex]->streamByIndex(j)->id()); } streamConfigList->Clear(); @@ -657,7 +662,7 @@ void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList) id = portStatsList->port_stats(i).port_id().id(); // FIXME: don't mix port id & index into mPorts[] - mPorts[id].updateStats(portStatsList->mutable_port_stats(i)); + mPorts[id]->updateStats(portStatsList->mutable_port_stats(i)); } emit statsChanged(mPortGroupId); diff --git a/client/portgroup.h b/client/portgroup.h index 81363cc..c63d739 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -38,7 +38,7 @@ private: ::OstProto::PortIdList portIdList; public: // FIXME(HIGH): member access - QList mPorts; + QList mPorts; public: PortGroup(QHostAddress ip = QHostAddress::LocalHost, @@ -91,7 +91,7 @@ public: void processClearStatsAck(OstProto::Ack *ack); signals: - void portGroupDataChanged(PortGroup* portGroup, int portId = 0xFFFF); + void portGroupDataChanged(int portGroupId, int portId = 0xFFFF); void portListAboutToBeChanged(quint32 portGroupId); void portListChanged(quint32 portGroupId); void statsChanged(quint32 portGroupId); diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index 4387aee..e5aa69e 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -32,36 +32,23 @@ bool PortGroupList::isPort(const QModelIndex& index) PortGroup& PortGroupList::portGroup(const QModelIndex& index) { - if (mPortGroupListModel.isPortGroup(index)) - { - //return *(mPortGroups[mPortGroupListModel.portGroupId(index)]); - return *(mPortGroups[index.row()]); - } -#if 0 // FIXME(MED) - else - return NULL; -#endif + Q_ASSERT(mPortGroupListModel.isPortGroup(index)); + + return *(mPortGroups[index.row()]); } Port& PortGroupList::port(const QModelIndex& index) { - if (mPortGroupListModel.isPort(index)) - { - return (mPortGroups.at(index.parent().row())-> - mPorts[index.row()]); - } -#if 0 // FIXME(MED) - else - return NULL; -#endif + Q_ASSERT(mPortGroupListModel.isPort(index)); + return (*mPortGroups.at(index.parent().row())->mPorts[index.row()]); } void PortGroupList::addPortGroup(PortGroup &portGroup) { mPortGroupListModel.portGroupAboutToBeAppended(); - connect(&portGroup, SIGNAL(portGroupDataChanged(PortGroup*, int)), - &mPortGroupListModel, SLOT(when_portGroupDataChanged(PortGroup*, int))); + connect(&portGroup, SIGNAL(portGroupDataChanged(int, int)), + &mPortGroupListModel, SLOT(when_portGroupDataChanged(int, int))); #if 0 connect(&portGroup, SIGNAL(portListAboutToBeChanged(quint32)), &mPortGroupListModel, SLOT(triggerLayoutAboutToBeChanged())); diff --git a/client/portmodel.cpp b/client/portmodel.cpp index 9397cc1..480b642 100644 --- a/client/portmodel.cpp +++ b/client/portmodel.cpp @@ -132,19 +132,19 @@ QVariant PortModel::data(const QModelIndex &index, int role) const return QString("Port %1: %2 [%3] (%4)"). arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()].id()). + parent.row())->mPorts[index.row()]->id()). arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()].name()). + parent.row())->mPorts[index.row()]->name()). arg(QHostAddress("0.0.0.0").toString()). // FIXME(LOW) arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()].description()); + parent.row())->mPorts[index.row()]->description()); } else if ((role == Qt::DecorationRole)) { DBG0("Exit PortModel data 5\n"); if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) return QVariant(); - switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()].linkState()) + switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()]->linkState()) { case OstProto::LinkStateUnknown: return QIcon(":/icons/bullet_white.png"); @@ -198,7 +198,7 @@ QModelIndex PortModel::index (int row, int col, else { quint16 pg = parent.internalId() >> 16; - quint16 p = pgl->mPortGroups.value(parent.row())->mPorts.value(row).id(); + quint16 p = pgl->mPortGroups.value(parent.row())->mPorts.value(row)->id(); quint32 id = (pg << 16) | p; //qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); @@ -264,21 +264,18 @@ quint32 PortModel::portId(const QModelIndex& index) // ---------------------------------------------- // Slots // ---------------------------------------------- -void PortModel::when_portGroupDataChanged(PortGroup* portGroup, int portId) +void PortModel::when_portGroupDataChanged(int portGroupId, int portId) { QModelIndex index; + int row; - if (!pgl->mPortGroups.contains(portGroup)) - { - qDebug("when_portGroupDataChanged(): pg not in list - do nothing"); - return; - } + if (portId == 0xFFFF) + row = pgl->indexOfPortGroup(portGroupId); + else + row = portId; + + index = createIndex(row, 0, (portGroupId << 16) | portId); - qDebug("when_portGroupDataChanged pgid = %d", portGroup->id()); - qDebug("when_portGroupDataChanged idx = %d", pgl->mPortGroups.indexOf(portGroup)); - - index = createIndex(pgl->mPortGroups.indexOf(portGroup), 0, - (portGroup->id() << 16) | portId); emit dataChanged(index, index); } @@ -308,18 +305,6 @@ void PortModel::portGroupRemoved() endRemoveRows(); } -#if 0 -void PortModel::triggerLayoutAboutToBeChanged() -{ - emit layoutAboutToBeChanged(); -} - -void PortModel::triggerLayoutChanged() -{ - emit layoutChanged(); -} -#endif - void PortModel::when_portListChanged() { reset(); diff --git a/client/portmodel.h b/client/portmodel.h index de2b140..bd4b791 100644 --- a/client/portmodel.h +++ b/client/portmodel.h @@ -32,7 +32,7 @@ class PortModel : public QAbstractItemModel private slots: - void when_portGroupDataChanged(PortGroup *portGroup, int portId); + void when_portGroupDataChanged(int portGroupId, int portId); void portGroupAboutToBeAppended(); void portGroupAppended(); diff --git a/client/portstatsfilter.ui b/client/portstatsfilter.ui index af9af02..61aa7a7 100644 --- a/client/portstatsfilter.ui +++ b/client/portstatsfilter.ui @@ -57,6 +57,9 @@ > + + :/icons/arrow_right.png + @@ -64,6 +67,9 @@ < + + :/icons/arrow_left.png + diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 6d77945..ce75846 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -91,7 +91,7 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const { OstProto::PortStats stats; - stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx].getStats(); + stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx]->getStats(); switch(row) { diff --git a/client/streammodel.cpp b/client/streammodel.cpp index cba20e6..a3036fb 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -236,7 +236,7 @@ void StreamModel::setCurrentPortIndex(const QModelIndex ¤t) { qDebug("change to valid port"); quint16 pg = current.internalId() >> 16; - mCurrentPort = &pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()]; + mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()]; } reset(); } From c9563b50eb1b12efd294976ac4ea082af5ea1ed4 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 16 Nov 2009 13:09:20 +0000 Subject: [PATCH 31/98] Features Sample Protocol completed - can be used as a template while implementing a new protocol --- common/abstractprotocol.h | 2 +- common/ostproto.pro | 12 +- common/protocol.proto | 1 + common/protocolmanager.cpp | 4 + common/sample.cpp | 347 +++++++++++++++++++++++++++++++++---- common/sample.h | 27 +++ common/sample.proto | 19 ++ common/sample.ui | 191 ++++++++++++++++++++ 8 files changed, 568 insertions(+), 35 deletions(-) create mode 100644 common/sample.proto create mode 100644 common/sample.ui diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index ccf1b12..c520a31 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -88,7 +88,7 @@ public: quint32 payloadProtocolId(ProtocolIdType type) const; virtual int fieldCount() const; - virtual int metaFieldCount() const; + int metaFieldCount() const; int frameFieldCount() const; virtual FieldFlags fieldFlags(int index) const; diff --git a/common/ostproto.pro b/common/ostproto.pro index 8ae7f99..38064b3 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -13,7 +13,8 @@ FORMS += \ vlan.ui \ ip4.ui \ tcp.ui \ - udp.ui + udp.ui \ + sample.ui PROTOS += \ protocol.proto \ mac.proto \ @@ -29,7 +30,8 @@ PROTOS += \ vlanstack.proto \ ip4.proto \ tcp.proto \ - udp.proto + udp.proto \ + sample.proto HEADERS += \ abstractprotocol.h \ comboprotocol.h \ @@ -50,7 +52,8 @@ HEADERS += \ vlanstack.h \ ip4.h \ tcp.h \ - udp.h + udp.h \ + sample.h SOURCES += \ abstractprotocol.cpp \ protocolmanager.cpp \ @@ -67,7 +70,8 @@ SOURCES += \ svlan.cpp \ ip4.cpp \ tcp.cpp \ - udp.cpp + udp.cpp \ + sample.cpp protobuf_decl.name = protobuf header protobuf_decl.input = PROTOS diff --git a/common/protocol.proto b/common/protocol.proto index 6557dbb..8b8a8f7 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -70,6 +70,7 @@ message Protocol { enum k { kMacFieldNumber = 51; kPayloadFieldNumber = 52; + kSampleFieldNumber = 53; kEth2FieldNumber = 121; kDot3FieldNumber = 122; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 8a9547d..3a9e254 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -2,6 +2,7 @@ #include "abstractprotocol.h" #include "protocol.pb.h" +#include "sample.h" #include "mac.h" #include "payload.h" #include "eth2.h" @@ -52,6 +53,9 @@ ProtocolManager::ProtocolManager() registerProtocol(OstProto::Protocol::kUdpFieldNumber, (void*) UdpProtocol::createInstance); + registerProtocol(OstProto::Protocol::kSampleFieldNumber, + (void*) SampleProtocol::createInstance); + populateNeighbourProtocols(); } diff --git a/common/sample.cpp b/common/sample.cpp index 63aaa7e..2477908 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -1,19 +1,14 @@ #include -#include #include "sample.h" -/*! \todo (MED) Complete the "sample" protocol and make it compilable so that - it can be used as an example for new protocols - */ - SampleConfigForm::SampleConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); } -SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent); +SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent) : AbstractProtocol(stream, parent) { configForm = NULL; @@ -38,24 +33,55 @@ quint32 SampleProtocol::protocolNumber() const void SampleProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { protocol.MutableExtension(OstProto::sample)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()) + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void SampleProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id()->id() == protocolNumber() && + if (protocol.protocol_id().id() == protocolNumber() && protocol.HasExtension(OstProto::sample)) data.MergeFrom(protocol.GetExtension(OstProto::sample)); } QString SampleProtocol::name() const { - return QString("Sample"); + return QString("Sample Protocol"); } QString SampleProtocol::shortName() const { - return QString("Sample"); + return QString("SAMPLE"); +} + +/*! + Return the ProtocolIdType for your protocol \n + + If your protocol doesn't have a protocolId field, you don't need to + reimplement this method - the base class implementation will do the + right thing +*/ +AbstractProtocol::ProtocolIdType SampleProtocol::protocolIdType() const +{ + return ProtocolIdIp; +} + +/*! + Return the protocolId for your protoocol based on the 'type' requested \n + + If not all types are valid for your protocol, handle the valid type(s) + and for the remaining fallback to the base class implementation; if your + protocol doesn't have a protocolId at all, you don't need to reimplement + this method - the base class will do the right thing +*/ +quint32 SampleProtocol::protocolId(ProtocolIdType type) const +{ + switch(type) + { + case ProtocolIdIp: return 1234; + default:break; + } + + return AbstractProtocol::protocolId(type); } int SampleProtocol::fieldCount() const @@ -71,18 +97,26 @@ AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const switch (index) { - case sample_normal: + case sample_a: + case sample_b: + case sample_payloadLength: break; - case sample_cksum: + case sample_checksum: flags |= FieldIsCksum; break; - case sample_meta: + case sample_x: + case sample_y: + break; + + case sample_is_override_checksum: flags |= FieldIsMeta; break; default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); break; } @@ -94,55 +128,188 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, { switch (index) { - case sample_one: + case sample_a: { + int a = data.ab() >> 13; + switch(attrib) { case FieldName: - return QString("ONE"); + return QString("A"); case FieldValue: - return data.one(); + return a; case FieldTextValue: - return QString("%1").arg(data.one()); + return QString("%1").arg(a); case FieldFrameValue: - return QByteArray(1, (char)(data.one() & 0xF0)); + return QByteArray(1, (char) a); case FieldBitSize: - return 4; + return 3; default: break; } break; } - case sample_two: + case sample_b: { + int b = data.ab() & 0x1FFF; + switch(attrib) { case FieldName: - return QString("TWO"); + return QString("B"); case FieldValue: - return data.two(); + return b; case FieldTextValue: - return QString("%1").arg(data.two()); + return QString("%1").arg(b, 4, BASE_HEX, QChar('0')); case FieldFrameValue: { QByteArray fv; - fv.resize(0); - qToBigEndian(FIXME, (uchar*) fv.data()); + fv.resize(2); + qToBigEndian((quint16) b, (uchar*) fv.data()); return fv; } - return QByteArray(1, (char)(FIXME() & 0xF0)); case FieldBitSize: - return 4; + return 13; default: break; } break; } - // Meta fields - case sample_FIXME: + case sample_payloadLength: + { + switch(attrib) + { + case FieldName: + return QString("Payload Length"); + case FieldValue: + return protocolFramePayloadSize(streamIndex); + case FieldFrameValue: + { + QByteArray fv; + int totlen; + totlen = protocolFramePayloadSize(streamIndex); + fv.resize(2); + qToBigEndian((quint16) totlen, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("%1").arg( + protocolFramePayloadSize(streamIndex)); + case FieldBitSize: + return 16; + default: + break; + } + break; + } + case sample_checksum: + { + quint16 cksum; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + { + if (data.is_override_checksum()) + cksum = data.checksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumIp); + } + default: + break; + } + + switch(attrib) + { + case FieldName: + return QString("Checksum"); + case FieldValue: + return cksum; + case FieldFrameValue: + { + QByteArray fv; + + fv.resize(2); + qToBigEndian(cksum, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("0x%1").arg( + cksum, 4, BASE_HEX, QChar('0'));; + case FieldBitSize: + return 16; + default: + break; + } + break; + } + case sample_x: + { + switch(attrib) + { + case FieldName: + return QString("X"); + case FieldValue: + return data.x(); + case FieldTextValue: + return QString("%1").arg(data.x()); + //return QString("%1").arg(data.x(), 8, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.x(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + case sample_y: + { + switch(attrib) + { + case FieldName: + return QString("Y"); + case FieldValue: + return data.y(); + case FieldTextValue: + //return QString("%1").arg(data.y()); + return QString("%1").arg(data.y(), 8, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.y(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + + + // Meta fields + case sample_is_override_checksum: + { + switch(attrib) + { + case FieldValue: + return data.is_override_checksum(); + default: + break; + } + break; + } default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); break; } @@ -152,10 +319,105 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, bool SampleProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { - // FIXME + bool isOk = false; + + if (attrib != FieldValue) + goto _exit; + + switch (index) + { + case sample_a: + { + uint a = value.toUInt(&isOk); + if (isOk) + data.set_ab((data.ab() & 0xe000) | (a << 13)); + break; + } + case sample_b: + { + uint b = value.toUInt(&isOk); + if (isOk) + data.set_ab((data.ab() & 0x1FFF) | b); + break; + } + case sample_payloadLength: + { + uint len = value.toUInt(&isOk); + if (isOk) + data.set_payload_length(len); + break; + } + case sample_checksum: + { + uint csum = value.toUInt(&isOk); + if (isOk) + data.set_checksum(csum); + break; + } + case sample_x: + { + uint x = value.toUInt(&isOk); + if (isOk) + data.set_x(x); + break; + } + case sample_y: + { + uint y = value.toUInt(&isOk); + if (isOk) + data.set_y(y); + break; + } + case sample_is_override_checksum: + { + bool ovr = value.toBool(); + data.set_is_override_checksum(ovr); + isOk = true; + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + +_exit: + return isOk; +} + +/*! + Return the protocol frame size in bytes\n + + If your protocol has a fixed size - you don't need to reimplement this; the + base class implementation is good enough +*/ +int SampleProtocol::protocolFrameSize(int streamIndex) const +{ + return AbstractProtocol::protocolFrameSize(streamIndex); +} + +/*! + If your protocol has any variable fields, return true \n + + Otherwise you don't need to reimplement this method - the base class always + returns false +*/ +bool SampleProtocol::isProtocolFrameValueVariable() const +{ return false; } +/*! + If your protocol frame size can vary across pkts of the same stream, + return true \n + + Otherwise you don't need to reimplement this method - the base class always + returns false +*/ +bool SampleProtocol::isProtocolFrameSizeVariable() const +{ + return false; +} QWidget* SampleProtocol::configWidget() { @@ -171,6 +433,21 @@ QWidget* SampleProtocol::configWidget() void SampleProtocol::loadConfigWidget() { configWidget(); + + configForm->sampleA->setText(fieldData(sample_a, FieldValue).toString()); + configForm->sampleB->setText(fieldData(sample_b, FieldValue).toString()); + + configForm->samplePayloadLength->setText( + fieldData(sample_payloadLength, FieldValue).toString()); + + configForm->isChecksumOverride->setChecked( + fieldData(sample_is_override_checksum, FieldValue).toBool()); + configForm->sampleChecksum->setText(uintToHexStr( + fieldData(sample_checksum, FieldValue).toUInt(), 2)); + + configForm->sampleX->setText(fieldData(sample_x, FieldValue).toString()); + configForm->sampleY->setText(fieldData(sample_y, FieldValue).toString()); + } void SampleProtocol::storeConfigWidget() @@ -178,5 +455,15 @@ void SampleProtocol::storeConfigWidget() bool isOk; configWidget(); + setFieldData(sample_a, configForm->sampleA->text()); + setFieldData(sample_b, configForm->sampleB->text()); + + setFieldData(sample_payloadLength, configForm->samplePayloadLength->text()); + setFieldData(sample_is_override_checksum, + configForm->isChecksumOverride->isChecked()); + setFieldData(sample_checksum, configForm->sampleChecksum->text().toUInt(&isOk, BASE_HEX)); + + setFieldData(sample_x, configForm->sampleX->text()); + setFieldData(sample_y, configForm->sampleY->text()); } diff --git a/common/sample.h b/common/sample.h index 6075262..a0e0ad3 100644 --- a/common/sample.h +++ b/common/sample.h @@ -6,6 +6,15 @@ #include "sample.pb.h" #include "ui_sample.h" +/* +Sample Protocol Frame Format - + +-----+------+------+------+------+------+ + | A | B | LEN | CSUM | X | Y | + | (3) | (13) | (16) | (16) | (32) | (32) | + +-----+------+------+------+------+------+ +Figures in brackets represent field width in bits +*/ + class SampleConfigForm : public QWidget, public Ui::Sample { Q_OBJECT @@ -21,6 +30,16 @@ private: SampleConfigForm *configForm; enum samplefield { + // Frame Fields + sample_a = 0, + sample_b, + sample_payloadLength, + sample_checksum, + sample_x, + sample_y, + + // Meta Fields + sample_is_override_checksum, sample_fieldCount }; @@ -36,6 +55,9 @@ public: virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual ProtocolIdType protocolIdType() const; + virtual quint32 protocolId(ProtocolIdType type) const; + virtual QString name() const; virtual QString shortName() const; @@ -47,6 +69,11 @@ public: virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual int protocolFrameSize(int streamIndex = 0) const; + + virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameSizeVariable() const; + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/common/sample.proto b/common/sample.proto new file mode 100644 index 0000000..76213d4 --- /dev/null +++ b/common/sample.proto @@ -0,0 +1,19 @@ +import "protocol.proto"; + +package OstProto; + +// Sample Protocol +message Sample { + + optional bool is_override_checksum = 1; + + optional uint32 ab = 2; + optional uint32 payload_length = 3; + optional uint32 checksum = 4; + optional uint32 x = 5 [default = 1234]; + optional uint32 y = 6; +} + +extend Protocol { + optional Sample sample = 53; +} diff --git a/common/sample.ui b/common/sample.ui new file mode 100644 index 0000000..2932014 --- /dev/null +++ b/common/sample.ui @@ -0,0 +1,191 @@ + + Sample + + + + 0 + 0 + 263 + 116 + + + + Form + + + + + + Field A + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + sampleA + + + + + + + >HH; + + + + + + + + + + Checksum + + + + + + + false + + + >HH HH; + + + + + + + Field B + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + sampleB + + + + + + + >HH HH; + + + + + + + Field X + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + sampleX + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Length + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + samplePayloadLength + + + + + + + false + + + + + + + + + + Field Y + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + sampleY + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + sampleA + sampleB + samplePayloadLength + isChecksumOverride + sampleChecksum + sampleX + sampleY + + + + + isChecksumOverride + toggled(bool) + sampleChecksum + setEnabled(bool) + + + 345 + 122 + + + 406 + 122 + + + + + From ebc0403fde51df59bc205b6ee7c92345f626b1a6 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 23 Nov 2009 08:08:22 +0000 Subject: [PATCH 32/98] Features UserScript Protocol "first cut" checked-in. Needs rework. --- client/ostinato.pro | 2 +- common/ostproto.pro | 6 +- common/protocol.proto | 1 + common/protocolmanager.cpp | 7 +- common/userscript.cpp | 492 +++++++++++++++++++++++++++++++++++++ common/userscript.h | 160 ++++++++++++ common/userscript.proto | 14 ++ common/userscript.ui | 61 +++++ server/drone.pro | 2 +- 9 files changed, 740 insertions(+), 5 deletions(-) create mode 100644 common/userscript.cpp create mode 100644 common/userscript.h create mode 100644 common/userscript.proto create mode 100644 common/userscript.ui diff --git a/client/ostinato.pro b/client/ostinato.pro index 707969e..ff54e47 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -1,6 +1,6 @@ TEMPLATE = app CONFIG += qt debug -QT += network +QT += network script INCLUDEPATH += "../rpc/" "../common/" LIBS += -lprotobuf win32:LIBS += -L"../common/debug" -lostproto diff --git a/common/ostproto.pro b/common/ostproto.pro index 38064b3..19121ca 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -1,6 +1,6 @@ TEMPLATE = lib CONFIG += qt staticlib -QT += network +QT += network script LIBS += \ -lprotobuf FORMS += \ @@ -14,6 +14,7 @@ FORMS += \ ip4.ui \ tcp.ui \ udp.ui \ + userscript.ui \ sample.ui PROTOS += \ protocol.proto \ @@ -31,6 +32,7 @@ PROTOS += \ ip4.proto \ tcp.proto \ udp.proto \ + userscript.proto \ sample.proto HEADERS += \ abstractprotocol.h \ @@ -53,6 +55,7 @@ HEADERS += \ ip4.h \ tcp.h \ udp.h \ + userscript.h \ sample.h SOURCES += \ abstractprotocol.cpp \ @@ -71,6 +74,7 @@ SOURCES += \ ip4.cpp \ tcp.cpp \ udp.cpp \ + userscript.cpp \ sample.cpp protobuf_decl.name = protobuf header diff --git a/common/protocol.proto b/common/protocol.proto index 8b8a8f7..30bec18 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -71,6 +71,7 @@ message Protocol { kMacFieldNumber = 51; kPayloadFieldNumber = 52; kSampleFieldNumber = 53; + kUserScriptFieldNumber = 54; kEth2FieldNumber = 121; kDot3FieldNumber = 122; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 3a9e254..7c8763d 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -2,7 +2,6 @@ #include "abstractprotocol.h" #include "protocol.pb.h" -#include "sample.h" #include "mac.h" #include "payload.h" #include "eth2.h" @@ -16,6 +15,8 @@ #include "ip4.h" #include "tcp.h" #include "udp.h" +#include "userscript.h" +#include "sample.h" ProtocolManager OstProtocolManager; @@ -53,6 +54,8 @@ ProtocolManager::ProtocolManager() registerProtocol(OstProto::Protocol::kUdpFieldNumber, (void*) UdpProtocol::createInstance); + registerProtocol(OstProto::Protocol::kUserScriptFieldNumber, + (void*) UserScriptProtocol::createInstance); registerProtocol(OstProto::Protocol::kSampleFieldNumber, (void*) SampleProtocol::createInstance); @@ -64,7 +67,7 @@ void ProtocolManager::registerProtocol(int protoNumber, { AbstractProtocol *p; - //! \todo (MED) validate incoming params for duplicates with existing + Q_ASSERT(!factory.contains(protoNumber)); factory.insert(protoNumber, protoInstanceCreator); diff --git a/common/userscript.cpp b/common/userscript.cpp new file mode 100644 index 0000000..5cb792c --- /dev/null +++ b/common/userscript.cpp @@ -0,0 +1,492 @@ +#include "userscript.h" + +#include +#include +#include +#include + +UserScriptConfigForm::UserScriptConfigForm(UserScriptProtocol *protocol, + QWidget *parent) : QWidget(parent), _protocol(protocol) +{ + setupUi(this); +} + +void UserScriptConfigForm::on_programEdit_textChanged() +{ +} + +void UserScriptConfigForm::on_compileButton_clicked(bool checked) +{ + _protocol->storeConfigWidget(); + if (_protocol->userScriptErrorLineNumber() >= 0) + { + statusLabel->setText("Fail"); + QMessageBox::critical(this, "Error", + QString("Line %1: %2").arg( + _protocol->userScriptErrorLineNumber()).arg( + _protocol->userScriptErrorText())); + } + else + { + statusLabel->setText("Success"); + } +} + +UserScriptProtocol::UserScriptProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent), + _userProtocol(this) +{ + configForm = NULL; + _isUpdated = false; + _errorLineNumber = -1; + + _userProtocolScriptValue = _scriptEngine.newQObject(&_userProtocol); + _userProtocolScriptValue.setProperty("protocolId", _scriptEngine.newObject()); + _scriptEngine.globalObject().setProperty("protocol", _userProtocolScriptValue); + + + QScriptValue meta = _scriptEngine.newQMetaObject(_userProtocol.metaObject()); + _scriptEngine.globalObject().setProperty("Protocol", meta); + +} + +UserScriptProtocol::~UserScriptProtocol() +{ + delete configForm; +} + +AbstractProtocol* UserScriptProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) +{ + return new UserScriptProtocol(stream, parent); +} + +quint32 UserScriptProtocol::protocolNumber() const +{ + return OstProto::Protocol::kUserScriptFieldNumber; +} + +void UserScriptProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const +{ + protocol.MutableExtension(OstProto::userScript)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void UserScriptProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::userScript)) + data.MergeFrom(protocol.GetExtension(OstProto::userScript)); + + evaluateUserScript(); +} + +QString UserScriptProtocol::name() const +{ + return QString("%1:{UserScript}").arg(_userProtocol.name()); +} + +QString UserScriptProtocol::shortName() const +{ + return QString("%1:{Script}").arg(_userProtocol.shortName()); +} + +quint32 UserScriptProtocol::protocolId(ProtocolIdType type) const +{ + if (_userProtocol._protocolId.contains(static_cast(type))) + return _userProtocol._protocolId.value(static_cast(type)); + else + return AbstractProtocol::protocolId(type); +} + +int UserScriptProtocol::fieldCount() const +{ + return userScript_fieldCount; +} + +QVariant UserScriptProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case userScript_program: + { + switch(attrib) + { + case FieldName: + return QString("UserProtocol"); + + case FieldValue: + case FieldTextValue: + return QString().fromStdString(data.program()); + + case FieldFrameValue: + { + QScriptValue userFunction; + QByteArray fv; + + evaluateUserScript(); // FIXME: don't call everytime! + + if (_userProtocol.isProtocolFrameFixed()) + { + fv = _userProtocol.protocolFrameFixedValue(); + if (fv.size()) + return fv; + else + return QByteArray(4, 0); // FIXME + } + + userFunction = _userProtocolScriptValue.property( + "protocolFrameValue"); + + qDebug("userscript protoFrameVal(): isValid:%d/isFunc:%d", + userFunction.isValid(), userFunction.isFunction()); + + if (userFunction.isValid() && userFunction.isFunction()) + { + QScriptValue userValue; + + userValue = userFunction.call(QScriptValue(), + QScriptValueList() + << QScriptValue(&_scriptEngine, streamIndex)); + + qDebug("userscript value: isValid:%d/isArray:%d", + userValue.isValid(), userValue.isArray()); + + if (userValue.isArray()) + { + QList pktBuf; + + qScriptValueToSequence(userValue, pktBuf); + + fv.resize(pktBuf.size()); + for (int i = 0; i < pktBuf.size(); i++) + fv[i] = pktBuf.at(i) & 0xFF; + } + } + + if (fv.size()) + return fv; + else + return QByteArray(4, 0); // FIXME + } + //case FieldBitSize: + //return 3; + default: + break; + } + break; + + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool UserScriptProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + bool isOk = false; + + if (attrib != FieldValue) + goto _exit; + + switch (index) + { + case userScript_program: + { + data.set_program(value.toString().toStdString()); + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + +_exit: + return isOk; +} + +bool UserScriptProtocol::isProtocolFrameValueVariable() const +{ + return _userProtocol.isProtocolFrameValueVariable(); +} + +bool UserScriptProtocol::isProtocolFrameSizeVariable() const +{ + return _userProtocol.isProtocolFrameSizeVariable(); +} + +QWidget* UserScriptProtocol::configWidget() +{ + if (configForm == NULL) + { + configForm = new UserScriptConfigForm(this); + loadConfigWidget(); + } + + return configForm; +} + +void UserScriptProtocol::loadConfigWidget() +{ + configWidget(); + + configForm->programEdit->setPlainText( + fieldData(userScript_program, FieldValue).toString()); +} + +void UserScriptProtocol::storeConfigWidget() +{ + configWidget(); + setFieldData(userScript_program, configForm->programEdit->toPlainText()); + evaluateUserScript(); +} + +bool UserScriptProtocol::evaluateUserScript() const +{ + QScriptValue userFunction; + QScriptValue userValue; + + _errorLineNumber = -1; + _userProtocol.reset(); + _userProtocolScriptValue.setProperty("protocolFrameValue", QScriptValue()); + + _scriptEngine.evaluate( + fieldData(userScript_program, FieldValue).toString()); + if (_scriptEngine.hasUncaughtException()) + goto _error_exception; + + userFunction = _userProtocolScriptValue.property( + "protocolFrameValue"); + qDebug("userscript eval protoFrameVal(): isValid:%d/isFunc:%d", + userFunction.isValid(), userFunction.isFunction()); + if (!userFunction.isValid()) + goto _error_frame_value_not_set; + + if (userFunction.isArray()) + { + QList pktBuf; + + userValue = userFunction; + _userProtocol.setProtocolFrameValueVariable(false); + + qScriptValueToSequence(userValue, pktBuf); + _userProtocol.setProtocolFrameFixedValue(pktBuf); + } + else if (userFunction.isFunction()) + { + userValue = userFunction.call(); + if (_scriptEngine.hasUncaughtException()) + goto _error_exception; + qDebug("userscript eval value: isValid:%d/isArray:%d", + userValue.isValid(), userValue.isArray()); + if (!userValue.isArray()) + goto _error_not_an_array; + + if (_userProtocol.isProtocolFrameFixed()) + { + QList pktBuf; + + qScriptValueToSequence(userValue, pktBuf); + _userProtocol.setProtocolFrameFixedValue(pktBuf); + } + } + else + goto _error_frame_value_type; + + + userValue = _userProtocolScriptValue.property("protocolId"); + + if (userValue.isValid() && userValue.isObject()) + { + QMetaEnum meta; + QScriptValue userProtocolId; + + meta = _userProtocol.metaObject()->enumerator( + _userProtocol.metaObject()->indexOfEnumerator("ProtocolIdType")); + for (int i = 0; i < meta.keyCount(); i++) + { + userProtocolId = userValue.property(meta.key(i)); + + qDebug("userscript protoId: isValid:%d/isNumber:%d", + userProtocolId.isValid(), + userProtocolId.isNumber()); + + if (userProtocolId.isValid() && userProtocolId.isNumber()) + _userProtocol._protocolId.insert( + meta.value(i), userProtocolId.toUInt32()); + } + } + + _isUpdated = true; + return true; + +_error_not_an_array: + _errorLineNumber = userScriptLineCount(); + _errorText = QString("property 'protocolFrameValue' returns invalid array"); + goto _error; + +_error_frame_value_type: + _errorLineNumber = userScriptLineCount(); + _errorText = QString("property 'protocolFrameValue' is neither an array nor a function"); + goto _error; + +_error_frame_value_not_set: + _errorLineNumber = userScriptLineCount(); + _errorText = QString("mandatory property 'protocolFrameValue' is not set"); + goto _error; + +_error_exception: + _errorLineNumber = _scriptEngine.uncaughtExceptionLineNumber(); + _errorText = _scriptEngine.uncaughtException().toString(); + goto _error; + +_error: + _userProtocol.reset(); + return false; +} + +int UserScriptProtocol::userScriptErrorLineNumber() const +{ + return _errorLineNumber; +} + +QString UserScriptProtocol::userScriptErrorText() const +{ + return _errorText; +} + +int UserScriptProtocol::userScriptLineCount() const +{ + return fieldData(userScript_program, FieldValue).toString().count( + QChar('\n')) + 1; +} + +// +// --------------------------------------------------------------- +// + +UserProtocol::UserProtocol(AbstractProtocol *parent) + : _parent (parent) +{ + reset(); +} + +bool UserProtocol::isProtocolFrameFixed() const +{ + return !isProtocolFrameValueVariable() && !isProtocolFrameSizeVariable(); +} + +const QByteArray& UserProtocol::protocolFrameFixedValue() const +{ + return _protocolFrameFixedValue; +} + +void UserProtocol::setProtocolFrameFixedValue(const QByteArray& value) +{ + _protocolFrameFixedValue = value; +} + +void UserProtocol::setProtocolFrameFixedValue(const QList& value) +{ + _protocolFrameFixedValue.resize(value.size()); + for (int i = 0; i < value.size(); i++) + _protocolFrameFixedValue[i] = value.at(i) & 0xFF; +} + +void UserProtocol::reset() +{ + _name = QString(); + _shortName = QString(); + _protocolId.clear(); + _protocolFrameValueVariable = false; + _protocolFrameSizeVariable = false; + _protocolFrameFixedValue.resize(0); +} + +QString UserProtocol::name() const +{ + return _name; +} + +void UserProtocol::setName(QString &name) +{ + _name = name; +} + +QString UserProtocol::shortName() const +{ + return _shortName; +} + +void UserProtocol::setShortName(QString &shortName) +{ + _shortName = shortName; +} + +bool UserProtocol::isProtocolFrameValueVariable() const +{ + return _protocolFrameValueVariable; +} + +void UserProtocol::setProtocolFrameValueVariable(bool variable) +{ + qDebug("%s: %d", __FUNCTION__, variable); + _protocolFrameValueVariable = variable; +} + +bool UserProtocol::isProtocolFrameSizeVariable() const +{ + return _protocolFrameSizeVariable; +} + +void UserProtocol::setProtocolFrameSizeVariable(bool variable) +{ + _protocolFrameSizeVariable = variable; +} + +quint32 UserProtocol::payloadProtocolId(UserProtocol::ProtocolIdType type) const +{ + return _parent->payloadProtocolId( + static_cast(type)); +} + +int UserProtocol::protocolFrameOffset(int streamIndex) const +{ + return _parent->protocolFrameOffset(streamIndex); +} + +int UserProtocol::protocolFramePayloadSize(int streamIndex) const +{ + return _parent->protocolFramePayloadSize(streamIndex); +} + +bool UserProtocol::isProtocolFramePayloadValueVariable() const +{ + return _parent->isProtocolFramePayloadValueVariable(); +} + +bool UserProtocol::isProtocolFramePayloadSizeVariable() const +{ + return _parent->isProtocolFramePayloadSizeVariable(); +} + +quint32 UserProtocol::protocolFrameHeaderCksum(int streamIndex, + AbstractProtocol::CksumType cksumType) const +{ + return _parent->protocolFrameHeaderCksum(streamIndex, cksumType); +} + +quint32 UserProtocol::protocolFramePayloadCksum(int streamIndex, + AbstractProtocol::CksumType cksumType) const +{ + return _parent->protocolFramePayloadCksum(streamIndex, cksumType); +} + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/common/userscript.h b/common/userscript.h new file mode 100644 index 0000000..504e285 --- /dev/null +++ b/common/userscript.h @@ -0,0 +1,160 @@ +#ifndef _USER_SCRIPT_H +#define _USER_SCRIPT_H + +#include "abstractprotocol.h" +#include "userscript.pb.h" +#include "ui_userscript.h" + +#include +#include + +class UserScriptProtocol; + +class UserProtocol : public QObject +{ + friend class UserScriptProtocol; + + Q_OBJECT; + Q_ENUMS(ProtocolIdType); + + Q_PROPERTY(QString name READ name WRITE setName); + Q_PROPERTY(QString shortName READ shortName WRITE setShortName); + Q_PROPERTY(bool protocolFrameValueVariable + READ isProtocolFrameValueVariable + WRITE setProtocolFrameValueVariable); + Q_PROPERTY(bool protocolFrameSizeVariable + READ isProtocolFrameSizeVariable + WRITE setProtocolFrameSizeVariable); + +public: + enum ProtocolIdType + { + ProtocolIdLlc = AbstractProtocol::ProtocolIdLlc, + ProtocolIdEth = AbstractProtocol::ProtocolIdEth, + ProtocolIdIp = AbstractProtocol::ProtocolIdIp + }; + + UserProtocol(AbstractProtocol *parent); + + bool isProtocolFrameFixed() const; + const QByteArray& protocolFrameFixedValue() const; + void setProtocolFrameFixedValue(const QByteArray& value); + void setProtocolFrameFixedValue(const QList& value); + +public slots: + void reset(); + + QString name() const; + void setName(QString &name); + QString shortName() const; + void setShortName(QString &shortName); + + bool isProtocolFrameValueVariable() const; + void setProtocolFrameValueVariable(bool variable); + bool isProtocolFrameSizeVariable() const; + void setProtocolFrameSizeVariable(bool variable); + + quint32 payloadProtocolId(UserProtocol::ProtocolIdType type) const; + int protocolFrameOffset(int streamIndex = 0) const; + int protocolFramePayloadSize(int streamIndex = 0) const; + + bool isProtocolFramePayloadValueVariable() const; + bool isProtocolFramePayloadSizeVariable() const; + + quint32 protocolFrameHeaderCksum(int streamIndex = 0, + AbstractProtocol::CksumType cksumType = AbstractProtocol::CksumIp) const; + quint32 protocolFramePayloadCksum(int streamIndex = 0, + AbstractProtocol::CksumType cksumType = AbstractProtocol::CksumIp) const; + +private: + AbstractProtocol *_parent; + + QString _name; + QString _shortName; + QMap _protocolId; + bool _protocolFrameValueVariable; + bool _protocolFrameSizeVariable; + QByteArray _protocolFrameFixedValue; + +}; + +class UserScriptConfigForm : public QWidget, public Ui::UserScript +{ + Q_OBJECT + +public: + UserScriptConfigForm(UserScriptProtocol *protocol, QWidget *parent = 0); + +private: + UserScriptProtocol *_protocol; + +private slots: + void on_programEdit_textChanged(); + void on_compileButton_clicked(bool checked = false); +}; + + +class UserScriptProtocol : public AbstractProtocol +{ + friend class UserScriptConfigForm; + +public: + UserScriptProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~UserScriptProtocol(); + + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + + virtual quint32 protocolId(ProtocolIdType type) const; + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameSizeVariable() const; + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); + +private: + bool evaluateUserScript() const; + int userScriptErrorLineNumber() const; + QString userScriptErrorText() const; + + int userScriptLineCount() const; + + + OstProto::UserScript data; + UserScriptConfigForm *configForm; + enum userScriptfield + { + // Frame Fields + userScript_program = 0, + + userScript_fieldCount + }; + + mutable QScriptEngine _scriptEngine; + mutable UserProtocol _userProtocol; + mutable QScriptValue _userProtocolScriptValue; + + mutable bool _isUpdated; + mutable int _errorLineNumber; + mutable QString _errorText; +}; + +#endif + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/common/userscript.proto b/common/userscript.proto new file mode 100644 index 0000000..3f26cd2 --- /dev/null +++ b/common/userscript.proto @@ -0,0 +1,14 @@ +import "protocol.proto"; + +package OstProto; + +// Sample Protocol +message UserScript { + + optional string program = 1; + +} + +extend Protocol { + optional UserScript userScript = 54; +} diff --git a/common/userscript.ui b/common/userscript.ui new file mode 100644 index 0000000..a5dde73 --- /dev/null +++ b/common/userscript.ui @@ -0,0 +1,61 @@ + + UserScript + + + + 0 + 0 + 517 + 335 + + + + Form + + + + + + + + + + + Compilation Status: + + + + + + + Unknown + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Compile + + + + + + + + + + diff --git a/server/drone.pro b/server/drone.pro index c42d9a4..f569b4d 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -1,6 +1,6 @@ TEMPLATE = app CONFIG += qt debug -QT += network +QT += network script DEFINES += HAVE_REMOTE WPCAP INCLUDEPATH += "../rpc" LIBS += -lprotobuf From 4c5b8faff7c1784e373578b6af3a352da5df6707 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 28 Nov 2009 08:35:05 +0000 Subject: [PATCH 33/98] Fixes/Rework - UserScript Protocol reworked. Needs more testing. May need a significant rewrite in the future, but for now this will have to do - therefore it has been marked "EXPERIMENTAL" for now --- common/abstractprotocol.cpp | 2 + common/ip4.h | 5 +- common/userscript.cpp | 556 +++++++++++++++++++++--------------- common/userscript.h | 64 +++-- common/userscript.ui | 87 +++--- 5 files changed, 413 insertions(+), 301 deletions(-) diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 3dd58ae..025a745 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -287,6 +287,8 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) if (!flags.testFlag(FieldIsMeta)) { bits = fieldData(i, FieldBitSize, streamIndex).toUInt(); + if (bits == 0) + continue; Q_ASSERT(bits > 0); if (forCksum && flags.testFlag(FieldIsCksum)) diff --git a/common/ip4.h b/common/ip4.h index 34f4c37..e3e1a23 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -80,11 +80,12 @@ public: int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); - virtual quint32 protocolFrameCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; virtual bool isProtocolFrameValueVariable() const; + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); diff --git a/common/userscript.cpp b/common/userscript.cpp index 5cb792c..89191fb 100644 --- a/common/userscript.cpp +++ b/common/userscript.cpp @@ -1,53 +1,70 @@ #include "userscript.h" -#include #include -#include -#include + +// +// -------------------- UserScriptConfigForm -------------------- +// UserScriptConfigForm::UserScriptConfigForm(UserScriptProtocol *protocol, - QWidget *parent) : QWidget(parent), _protocol(protocol) + QWidget *parent) : QWidget(parent), protocol_(protocol) { setupUi(this); + updateStatus(); +} + +void UserScriptConfigForm::updateStatus() +{ + if (protocol_->isScriptValid()) + { + statusLabel->setText(QString("Success")); + compileButton->setDisabled(true); + } + else + { + statusLabel->setText( + QString("Error: %1: %2").arg( + protocol_->userScriptErrorLineNumber()).arg( + protocol_->userScriptErrorText())); + compileButton->setEnabled(true); + } } void UserScriptConfigForm::on_programEdit_textChanged() { + compileButton->setEnabled(true); } void UserScriptConfigForm::on_compileButton_clicked(bool checked) { - _protocol->storeConfigWidget(); - if (_protocol->userScriptErrorLineNumber() >= 0) + protocol_->storeConfigWidget(); + if (!protocol_->isScriptValid()) { - statusLabel->setText("Fail"); QMessageBox::critical(this, "Error", - QString("Line %1: %2").arg( - _protocol->userScriptErrorLineNumber()).arg( - _protocol->userScriptErrorText())); - } - else - { - statusLabel->setText("Success"); + QString("%1: %2").arg( + protocol_->userScriptErrorLineNumber()).arg( + protocol_->userScriptErrorText())); } + updateStatus(); } +// +// -------------------- UserScriptProtocol -------------------- +// + UserScriptProtocol::UserScriptProtocol(StreamBase *stream, AbstractProtocol *parent) : AbstractProtocol(stream, parent), - _userProtocol(this) + userProtocol_(this) { configForm = NULL; - _isUpdated = false; - _errorLineNumber = -1; + isScriptValid_ = false; + errorLineNumber_ = 0; - _userProtocolScriptValue = _scriptEngine.newQObject(&_userProtocol); - _userProtocolScriptValue.setProperty("protocolId", _scriptEngine.newObject()); - _scriptEngine.globalObject().setProperty("protocol", _userProtocolScriptValue); - - - QScriptValue meta = _scriptEngine.newQMetaObject(_userProtocol.metaObject()); - _scriptEngine.globalObject().setProperty("Protocol", meta); + userProtocolScriptValue_ = engine_.newQObject(&userProtocol_); + engine_.globalObject().setProperty("protocol", userProtocolScriptValue_); + QScriptValue meta = engine_.newQMetaObject(userProtocol_.metaObject()); + engine_.globalObject().setProperty("Protocol", meta); } UserScriptProtocol::~UserScriptProtocol() @@ -83,23 +100,42 @@ void UserScriptProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) QString UserScriptProtocol::name() const { - return QString("%1:{UserScript}").arg(_userProtocol.name()); + return QString("%1:{UserScript} [EXPERIMENTAL]").arg(userProtocol_.name()); } QString UserScriptProtocol::shortName() const { - return QString("%1:{Script}").arg(_userProtocol.shortName()); + return QString("%1:{Script} [EXPERIMENTAL]").arg(userProtocol_.name()); } quint32 UserScriptProtocol::protocolId(ProtocolIdType type) const { - if (_userProtocol._protocolId.contains(static_cast(type))) - return _userProtocol._protocolId.value(static_cast(type)); - else - return AbstractProtocol::protocolId(type); + QScriptValue userFunction; + QScriptValue userValue; + + if (!isScriptValid_) + goto _do_default; + + userFunction = userProtocolScriptValue_.property("protocolId"); + + if (!userFunction.isValid()) + goto _do_default; + + Q_ASSERT(userFunction.isFunction()); + + userValue = userFunction.call(QScriptValue(), + QScriptValueList() << QScriptValue(&engine_, type)); + + Q_ASSERT(userValue.isValid()); + Q_ASSERT(userValue.isNumber()); + + return userValue.toUInt32(); + +_do_default: + return AbstractProtocol::protocolId(type); } -int UserScriptProtocol::fieldCount() const +int UserScriptProtocol::fieldCount() const { return userScript_fieldCount; } @@ -109,79 +145,54 @@ QVariant UserScriptProtocol::fieldData(int index, FieldAttrib attrib, { switch (index) { - case userScript_program: + case userScript_program: + + switch(attrib) { - switch(attrib) - { - case FieldName: - return QString("UserProtocol"); + case FieldName: + return QString("UserProtocol"); - case FieldValue: - case FieldTextValue: - return QString().fromStdString(data.program()); + case FieldValue: + case FieldTextValue: + return QString().fromStdString(data.program()); - case FieldFrameValue: - { - QScriptValue userFunction; - QByteArray fv; + case FieldFrameValue: + { + if (!isScriptValid_) + return QByteArray(); - evaluateUserScript(); // FIXME: don't call everytime! + QScriptValue userFunction = userProtocolScriptValue_.property( + "protocolFrameValue"); - if (_userProtocol.isProtocolFrameFixed()) - { - fv = _userProtocol.protocolFrameFixedValue(); - if (fv.size()) - return fv; - else - return QByteArray(4, 0); // FIXME - } + Q_ASSERT(userFunction.isValid()); + Q_ASSERT(userFunction.isFunction()); - userFunction = _userProtocolScriptValue.property( - "protocolFrameValue"); + QScriptValue userValue = userFunction.call(QScriptValue(), + QScriptValueList() << QScriptValue(&engine_, streamIndex)); - qDebug("userscript protoFrameVal(): isValid:%d/isFunc:%d", - userFunction.isValid(), userFunction.isFunction()); + Q_ASSERT(userValue.isValid()); + Q_ASSERT(userValue.isArray()); - if (userFunction.isValid() && userFunction.isFunction()) - { - QScriptValue userValue; + QByteArray fv; + QList pktBuf; + + qScriptValueToSequence(userValue, pktBuf); - userValue = userFunction.call(QScriptValue(), - QScriptValueList() - << QScriptValue(&_scriptEngine, streamIndex)); - - qDebug("userscript value: isValid:%d/isArray:%d", - userValue.isValid(), userValue.isArray()); - - if (userValue.isArray()) - { - QList pktBuf; - - qScriptValueToSequence(userValue, pktBuf); - - fv.resize(pktBuf.size()); - for (int i = 0; i < pktBuf.size(); i++) - fv[i] = pktBuf.at(i) & 0xFF; - } - } - - if (fv.size()) - return fv; - else - return QByteArray(4, 0); // FIXME - } - //case FieldBitSize: - //return 3; - default: - break; - } - break; + fv.resize(pktBuf.size()); + for (int i = 0; i < pktBuf.size(); i++) + fv[i] = pktBuf.at(i) & 0xFF; + return fv; } default: - qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, - index); break; + } + break; + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; } return AbstractProtocol::fieldData(index, attrib, streamIndex); @@ -212,14 +223,65 @@ _exit: return isOk; } +int UserScriptProtocol::protocolFrameSize(int streamIndex) const +{ + if (!isScriptValid_) + return 0; + + QScriptValue userFunction = userProtocolScriptValue_.property( + "protocolFrameSize"); + + Q_ASSERT(userFunction.isValid()); + Q_ASSERT(userFunction.isFunction()); + + QScriptValue userValue = userFunction.call(QScriptValue(), + QScriptValueList() << QScriptValue(&engine_, streamIndex)); + + Q_ASSERT(userValue.isNumber()); + + return userValue.toInt32(); +} + bool UserScriptProtocol::isProtocolFrameValueVariable() const { - return _userProtocol.isProtocolFrameValueVariable(); + return userProtocol_.isProtocolFrameValueVariable(); } bool UserScriptProtocol::isProtocolFrameSizeVariable() const { - return _userProtocol.isProtocolFrameSizeVariable(); + return userProtocol_.isProtocolFrameSizeVariable(); +} + +quint32 UserScriptProtocol::protocolFrameCksum(int streamIndex, + CksumType cksumType) const +{ + QScriptValue userFunction; + QScriptValue userValue; + + if (!isScriptValid_) + goto _do_default; + + userFunction = userProtocolScriptValue_.property("protocolFrameCksum"); + + qDebug("userscript protoFrameCksum(): isValid:%d/isFunc:%d", + userFunction.isValid(), userFunction.isFunction()); + + if (!userFunction.isValid()) + goto _do_default; + + Q_ASSERT(userFunction.isFunction()); + + userValue = userFunction.call(QScriptValue(), + QScriptValueList() << QScriptValue(&engine_, streamIndex) + << QScriptValue(&engine_, cksumType)); + + Q_ASSERT(userValue.isValid()); + Q_ASSERT(userValue.isNumber()); + + return userValue.toUInt32(); + +_do_default: + return AbstractProtocol::protocolFrameCksum(streamIndex, cksumType); } QWidget* UserScriptProtocol::configWidget() @@ -248,118 +310,186 @@ void UserScriptProtocol::storeConfigWidget() evaluateUserScript(); } -bool UserScriptProtocol::evaluateUserScript() const +void UserScriptProtocol::evaluateUserScript() const { QScriptValue userFunction; QScriptValue userValue; + QString property; - _errorLineNumber = -1; - _userProtocol.reset(); - _userProtocolScriptValue.setProperty("protocolFrameValue", QScriptValue()); + isScriptValid_ = false; + errorLineNumber_ = userScriptLineCount(); - _scriptEngine.evaluate( - fieldData(userScript_program, FieldValue).toString()); - if (_scriptEngine.hasUncaughtException()) + // Reset all properties including the dynamic ones + userProtocol_.reset(); + userProtocolScriptValue_.setProperty("protocolFrameValue", QScriptValue()); + userProtocolScriptValue_.setProperty("protocolFrameSize", QScriptValue()); + userProtocolScriptValue_.setProperty("protocolFrameCksum", QScriptValue()); + userProtocolScriptValue_.setProperty("protocolId", QScriptValue()); + + engine_.evaluate(fieldData(userScript_program, FieldValue).toString()); + if (engine_.hasUncaughtException()) goto _error_exception; - userFunction = _userProtocolScriptValue.property( - "protocolFrameValue"); - qDebug("userscript eval protoFrameVal(): isValid:%d/isFunc:%d", - userFunction.isValid(), userFunction.isFunction()); + // Validate protocolFrameValue() + property = QString("protocolFrameValue"); + userFunction = userProtocolScriptValue_.property(property); + + qDebug("userscript property %s: isValid:%d/isFunc:%d", + property.toAscii().constData(), + userFunction.isValid(), userFunction.isFunction()); + if (!userFunction.isValid()) - goto _error_frame_value_not_set; - - if (userFunction.isArray()) { - QList pktBuf; - - userValue = userFunction; - _userProtocol.setProtocolFrameValueVariable(false); - - qScriptValueToSequence(userValue, pktBuf); - _userProtocol.setProtocolFrameFixedValue(pktBuf); + errorText_ = property + QString(" not set"); + goto _error_exit; } - else if (userFunction.isFunction()) + + if (!userFunction.isFunction()) { - userValue = userFunction.call(); - if (_scriptEngine.hasUncaughtException()) - goto _error_exception; - qDebug("userscript eval value: isValid:%d/isArray:%d", + errorText_ = property + QString(" is not a function"); + goto _error_exit; + } + + userValue = userFunction.call(); + if (engine_.hasUncaughtException()) + goto _error_exception; + + qDebug("userscript property %s return value: isValid:%d/isArray:%d", + property.toAscii().constData(), userValue.isValid(), userValue.isArray()); - if (!userValue.isArray()) - goto _error_not_an_array; - if (_userProtocol.isProtocolFrameFixed()) - { - QList pktBuf; - - qScriptValueToSequence(userValue, pktBuf); - _userProtocol.setProtocolFrameFixedValue(pktBuf); - } - } - else - goto _error_frame_value_type; - - - userValue = _userProtocolScriptValue.property("protocolId"); - - if (userValue.isValid() && userValue.isObject()) + if (!userValue.isArray()) { - QMetaEnum meta; - QScriptValue userProtocolId; - - meta = _userProtocol.metaObject()->enumerator( - _userProtocol.metaObject()->indexOfEnumerator("ProtocolIdType")); - for (int i = 0; i < meta.keyCount(); i++) - { - userProtocolId = userValue.property(meta.key(i)); - - qDebug("userscript protoId: isValid:%d/isNumber:%d", - userProtocolId.isValid(), - userProtocolId.isNumber()); - - if (userProtocolId.isValid() && userProtocolId.isNumber()) - _userProtocol._protocolId.insert( - meta.value(i), userProtocolId.toUInt32()); - } + errorText_ = property + QString(" does not return an array"); + goto _error_exit; } - _isUpdated = true; - return true; + // Validate protocolFrameSize() + property = QString("protocolFrameSize"); + userFunction = userProtocolScriptValue_.property(property); -_error_not_an_array: - _errorLineNumber = userScriptLineCount(); - _errorText = QString("property 'protocolFrameValue' returns invalid array"); - goto _error; + qDebug("userscript property %s: isValid:%d/isFunc:%d", + property.toAscii().constData(), + userFunction.isValid(), userFunction.isFunction()); -_error_frame_value_type: - _errorLineNumber = userScriptLineCount(); - _errorText = QString("property 'protocolFrameValue' is neither an array nor a function"); - goto _error; + if (!userFunction.isValid()) + { + errorText_ = property + QString(" not set"); + goto _error_exit; + } -_error_frame_value_not_set: - _errorLineNumber = userScriptLineCount(); - _errorText = QString("mandatory property 'protocolFrameValue' is not set"); - goto _error; + if (!userFunction.isFunction()) + { + errorText_ = property + QString(" is not a function"); + goto _error_exit; + } + + userValue = userFunction.call(); + if (engine_.hasUncaughtException()) + goto _error_exception; + + qDebug("userscript property %s return value: isValid:%d/isNumber:%d", + property.toAscii().constData(), + userValue.isValid(), userValue.isNumber()); + + if (!userValue.isNumber()) + { + errorText_ = property + QString(" does not return a number"); + goto _error_exit; + } + + // Validate protocolFrameCksum() [optional] + property = QString("protocolFrameCksum"); + userFunction = userProtocolScriptValue_.property(property); + + qDebug("userscript property %s: isValid:%d/isFunc:%d", + property.toAscii().constData(), + userFunction.isValid(), userFunction.isFunction()); + + if (!userFunction.isValid()) + goto _skip_cksum; + + if (!userFunction.isFunction()) + { + errorText_ = property + QString(" is not a function"); + goto _error_exit; + } + + userValue = userFunction.call(); + if (engine_.hasUncaughtException()) + goto _error_exception; + + qDebug("userscript property %s return value: isValid:%d/isNumber:%d", + property.toAscii().constData(), + userValue.isValid(), userValue.isNumber()); + + if (!userValue.isNumber()) + { + errorText_ = property + QString(" does not return a number"); + goto _error_exit; + } + + +_skip_cksum: + // Validate protocolId() [optional] + property = QString("protocolId"); + userFunction = userProtocolScriptValue_.property(property); + + qDebug("userscript property %s: isValid:%d/isFunc:%d", + property.toAscii().constData(), + userFunction.isValid(), userFunction.isFunction()); + + if (!userFunction.isValid()) + goto _skip_protocol_id; + + if (!userFunction.isFunction()) + { + errorText_ = property + QString(" is not a function"); + goto _error_exit; + } + + userValue = userFunction.call(); + if (engine_.hasUncaughtException()) + goto _error_exception; + + qDebug("userscript property %s return value: isValid:%d/isNumber:%d", + property.toAscii().constData(), + userValue.isValid(), userValue.isNumber()); + + if (!userValue.isNumber()) + { + errorText_ = property + QString(" does not return a number"); + goto _error_exit; + } + + +_skip_protocol_id: + errorText_ = QString(""); + isScriptValid_ = true; + return; _error_exception: - _errorLineNumber = _scriptEngine.uncaughtExceptionLineNumber(); - _errorText = _scriptEngine.uncaughtException().toString(); - goto _error; + errorLineNumber_ = engine_.uncaughtExceptionLineNumber(); + errorText_ = engine_.uncaughtException().toString(); -_error: - _userProtocol.reset(); - return false; +_error_exit: + userProtocol_.reset(); + return; +} + +bool UserScriptProtocol::isScriptValid() const +{ + return isScriptValid_; } int UserScriptProtocol::userScriptErrorLineNumber() const { - return _errorLineNumber; + return errorLineNumber_; } QString UserScriptProtocol::userScriptErrorText() const { - return _errorText; + return errorText_; } int UserScriptProtocol::userScriptLineCount() const @@ -369,124 +499,92 @@ int UserScriptProtocol::userScriptLineCount() const } // -// --------------------------------------------------------------- +// -------------------- UserProtocol -------------------- // UserProtocol::UserProtocol(AbstractProtocol *parent) - : _parent (parent) + : parent_ (parent) { reset(); } -bool UserProtocol::isProtocolFrameFixed() const -{ - return !isProtocolFrameValueVariable() && !isProtocolFrameSizeVariable(); -} - -const QByteArray& UserProtocol::protocolFrameFixedValue() const -{ - return _protocolFrameFixedValue; -} - -void UserProtocol::setProtocolFrameFixedValue(const QByteArray& value) -{ - _protocolFrameFixedValue = value; -} - -void UserProtocol::setProtocolFrameFixedValue(const QList& value) -{ - _protocolFrameFixedValue.resize(value.size()); - for (int i = 0; i < value.size(); i++) - _protocolFrameFixedValue[i] = value.at(i) & 0xFF; -} - void UserProtocol::reset() { - _name = QString(); - _shortName = QString(); - _protocolId.clear(); - _protocolFrameValueVariable = false; - _protocolFrameSizeVariable = false; - _protocolFrameFixedValue.resize(0); + name_ = QString(); + protocolFrameValueVariable_ = false; + protocolFrameSizeVariable_ = false; } QString UserProtocol::name() const { - return _name; + return name_; } void UserProtocol::setName(QString &name) { - _name = name; -} - -QString UserProtocol::shortName() const -{ - return _shortName; -} - -void UserProtocol::setShortName(QString &shortName) -{ - _shortName = shortName; + name_ = name; } bool UserProtocol::isProtocolFrameValueVariable() const { - return _protocolFrameValueVariable; + return protocolFrameValueVariable_; } void UserProtocol::setProtocolFrameValueVariable(bool variable) { - qDebug("%s: %d", __FUNCTION__, variable); - _protocolFrameValueVariable = variable; + protocolFrameValueVariable_ = variable; } bool UserProtocol::isProtocolFrameSizeVariable() const { - return _protocolFrameSizeVariable; + return protocolFrameSizeVariable_; } void UserProtocol::setProtocolFrameSizeVariable(bool variable) { - _protocolFrameSizeVariable = variable; + protocolFrameSizeVariable_ = variable; } quint32 UserProtocol::payloadProtocolId(UserProtocol::ProtocolIdType type) const { - return _parent->payloadProtocolId( + return parent_->payloadProtocolId( static_cast(type)); } int UserProtocol::protocolFrameOffset(int streamIndex) const { - return _parent->protocolFrameOffset(streamIndex); + return parent_->protocolFrameOffset(streamIndex); } int UserProtocol::protocolFramePayloadSize(int streamIndex) const { - return _parent->protocolFramePayloadSize(streamIndex); + return parent_->protocolFramePayloadSize(streamIndex); } bool UserProtocol::isProtocolFramePayloadValueVariable() const { - return _parent->isProtocolFramePayloadValueVariable(); + return parent_->isProtocolFramePayloadValueVariable(); } bool UserProtocol::isProtocolFramePayloadSizeVariable() const { - return _parent->isProtocolFramePayloadSizeVariable(); + return parent_->isProtocolFramePayloadSizeVariable(); } quint32 UserProtocol::protocolFrameHeaderCksum(int streamIndex, AbstractProtocol::CksumType cksumType) const { - return _parent->protocolFrameHeaderCksum(streamIndex, cksumType); + return parent_->protocolFrameHeaderCksum(streamIndex, cksumType); } quint32 UserProtocol::protocolFramePayloadCksum(int streamIndex, AbstractProtocol::CksumType cksumType) const { - return _parent->protocolFramePayloadCksum(streamIndex, cksumType); + quint32 cksum; + + cksum = parent_->protocolFramePayloadCksum(streamIndex, cksumType); + qDebug("UserProto:%s = %d", __FUNCTION__, cksum); + return cksum; } /* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/common/userscript.h b/common/userscript.h index 504e285..3f51142 100644 --- a/common/userscript.h +++ b/common/userscript.h @@ -12,13 +12,11 @@ class UserScriptProtocol; class UserProtocol : public QObject { - friend class UserScriptProtocol; - Q_OBJECT; Q_ENUMS(ProtocolIdType); + Q_ENUMS(CksumType); Q_PROPERTY(QString name READ name WRITE setName); - Q_PROPERTY(QString shortName READ shortName WRITE setShortName); Q_PROPERTY(bool protocolFrameValueVariable READ isProtocolFrameValueVariable WRITE setProtocolFrameValueVariable); @@ -34,20 +32,20 @@ public: ProtocolIdIp = AbstractProtocol::ProtocolIdIp }; - UserProtocol(AbstractProtocol *parent); + enum CksumType + { + CksumIp = AbstractProtocol::CksumIp, + CksumIpPseudo = AbstractProtocol::CksumIpPseudo, + CksumTcpUdp = AbstractProtocol::CksumTcpUdp + }; - bool isProtocolFrameFixed() const; - const QByteArray& protocolFrameFixedValue() const; - void setProtocolFrameFixedValue(const QByteArray& value); - void setProtocolFrameFixedValue(const QList& value); + UserProtocol(AbstractProtocol *parent); public slots: void reset(); QString name() const; void setName(QString &name); - QString shortName() const; - void setShortName(QString &shortName); bool isProtocolFrameValueVariable() const; void setProtocolFrameValueVariable(bool variable); @@ -67,17 +65,15 @@ public slots: AbstractProtocol::CksumType cksumType = AbstractProtocol::CksumIp) const; private: - AbstractProtocol *_parent; - - QString _name; - QString _shortName; - QMap _protocolId; - bool _protocolFrameValueVariable; - bool _protocolFrameSizeVariable; - QByteArray _protocolFrameFixedValue; + AbstractProtocol *parent_; + QString name_; + bool protocolFrameValueVariable_; + bool protocolFrameSizeVariable_; }; + + class UserScriptConfigForm : public QWidget, public Ui::UserScript { Q_OBJECT @@ -86,7 +82,8 @@ public: UserScriptConfigForm(UserScriptProtocol *protocol, QWidget *parent = 0); private: - UserScriptProtocol *_protocol; + void updateStatus(); + UserScriptProtocol *protocol_; private slots: void on_programEdit_textChanged(); @@ -94,9 +91,9 @@ private slots: }; + class UserScriptProtocol : public AbstractProtocol { - friend class UserScriptConfigForm; public: UserScriptProtocol(StreamBase *stream, AbstractProtocol *parent = 0); @@ -121,23 +118,26 @@ public: virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual int protocolFrameSize(int streamIndex = 0) const; + virtual bool isProtocolFrameValueVariable() const; virtual bool isProtocolFrameSizeVariable() const; + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + virtual QWidget* configWidget(); virtual void loadConfigWidget(); virtual void storeConfigWidget(); -private: - bool evaluateUserScript() const; + void evaluateUserScript() const; + bool isScriptValid() const; int userScriptErrorLineNumber() const; QString userScriptErrorText() const; +private: int userScriptLineCount() const; - - OstProto::UserScript data; - UserScriptConfigForm *configForm; enum userScriptfield { // Frame Fields @@ -145,14 +145,16 @@ private: userScript_fieldCount }; + OstProto::UserScript data; + UserScriptConfigForm *configForm; - mutable QScriptEngine _scriptEngine; - mutable UserProtocol _userProtocol; - mutable QScriptValue _userProtocolScriptValue; + mutable QScriptEngine engine_; + mutable UserProtocol userProtocol_; + mutable QScriptValue userProtocolScriptValue_; - mutable bool _isUpdated; - mutable int _errorLineNumber; - mutable QString _errorText; + mutable bool isScriptValid_; + mutable int errorLineNumber_; + mutable QString errorText_; }; #endif diff --git a/common/userscript.ui b/common/userscript.ui index a5dde73..e18e024 100644 --- a/common/userscript.ui +++ b/common/userscript.ui @@ -12,47 +12,56 @@ Form - - + + - - - - - - Compilation Status: - - - - - - - Unknown - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Compile - - - - + + + + + 10 + 0 + + + + QFrame::Panel + + + QFrame::Sunken + + + + 4 + + + 4 + + + 4 + + + 4 + + + 4 + + + + + Unknown + + + + + + + + + + Compile + + From bb6a9235c31027bbbb0773aaddae29c635be514e Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 29 Nov 2009 16:32:31 +0000 Subject: [PATCH 34/98] Features - Ostinato Client - will start the server as a child process at startup and terminate it at exit - Ostinato Server (Drone) - is now a system tray application - if not able to bind to a IP/Port successfully, informs the user and exits - the GUI is now nothing more than a TextLabel Others - If a getStats() request is pending, the client will not queue up any more requests till a reply is received for the pending one - Nitpicks in the Payload protocol Widget, PortsWindow Widget --- client/main.cpp | 3 +- client/mainwindow.cpp | 14 ++- client/mainwindow.h | 12 ++- client/portgroup.cpp | 6 ++ client/portgroup.h | 1 + client/portswindow.cpp | 1 - client/portswindow.ui | 3 + common/payload.ui | 135 +++++++++++++++++---------- rpc/rpcserver.cpp | 27 ++++-- rpc/rpcserver.h | 4 +- server/abstracthost.h | 14 --- server/drone.cpp | 79 +++++++++++++--- server/drone.h | 41 ++++++--- server/drone.pro | 1 + server/drone.ui | 182 ++++++++++++++++++++++++------------- server/drone_main.cpp | 17 +++- server/icons/portgroup.png | Bin 0 -> 667 bytes server/myservice.cpp | 5 +- server/myservice.h | 6 +- 19 files changed, 367 insertions(+), 184 deletions(-) delete mode 100644 server/abstracthost.h create mode 100644 server/icons/portgroup.png diff --git a/client/main.cpp b/client/main.cpp index 34a9f8c..2f9b385 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -1,6 +1,7 @@ -#include #include "mainwindow.h" +#include + int main(int argc, char* argv[]) { QApplication app(argc, argv); diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 0a0e0fb..9b2d12a 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -1,17 +1,25 @@ #include "mainwindow.h" -#include "portgrouplist.h" #if 0 #include "dbgthread.h" #endif +#include "portgrouplist.h" +#include "portstatswindow.h" +#include "portswindow.h" #include "ui_about.h" +#include +#include + PortGroupList *pgl; MainWindow::MainWindow(QWidget *parent) : QMainWindow (parent) { + localServer_ = new QProcess(this); + localServer_->start("drone.exe"); + pgl = new PortGroupList; portsWindow = new PortsWindow(pgl, this); @@ -37,6 +45,10 @@ MainWindow::MainWindow(QWidget *parent) MainWindow::~MainWindow() { + delete pgl; + localServer_->terminate(); + localServer_->waitForFinished(); + delete localServer_; } void MainWindow::on_actionHelpAbout_triggered() diff --git a/client/mainwindow.h b/client/mainwindow.h index a5d31a6..5132385 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -1,19 +1,21 @@ #ifndef _MAIN_WINDOW_H #define _MAIN_WINDOW_H -#include -#include - #include "ui_mainwindow.h" +#include -#include "portswindow.h" -#include "portstatswindow.h" +class PortsWindow; +class PortStatsWindow; + +class QDockWidget; +class QProcess; class MainWindow : public QMainWindow, private Ui::MainWindow { Q_OBJECT private: + QProcess *localServer_; PortsWindow *portsWindow; PortStatsWindow *statsWindow; QDockWidget *portsDock; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 9e17ae8..4a2843c 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -21,6 +21,7 @@ PortGroup::PortGroup(QHostAddress ip, quint16 port) */ rpcController = new PbRpcController; rpcControllerStats = new PbRpcController; + isGetStatsPending_ = false; serviceStub = new OstProto::OstService::Stub(rpcChannel, OstProto::OstService::STUB_OWNS_CHANNEL); @@ -640,8 +641,12 @@ void PortGroup::getPortStats() if (state() != QAbstractSocket::ConnectedState) return; + if (isGetStatsPending_) + return; + portStatsList = new OstProto::PortStatsList; rpcControllerStats->Reset(); + isGetStatsPending_ = true; serviceStub->getStats(rpcControllerStats, &portIdList, portStatsList, NewCallback(this, &PortGroup::processPortStatsList, portStatsList)); } @@ -669,6 +674,7 @@ void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList) _error_exit: delete portStatsList; + isGetStatsPending_ = false; } void PortGroup::clearPortStats(QList *portList) diff --git a/client/portgroup.h b/client/portgroup.h index c63d739..f4d8e99 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -34,6 +34,7 @@ private: PbRpcChannel *rpcChannel; PbRpcController *rpcController; PbRpcController *rpcControllerStats; + bool isGetStatsPending_; ::OstProto::OstService::Stub *serviceStub; ::OstProto::PortIdList portIdList; diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 7d9bbc4..54d4b8b 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -71,7 +71,6 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) PortsWindow::~PortsWindow() { - delete plm; } void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) diff --git a/client/portswindow.ui b/client/portswindow.ui index 1ed9485..9e461a2 100644 --- a/client/portswindow.ui +++ b/client/portswindow.ui @@ -18,6 +18,9 @@ Qt::Horizontal + + false + Qt::ActionsContextMenu diff --git a/common/payload.ui b/common/payload.ui index c0a1b31..a7ff9a2 100644 --- a/common/payload.ui +++ b/common/payload.ui @@ -5,63 +5,100 @@ 0 0 - 142 - 98 + 299 + 114 Form - - - - - Data Pattern + + + + + Type + + + cmbPatternMode - - - - - - Fixed Word - - - - - Increment Byte - - - - - Decrement Byte - - - - - Random - - - - - - - - >HH HH HH HH; - - - - - - 11 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - + + + + + Fixed Word + + + + + Increment Byte + + + + + Decrement Byte + + + + + Random + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Pattern + + + lePattern + + + + + + + >HH HH HH HH; + + + + + + 11 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index 039fc83..3d5a10c 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -27,14 +27,25 @@ bool RpcServer::registerService(::google::protobuf::Service *service, connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); if (!server->listen(QHostAddress::Any, tcpPortNum)) { - LogInt(tr("Unable to start the server: %1").arg(server->errorString())); + qDebug("Unable to start the server: %s", + server->errorString().toAscii().constData()); + errorString_ = QString("Error starting Ostinato server: %1").arg( + server->errorString()); return false; } - LogInt(tr("The server is running on %1:%2").arg(server->serverAddress().toString()).arg(server->serverPort())); + qDebug("The server is running on %s: %d", + server->serverAddress().toString().toAscii().constData(), + server->serverPort()); + errorString_ = QString(); return true; } +QString RpcServer::errorString() +{ + return errorString_; +} + void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController) { QIODevice *blob; @@ -111,7 +122,7 @@ void RpcServer::when_newConnection() { QTcpSocket *sock; - LogInt(tr("already connected, no new connections will be accepted\n")); + qDebug("already connected, no new connections will be accepted"); // Accept and close connection //! \todo (MED) Send reason msg to client @@ -122,7 +133,9 @@ void RpcServer::when_newConnection() } clientSock = server->nextPendingConnection(); - LogInt(tr("accepting new connection from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); + qDebug("accepting new connection from %s: %d", + clientSock->peerAddress().toString().toAscii().constData(), + clientSock->peerPort()); connect(clientSock, SIGNAL(readyRead()), this, SLOT(when_dataAvail())); @@ -137,7 +150,9 @@ _exit: void RpcServer::when_disconnected() { - LogInt(tr("connection closed from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); + qDebug("connection closed from %s: %d", + clientSock->peerAddress().toString().toAscii().constData(), + clientSock->peerPort()); clientSock->deleteLater(); clientSock = NULL; @@ -145,7 +160,7 @@ void RpcServer::when_disconnected() void RpcServer::when_error(QAbstractSocket::SocketError socketError) { - LogInt(clientSock->errorString()); + qDebug("%s", clientSock->errorString().toAscii().constData()); } void RpcServer::when_dataAvail() diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h index d93b08a..619cb2d 100644 --- a/rpc/rpcserver.h +++ b/rpc/rpcserver.h @@ -23,8 +23,7 @@ class RpcServer : public QObject bool isPending; int pendingMethodId; - - void LogInt (QString log) {qDebug("%s", log.toAscii().data());} + QString errorString_; public: RpcServer(); //! \todo (LOW) use 'parent' param @@ -32,6 +31,7 @@ public: bool registerService(::google::protobuf::Service *service, quint16 tcpPortNum); + QString errorString(); void done(::google::protobuf::Message *resp, PbRpcController *controller); private slots: diff --git a/server/abstracthost.h b/server/abstracthost.h deleted file mode 100644 index 862666c..0000000 --- a/server/abstracthost.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _ABSTRACT_HOST -#define _ABSTRACT_HOST - -class AbstractHost -{ - public: - virtual void Log(const char* str) = 0; -#if 0 // PB - virtual int SendMsg(const void* msg, int size) = 0; -#endif -}; - -#endif - diff --git a/server/drone.cpp b/server/drone.cpp index 1f94d7e..c84aec5 100644 --- a/server/drone.cpp +++ b/server/drone.cpp @@ -1,23 +1,76 @@ #include "drone.h" +#include "rpcserver.h" +#include "myservice.h" + +#include +#include + extern int myport; -Drone::Drone(QDialog *parent) - : QDialog(parent) +Drone::Drone(QWidget *parent) + : QWidget(parent) { - ui.setupUi(this); + setupUi(this); - rpcServer = new RpcServer(); - service = new MyService(this); - rpcServer->registerService(service, myport ? myport : 7878); -} - -void Drone::Log(const char* str) -{ - ui.teLog->append(QString(str)); + rpcServer = new RpcServer(); + service = new MyService(); } -void Drone::LogInt(const QString &str) +Drone::~Drone() { - ui.teLog->append(str); + trayIcon_->hide(); + delete rpcServer; + delete service; +} + +bool Drone::init() +{ + Q_ASSERT(rpcServer); + + if (!rpcServer->registerService(service, myport ? myport : 7878)) + { + QMessageBox::critical(0, qApp->applicationName(), + rpcServer->errorString()); + return false; + } + + trayIconMenu_ = new QMenu(this); + + trayIconMenu_->addAction(actionShow); + trayIconMenu_->addAction(actionExit); + trayIconMenu_->setDefaultAction(actionShow); + trayIcon_ = new QSystemTrayIcon(); + trayIcon_->setIcon(QIcon(":/icons/portgroup.png")); + trayIcon_->setToolTip(qApp->applicationName()); + trayIcon_->setContextMenu(trayIconMenu_); + trayIcon_->show(); + + connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + connect(this, SIGNAL(hideMe(bool)), this, SLOT(setHidden(bool)), + Qt::QueuedConnection); + + return true; +} + +void Drone::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::WindowStateChange && isMinimized()) + { + emit hideMe(true); + event->ignore(); + return; + } + + QWidget::changeEvent(event); +} + +void Drone::trayIconActivated(QSystemTrayIcon::ActivationReason reason) +{ + if (reason == QSystemTrayIcon::DoubleClick) + { + showNormal(); + activateWindow(); + } } diff --git a/server/drone.h b/server/drone.h index 31574a6..5930dd0 100644 --- a/server/drone.h +++ b/server/drone.h @@ -1,26 +1,37 @@ #ifndef _DRONE_H #define _DRONE_H -#include -#include - #include "ui_drone.h" -#include "abstracthost.h" -#include "rpcserver.h" -#include "myservice.h" -class Drone : public QDialog, AbstractHost +#include +#include + +class RpcServer; +namespace OstProto { class OstService; } + +class Drone : public QWidget, Ui::Drone { Q_OBJECT - public: - Ui::Drone ui; - Drone(QDialog *parent = 0); - void Log(const char *msg); +public: + Drone(QWidget *parent = 0); + ~Drone(); + bool init(); + +signals: + void hideMe(bool hidden); + +protected: + void changeEvent(QEvent *event); + +private: + QSystemTrayIcon *trayIcon_; + QMenu *trayIconMenu_; + RpcServer *rpcServer; + OstProto::OstService *service; + +private slots: + void trayIconActivated(QSystemTrayIcon::ActivationReason reason); - private: - RpcServer *rpcServer; - OstProto::OstService *service; - void LogInt(const QString &msg); }; #endif diff --git a/server/drone.pro b/server/drone.pro index f569b4d..a5cd2bb 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -11,6 +11,7 @@ unix:LIBS += -L"../common" -lostproto win32:LIBS += -L"../rpc/debug" -lpbrpc unix:LIBS += -L"../rpc" -lpbrpc POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" +RESOURCES += drone.qrc HEADERS += drone.h FORMS += drone.ui SOURCES += drone_main.cpp drone.cpp diff --git a/server/drone.ui b/server/drone.ui index 5caa184..73fde04 100644 --- a/server/drone.ui +++ b/server/drone.ui @@ -1,69 +1,82 @@ Drone - + 0 0 - 400 - 300 + 268 + 216 Drone + + :/icons/portgroup.png + - - - 1 + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:29pt; font-weight:600;">Ostinato</span></p></body></html> + + + Qt::AlignCenter - - - Status - - - - - 160 - 100 - 46 - 14 - - - - TODO - - - - - - Log - - - - - - true - - - false - - - - - + + + + (Server) + + + Qt::AlignCenter + + + + + + + TODO: Info/Status here + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 51 + + + + - - - - Clear Log - - - @@ -84,41 +97,82 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + Show + + + + + Exit + + - + + + pushButton - clicked(bool) - Drone - accept() + clicked() + actionExit + trigger() - 341 - 279 + 134 + 194 - 226 - 268 + -1 + -1 - pbClearLog - clicked() - teLog - clear() + actionShow + triggered() + Drone + showNormal() - 52 - 278 + -1 + -1 - 100 - 185 + 133 + 107 + + + + + actionExit + triggered() + Drone + close() + + + -1 + -1 + + + 133 + 107 diff --git a/server/drone_main.cpp b/server/drone_main.cpp index 007f1af..6a9052f 100644 --- a/server/drone_main.cpp +++ b/server/drone_main.cpp @@ -1,18 +1,25 @@ #include "drone.h" -Drone *drone; - int myport; int main(int argc, char *argv[]) { QApplication app(argc, argv); + Drone drone; + + app.setApplicationName(drone.objectName()); if (argc > 1) myport = atoi(argv[1]); - drone = new Drone; - drone->show(); - return app.exec(); + if (!drone.init()) + exit(-1); + + drone.setWindowFlags(drone.windowFlags() + | Qt::WindowMaximizeButtonHint + | Qt::WindowMinimizeButtonHint); + drone.showMinimized(); + app.exec(); + return 0; } diff --git a/server/icons/portgroup.png b/server/icons/portgroup.png new file mode 100644 index 0000000000000000000000000000000000000000..9bc37dce369d66bdf38393b191df4d7e6c7ccd54 GIT binary patch literal 667 zcmV;M0%ZM(P)a!u4Ek1OWvhNg%r^rdTXsY3VK8?SdPP#w89em&*t9`8-y> z{{XWmi9uo#0y2mREC>R)tyU|D<2Xwun+7u3ce~yHC8N{n5>SE*7ca{{mxCuK52M#x z6?VgqVUHr69iApkt_fp7}UIJIX)^0!0b=W3KH zu#9)c?;$B!KqeOeo#x5*?d$d(>1am)Y%kbK4HaZEF7DqvCglmk2%DRMFl4hCO2bI^ zX=T@9j!era3Mj9K%ggW14jP4g$@9D^u1>q%4oF>&Q{%YG^bC$1Iv|Sn?VXTj+j1A` z_4;iBxjK9L%sJ01;N^>_f2ih9=zM1B|Mb6I%0_FShXA!&ZGuYnYi{m5Mm>)<#Bd!= zpw*3PwK}@fZ5>`FlHMWvu( #endif -#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} +#define LOG(...) {} #define MB (1024*1024) StreamInfo::StreamInfo() @@ -831,14 +831,13 @@ _found: return i; } -MyService::MyService(AbstractHost *host) +MyService::MyService() { pcap_if_t *dev; int i=0; char errbuf[PCAP_ERRBUF_SIZE]; // Init Data - this->host = host; numPorts = 0; alldevs = NULL; diff --git a/server/myservice.h b/server/myservice.h index bafe9b9..4be1bdb 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -9,7 +9,6 @@ #include "../common/protocol.pb.h" #include "../common/streambase.h" -#include "abstracthost.h" #include #include #include @@ -191,9 +190,6 @@ public: class MyService: public OstProto::OstService { - AbstractHost *host; - char logStr[1024]; - uint numPorts; /*! PortInfo::d::port_id and index into portInfo[] are same! */ @@ -203,7 +199,7 @@ class MyService: public OstProto::OstService int getStreamIndex(unsigned int portIdx,unsigned int streamId); public: - MyService(AbstractHost* host); + MyService(); virtual ~MyService(); /* Methods provided by the service */ From a1ae3e7e6c0087f8b56ff63d655771009c910477 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 26 Dec 2009 17:33:27 +0000 Subject: [PATCH 35/98] Refactoring - Major code reorganization of the server code across several classes with fewer 'friends' - New server classes - AbstractPort, PcapPort, WinPcapPort, PortManager - With this reorg classes have more focus than earlier and will be hopefully easy to extend Fixes - Ostinato client is now able to successfully reconnect and talk to the Ostinato server after a disconnect - earlier, if a method had been pending during the disconnect, the communication was not up after a reconnect; pending methods are cleaned up at disconnect now --- rpc/pbrpcchannel.cpp | 9 + rpc/pbrpccontroller.h | 2 + server/abstractport.cpp | 214 ++++++ server/abstractport.h | 82 +++ server/drone.pro | 10 +- server/drone.qrc | 5 + server/myservice.cpp | 1442 ++++++++------------------------------- server/myservice.h | 331 +++------ server/pcapextra.cpp | 116 +--- server/pcapextra.h | 34 +- server/pcapport.cpp | 407 +++++++++++ server/pcapport.h | 121 ++++ server/portmanager.cpp | 57 ++ server/portmanager.h | 26 + server/winpcapport.cpp | 144 ++++ server/winpcapport.h | 31 + 16 files changed, 1469 insertions(+), 1562 deletions(-) create mode 100644 server/abstractport.cpp create mode 100644 server/abstractport.h create mode 100644 server/drone.qrc create mode 100644 server/pcapport.cpp create mode 100644 server/pcapport.h create mode 100644 server/portmanager.cpp create mode 100644 server/portmanager.h create mode 100644 server/winpcapport.cpp create mode 100644 server/winpcapport.h diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index 9d5be05..f99c00b 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -290,6 +290,15 @@ void PbRpcChannel::on_mpSocket_connected() void PbRpcChannel::on_mpSocket_disconnected() { qDebug("In %s", __FUNCTION__); + + pendingMethodId = -1; + controller = NULL; + response = NULL; + isPending = false; + // \todo convert parsing from static to data member + //parsing = false + pendingCallList.clear(); + emit disconnected(); } diff --git a/rpc/pbrpccontroller.h b/rpc/pbrpccontroller.h index acc9520..916cb95 100644 --- a/rpc/pbrpccontroller.h +++ b/rpc/pbrpccontroller.h @@ -3,6 +3,8 @@ #include +class QIODevice; + class PbRpcController : public ::google::protobuf::RpcController { bool failed; diff --git a/server/abstractport.cpp b/server/abstractport.cpp new file mode 100644 index 0000000..8cbecd9 --- /dev/null +++ b/server/abstractport.cpp @@ -0,0 +1,214 @@ +#include "abstractport.h" + +#include +#include + +#include "../common/streambase.h" + +AbstractPort::AbstractPort(int id, const char *device) +{ + data_.mutable_port_id()->set_id(id); + data_.set_name(QString("if%1 ").arg(id).toStdString()); + + //! \todo (LOW) admin enable/disable of port + data_.set_is_enabled(true); + + //! \todo (HIGH) port exclusive control + data_.set_is_exclusive_control(false); + + isSendQueueDirty_ = true; + linkState_ = OstProto::LinkStateUnknown; + + memset((void*) &stats_, 0, sizeof(stats_)); + resetStats(); +} + +void AbstractPort::init() +{ +} + +AbstractPort::~AbstractPort() +{ +} + +StreamBase* AbstractPort::stream(int streamId) +{ + for (int i = 0; i < streamList_.size(); i++) + { + if (streamId == streamList_.at(i)->id()) + return streamList_.at(i); + } + + return NULL; +} + +bool AbstractPort::addStream(StreamBase *stream) +{ + streamList_.append(stream); + isSendQueueDirty_ = true; + return true; +} + +bool AbstractPort::deleteStream(int streamId) +{ + for (int i = 0; i < streamList_.size(); i++) + { + StreamBase *stream; + + if (streamId == streamList_.at(i)->id()) + { + stream = streamList_.takeAt(i); + delete stream; + + isSendQueueDirty_ = true; + return true; + } + } + + return false; +} + +void AbstractPort::updatePacketList() +{ + int len; + bool isVariable; + uchar pktBuf[2000]; + long sec; + long usec; + + qDebug("In %s", __FUNCTION__); + + clearPacketList(); + //returnToQIdx = -1; + + // First sort the streams by ordinalValue + qSort(streamList_); + + sec = 0; + usec = 0; + for (int i = 0; i < streamList_.size(); i++) + { +//_restart: + if (streamList_[i]->isEnabled()) + { + long numPackets, numBursts; + long ibg, ipg; + + switch (streamList_[i]->sendUnit()) + { + case OstProto::StreamControl::e_su_bursts: + numBursts = streamList_[i]->numBursts(); + numPackets = streamList_[i]->burstSize(); + ibg = 1000000/streamList_[i]->burstRate(); + ipg = 0; + break; + case OstProto::StreamControl::e_su_packets: + numBursts = 1; + numPackets = streamList_[i]->numPackets(); + ibg = 0; + ipg = 1000000/streamList_[i]->packetRate(); + break; + default: + qWarning("Unhandled stream control unit %d", + streamList_[i]->sendUnit()); + continue; + } + qDebug("numBursts = %ld, numPackets = %ld\n", + numBursts, numPackets); + qDebug("ibg = %ld, ipg = %ld\n", ibg, ipg); + + if (streamList_[i]->isFrameVariable()) + { + isVariable = true; + } + else + { + isVariable = false; + len = streamList_[i]->frameValue(pktBuf, sizeof(pktBuf), 0); + } + + for (int j = 0; j < numBursts; j++) + { + for (int k = 0; k < numPackets; k++) + { + if (isVariable) + { + len = streamList_[i]->frameValue(pktBuf, + sizeof(pktBuf), j * numPackets + k); + } + if (len <= 0) + continue; + + usec += ipg; + if (usec > 1000000) + { + sec++; + usec -= 1000000; + } + + qDebug("q(%d, %d, %d) sec = %lu usec = %lu", + i, j, k, sec, usec); + + appendToPacketList(sec, usec, pktBuf, len); + + } // for (numPackets) + + usec += ibg; + if (usec > 1000000) + { + sec++; + usec -= 1000000; + } + } // for (numBursts) + + switch(streamList_[i]->nextWhat()) + { + case ::OstProto::StreamControl::e_nw_stop: + goto _stop_no_more_pkts; + + case ::OstProto::StreamControl::e_nw_goto_id: + /*! \todo (MED): define and use + streamList_[i].d.control().goto_stream_id(); */ + + /*! \todo (MED): assumes goto Id is less than current!!!! + To support goto to any id, do + if goto_id > curr_id then + i = goto_id; + goto restart; + else + returnToQIdx = 0; + */ + + setPacketListLoopMode(true); + goto _stop_no_more_pkts; + + case ::OstProto::StreamControl::e_nw_goto_next: + break; + + default: + qFatal("---------- %s: Unhandled case (%d) -----------", + __FUNCTION__, streamList_[i]->nextWhat() ); + break; + } + + } // if (stream is enabled) + } // for (numStreams) + +_stop_no_more_pkts: + isSendQueueDirty_ = false; +} + +void AbstractPort::stats(PortStats *stats) +{ + stats->rxPkts = stats_.rxPkts - epochStats_.rxPkts; + stats->rxBytes = stats_.rxBytes - epochStats_.rxBytes; + stats->rxPps = stats_.rxPps; + stats->rxBps = stats_.rxBps; + + stats->txPkts = stats_.txPkts - epochStats_.txPkts; + stats->txBytes = stats_.txBytes - epochStats_.txBytes; + stats->txPps = stats_.txPps; + stats->txBps = stats_.txBps; +} + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/abstractport.h b/server/abstractport.h new file mode 100644 index 0000000..6c0bcc3 --- /dev/null +++ b/server/abstractport.h @@ -0,0 +1,82 @@ +#ifndef _SERVER_ABSTRACT_PORT_H +#define _SERVER_ABSTRACT_PORT_H + +#include +#include + +#include "../common/protocol.pb.h" + +class StreamBase; +class QIODevice; + +class AbstractPort +{ +public: + struct PortStats + { + quint64 rxPkts; + quint64 rxBytes; + quint64 rxPps; + quint64 rxBps; + + quint64 txPkts; + quint64 txBytes; + quint64 txPps; + quint64 txBps; + }; + + AbstractPort(int id, const char *device); + virtual ~AbstractPort(); + + virtual void init(); + + int id() { return data_.port_id().id(); } + void protoDataCopyInto(OstProto::Port *port) { port->CopyFrom(data_); } + + int streamCount() { return streamList_.size(); } + StreamBase* stream(int streamId); + bool addStream(StreamBase *stream); + bool deleteStream(int streamId); + + bool isDirty() { return isSendQueueDirty_; } + void setDirty() { isSendQueueDirty_ = true; } + + virtual OstProto::LinkState linkState() { return linkState_; } + + virtual void clearPacketList() = 0; + virtual bool appendToPacketList(long sec, long usec, const uchar *packet, + int length) = 0; + virtual void setPacketListLoopMode(bool loop) = 0; + void updatePacketList(); + + virtual void startTransmit() = 0; + virtual void stopTransmit() = 0; + virtual bool isTransmitOn() = 0; + + virtual void startCapture() = 0; + virtual void stopCapture() = 0; + virtual bool isCaptureOn() = 0; + virtual QIODevice* captureData() = 0; + + void stats(PortStats *stats); + void resetStats() { epochStats_ = stats_; } + +protected: + OstProto::Port data_; + OstProto::LinkState linkState_; + + struct PortStats stats_; + //! \todo Need lock for stats access/update + +private: + bool isSendQueueDirty_; + /*! \note StreamBase::id() and index into streamList[] are NOT same! */ + QList streamList_; + + struct PortStats epochStats_; + +}; + +#endif + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/drone.pro b/server/drone.pro index a5cd2bb..fe06b4e 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -3,18 +3,24 @@ CONFIG += qt debug QT += network script DEFINES += HAVE_REMOTE WPCAP INCLUDEPATH += "../rpc" -LIBS += -lprotobuf win32:LIBS += -lwpcap -lpacket unix:LIBS += -lpcap win32:LIBS += -L"../common/debug" -lostproto unix:LIBS += -L"../common" -lostproto win32:LIBS += -L"../rpc/debug" -lpbrpc unix:LIBS += -L"../rpc" -lpbrpc +LIBS += -lprotobuf POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" RESOURCES += drone.qrc HEADERS += drone.h FORMS += drone.ui -SOURCES += drone_main.cpp drone.cpp +SOURCES += \ + drone_main.cpp \ + drone.cpp \ + portmanager.cpp \ + abstractport.cpp \ + pcapport.cpp \ + winpcapport.cpp SOURCES += myservice.cpp SOURCES += pcapextra.cpp diff --git a/server/drone.qrc b/server/drone.qrc new file mode 100644 index 0000000..a642656 --- /dev/null +++ b/server/drone.qrc @@ -0,0 +1,5 @@ + + + icons/portgroup.png + + diff --git a/server/myservice.cpp b/server/myservice.cpp index 1fa13af..e742fe6 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -1,1301 +1,423 @@ +#include "myservice.h" + +#if 0 #include #include #include "qdebug.h" -#include "myservice.h" #include "../common/protocollistiterator.h" #include "../common/abstractprotocol.h" +#endif +#include "../common/streambase.h" #include "../rpc/pbrpccontroller.h" - -#if 0 -#include -#include -#endif - -#define LOG(...) {} -#define MB (1024*1024) - -StreamInfo::StreamInfo() -{ -} - -StreamInfo::~StreamInfo() -{ -} - -// -// ------------------ PortInfo -------------------- -// -PortInfo::PortInfo(uint id, pcap_if_t *dev) - : monitorRx(this), monitorTx(this), transmitter(this), capturer(this) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - - this->dev = dev; - -#ifdef Q_OS_WIN32 - adapter = PacketOpenAdapter(dev->name); - if (!adapter) - qFatal("Unable to open adapter %s", dev->name); - oidData = (PPACKET_OID_DATA) malloc(sizeof(PACKET_OID_DATA) + sizeof(uint)); - if (oidData) - { - memset(oidData, 0, sizeof(PACKET_OID_DATA) + sizeof(uint)); - oidData->Length=sizeof(uint); - } - else - qFatal("failed to alloc oidData"); -#endif - - /* - * Get 2 device handles - one for rx and one for tx. If we use only - * one handle for both rx and tx anythin that we tx using the single - * handle is not received back to us - */ - devHandleRx = pcap_open_live(dev->name, 0, PCAP_OPENFLAG_PROMISCUOUS , - 1000 /*ms*/, errbuf); - if (devHandleRx == NULL) - { - qDebug("Error opening port %s: %s\n", - dev->name, pcap_geterr(devHandleRx)); - } - -#if 0 - if (pcap_setdirection(devHandleRx, PCAP_D_IN)<0) - { - qDebug("[%s] Error setting direction inbound only\n", dev->name); - } -#endif - - /* By default, put the interface in statistics mode */ - if (pcap_setmode(devHandleRx, MODE_STAT)<0) - { - qDebug("Error setting statistics mode.\n"); - } - - devHandleTx = pcap_open_live(dev->name, 0, PCAP_OPENFLAG_PROMISCUOUS , - 1000 /*ms*/, errbuf); - if (devHandleTx == NULL) - { - qDebug("Error opening port %s: %s\n", - dev->name, pcap_geterr(devHandleTx)); - } - -#if 0 - if (pcap_setdirection(devHandleTx, PCAP_D_OUT)<0) - { - qDebug("[%s] Error setting direction outbound only\n", dev->name); - } -#endif - - /* By default, put the interface in statistics mode */ - if (pcap_setmode(devHandleTx, MODE_STAT)<0) - { - qDebug("Error setting statistics mode.\n"); - } - - d.mutable_port_id()->set_id(id); - -#ifdef Q_OS_WIN32 - d.set_name(QString("if%1 ").arg(id).toAscii().constData()); -#else - if (dev->name) - d.set_name(dev->name); - else - d.set_name(QString("if%1 ").arg(id).toAscii().constData()); -#endif - d.set_name(d.name()+"{"+ - pcap_datalink_val_to_name(pcap_datalink(devHandleRx))+"}"); - - if (dev->description) - d.set_description(dev->description); - d.set_is_enabled(true); //! \todo (LOW) admin enable/disable of port - d.set_is_exclusive_control(false); //! \todo (HIGH) port exclusive control - - memset((void*) &stats, 0, sizeof(stats)); - resetStats(); - - linkState = OstProto::LinkStateUnknown; - - // We'll create sendqueue later when required - sendQueueList.clear(); - returnToQIdx = -1; - pcapExtra.txPkts = 0; - pcapExtra.txBytes = 0; - isSendQueueDirty=true; - - // Start the monitor thread - monitorRx.start(); - monitorTx.start(); -} - -void PortInfo::updateLinkState() -{ -#ifdef Q_OS_WIN32 - OstProto::LinkState newLinkState - = OstProto::LinkStateUnknown; - - memset(oidData, 0, sizeof(PACKET_OID_DATA) + sizeof(uint)); - oidData->Oid = OID_GEN_MEDIA_CONNECT_STATUS; - oidData->Length = sizeof(uint); - if (PacketRequest(adapter, 0, oidData)) - { - uint state; - - if (oidData->Length == sizeof(state)) - { - memcpy((void*)&state, (void*)oidData->Data, oidData->Length); - if (state == 0) - newLinkState = OstProto::LinkStateUp; - else if (state == 1) - newLinkState = OstProto::LinkStateDown; - } - } - - linkState = newLinkState; -#elif defined(Q_OS_LINUX) - //! \todo (HI) implement link state for linux - get from /proc maybe? -#endif -} - -void PortInfo::update() -{ - int len; - bool isVariable; - uchar pktBuf[2000]; - pcap_pkthdr pktHdr; - ost_pcap_send_queue sendQ; - - qDebug("In %s", __FUNCTION__); - - if (sendQueueList.size()) - { - foreach(sendQ, sendQueueList) - pcap_sendqueue_destroy(sendQ.sendQueue); - } - sendQueueList.clear(); - returnToQIdx = -1; - - //! \todo (LOW): calculate sendqueue size - sendQ.sendQueue = pcap_sendqueue_alloc(1*MB); - sendQ.sendQueueCumLen.clear(); - - // First sort the streams by ordinalValue - qSort(streamList); - - pktHdr.ts.tv_sec = 0; - pktHdr.ts.tv_usec = 0; - for (int i = 0; i < streamList.size(); i++) - { -//_restart: - if (streamList[i]->isEnabled()) - { - long numPackets, numBursts; - long ibg, ipg; - - switch (streamList[i]->sendUnit()) - { - case OstProto::StreamControl::e_su_bursts: - numBursts = streamList[i]->numBursts(); - numPackets = streamList[i]->burstSize(); - ibg = 1000000/streamList[i]->burstRate(); - ipg = 0; - break; - case OstProto::StreamControl::e_su_packets: - numBursts = 1; - numPackets = streamList[i]->numPackets(); - ibg = 0; - ipg = 1000000/streamList[i]->packetRate(); - break; - default: - qWarning("Unhandled stream control unit %d", - streamList[i]->sendUnit()); - continue; - } - qDebug("numBursts = %ld, numPackets = %ld\n", - numBursts, numPackets); - qDebug("ibg = %ld, ipg = %ld\n", ibg, ipg); - - if (streamList[i]->isFrameVariable()) - { - isVariable = true; - } - else - { - isVariable = false; - len = streamList[i]->frameValue(pktBuf, sizeof(pktBuf), 0); - } - - for (int j = 0; j < numBursts; j++) - { - for (int k = 0; k < numPackets; k++) - { - if (isVariable) - { - len = streamList[i]->frameValue(pktBuf, sizeof(pktBuf), - j * numPackets + k); - } - if (len > 0) - { - pktHdr.caplen = pktHdr.len = len; - pktHdr.ts.tv_usec += ipg; - if (pktHdr.ts.tv_usec > 1000000) - { - pktHdr.ts.tv_sec++; - pktHdr.ts.tv_usec -= 1000000; - } - - // Not enough space? Alloc another one! - if ((sendQ.sendQueue->len + len + sizeof(pcap_pkthdr)) - > sendQ.sendQueue->maxlen) - { - sendQueueList.append(sendQ); - - //! \todo (LOW): calculate sendqueue size - sendQ.sendQueue = pcap_sendqueue_alloc(1*MB); - sendQ.sendQueueCumLen.clear(); - -#if 0 - pktHdr.ts.tv_sec = 0; - pktHdr.ts.tv_usec = 0; -#endif - } - - qDebug("q(%d, %d, %d) sec = %lu usec = %lu", - i, j, k, pktHdr.ts.tv_sec, pktHdr.ts.tv_usec); - - if (-1 == pcap_sendqueue_queue(sendQ.sendQueue, &pktHdr, - (u_char*) pktBuf)) - { - qDebug("[port %d] sendqueue_queue() failed for " - "streamidx %d\n", id(), i); - } - else - sendQ.sendQueueCumLen.append(sendQ.sendQueue->len); - } - } // for (numPackets) - pktHdr.ts.tv_usec += ibg; - if (pktHdr.ts.tv_usec > 1000000) - { - pktHdr.ts.tv_sec++; - pktHdr.ts.tv_usec -= 1000000; - } - } // for (numBursts) - - switch(streamList[i]->nextWhat()) - { - case ::OstProto::StreamControl::e_nw_stop: - goto _stop_no_more_pkts; - - case ::OstProto::StreamControl::e_nw_goto_id: - /*! \todo (MED): define and use - streamList[i].d.control().goto_stream_id(); */ - - /*! \todo (MED): assumes goto Id is less than current!!!! - To support goto to any id, do - if goto_id > curr_id then - i = goto_id; - goto restart; - else - returnToQIdx = 0; - */ - - returnToQIdx=0; - goto _stop_no_more_pkts; - - case ::OstProto::StreamControl::e_nw_goto_next: - break; - - default: - qFatal("---------- %s: Unhandled case (%d) -----------", - __FUNCTION__, streamList[i]->nextWhat() ); - break; - } - - } // if (stream is enabled) - } // for (numStreams) - -_stop_no_more_pkts: - // The last alloc'ed sendQ appended here - sendQueueList.append(sendQ); - - isSendQueueDirty = false; -} - -void PortInfo::startTransmit() -{ - transmitter.start(); -} - -void PortInfo::stopTransmit() -{ - transmitter.stop(); -} - -void PortInfo::startCapture() -{ - capturer.start(); -} - -void PortInfo::stopCapture() -{ - capturer.stop(); -} - -QFile* PortInfo::captureFile() -{ - return capturer.captureFile(); -} - -void PortInfo::resetStats() -{ - memcpy((void*) &epochStats, (void*) &stats, sizeof(stats)); -} - -// -// ------------------ PortMonitor ------------------- -// - -PortInfo::PortMonitorRx::PortMonitorRx(PortInfo *port) -{ - this->port = port; -#ifdef Q_OS_WIN32 - { - int sz = sizeof(PACKET_OID_DATA) + sizeof(quint64) + 4; - //oidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, - //sizeof(PACKET_OID_DATA) + sizeof(quint64) - 1); - oidData = (PPACKET_OID_DATA) malloc(sz); - if (oidData) - { - memset(oidData, 0, sz); - oidData->Length=sizeof(quint64); - } - else - qFatal("failed to alloc oidData"); - } -#endif -} - -PortInfo::PortMonitorTx::PortMonitorTx(PortInfo *port) -{ - this->port = port; -#ifdef Q_OS_WIN32 - { - int sz = sizeof(PACKET_OID_DATA) + sizeof(quint64) + 4; - //oidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, - //sizeof(PACKET_OID_DATA) + sizeof(quint64) - 1); - oidData = (PPACKET_OID_DATA) malloc(sz); - if (oidData) - { - memset(oidData, 0, sz); - oidData->Length=sizeof(quint64); - } - else - qFatal("failed to alloc oidData"); - } -#endif -} - -#ifdef Q_OS_WIN32 -void PortInfo::PortMonitorRx::callbackRx(u_char *state, - const struct pcap_pkthdr *header, const u_char *pkt_data) -{ - // This is the WinPcap Callback - which is a 'stats mode' callback - - uint usec; - PortInfo *port = (PortInfo*) state; - - quint64 pkts; - quint64 bytes; - - // Update RxStats and RxRates using PCAP data - pkts = *((quint64*)(pkt_data + 0)); - bytes = *((quint64*)(pkt_data + 8)); - -#if 0 - if (port->id() == 2) - qDebug("# %llu", pkts); -#endif - - // Note: PCAP reported bytes includes ETH_FRAME_HDR_SIZE - adjust for it - bytes -= pkts * ETH_FRAME_HDR_SIZE; - - usec = (header->ts.tv_sec - port->lastTsRx.tv_sec) * 1000000 + - (header->ts.tv_usec - port->lastTsRx.tv_usec); - port->stats.rxPps = (pkts * 1000000) / usec; - port->stats.rxBps = (bytes * 1000000) / usec; - - port->stats.rxPkts += pkts; - port->stats.rxBytes += bytes; - - // Store curr timestamp as last timestamp - port->lastTsRx.tv_sec = header->ts.tv_sec; - port->lastTsRx.tv_usec = header->ts.tv_usec; - -#if 0 - for (int i=0; i < 16; i++) - { - qDebug("%02x ", pkt_data[i]); - } - qDebug("{%d: %llu, %llu}\n", port->id(), - pkts, bytes); - qDebug("[%d: pkts : %llu]\n", port->id(), port->stats.rxPkts); - qDebug("[%d: bytes: %llu]\n", port->id(), port->stats.rxBytes); -#endif - - // Retreive NIC stats -#if 0 - port->monitorRx.oidData->Oid = OID_GEN_RCV_OK; - if (PacketRequest(port->devHandleRx->adapter, 0, port->monitorRx.oidData)) - { - if (port->monitorRx.oidData->Length <= sizeof(port->stats.rxPktsNic)) - memcpy((void*)&port->stats.rxPktsNic, - (void*)port->monitorRx.oidData->Data, - port->monitorRx.oidData->Length); - } -#endif -} -void PortInfo::PortMonitorTx::callbackTx(u_char *state, - const struct pcap_pkthdr *header, const u_char *pkt_data) -{ - // This is the WinPcap Callback - which is a 'stats mode' callback - - uint usec; - PortInfo *port = (PortInfo*) state; - - quint64 pkts; - quint64 bytes; - - -#if 0 - // Update RxStats and RxRates using PCAP data - pkts = *((quint64*)(pkt_data + 0)); - bytes = *((quint64*)(pkt_data + 8)); - -#if 0 - if (port->id() == 2) - qDebug("@ %llu", pkts); -#endif - - // Note: PCAP reported bytes includes ETH_FRAME_HDR_SIZE - adjust for it - bytes -= pkts * ETH_FRAME_HDR_SIZE; - - usec = (header->ts.tv_sec - port->lastTsTx.tv_sec) * 1000000 + - (header->ts.tv_usec - port->lastTsTx.tv_usec); - port->stats.txPps = (pkts * 1000000) / usec; - port->stats.txBps = (bytes * 1000000) / usec; - - port->stats.txPkts += pkts; - port->stats.txBytes += bytes; -#endif - - // Since WinPCAP (due to NDIS limitation) cannot distinguish between - // rx/tx packets, pcap stats are not of much use - for the tx stats - // update from PcapExtra - - pkts = port->pcapExtra.txPkts - port->stats.txPkts; - bytes = port->pcapExtra.txBytes - port->stats.txBytes; - - // Use the pcap timestamp for rate calculation though - usec = (header->ts.tv_sec - port->lastTsTx.tv_sec) * 1000000 + - (header->ts.tv_usec - port->lastTsTx.tv_usec); - port->stats.txPps = (pkts * 1000000) / usec; - port->stats.txBps = (bytes * 1000000) / usec; - - port->stats.txPkts = port->pcapExtra.txPkts; - port->stats.txBytes = port->pcapExtra.txBytes; - - // Store curr timestamp as last timestamp - port->lastTsTx.tv_sec = header->ts.tv_sec; - port->lastTsTx.tv_usec = header->ts.tv_usec; - -#if 0 - for (int i=0; i < 16; i++) - { - qDebug("%02x ", pkt_data[i]); - } - qDebug("{%d: %llu, %llu}\n", port->id(), - pkts, bytes); - qDebug("[%d: pkts : %llu]\n", port->id(), port->stats.rxPkts); - qDebug("[%d: bytes: %llu]\n", port->id(), port->stats.rxBytes); -#endif - - // Retreive NIC stats -#if 0 - port->monitorTx.oidData->Oid = OID_GEN_XMIT_OK; - if (PacketRequest(port->devHandleTx->adapter, 0, port->monitorTx.oidData)) - { - if (port->monitorTx.oidData->Length <= sizeof(port->stats.txPktsNic)) - memcpy((void*)&port->stats.txPktsNic, - (void*)port->monitorTx.oidData->Data, - port->monitorTx.oidData->Length); - } -#endif -} -#else -void PortInfo::PortMonitorRx::callbackRx(u_char *state, - const struct pcap_pkthdr *header, const u_char *pkt_data) -{ - // This is the LibPcap Callback - which is a 'capture mode' callback - // This callback is called once for EVERY packet - - uint usec; - PortInfo *port = (PortInfo*) state; - - quint64 pkts; - quint64 bytes; - - // Update RxStats and RxRates using PCAP data - usec = (header->ts.tv_sec - port->lastTsRx.tv_sec) * 1000000 + - (header->ts.tv_usec - port->lastTsRx.tv_usec); - //! \todo support Rx Pkt/Bit rate on Linux (libpcap callback) -#if 0 - port->stats.rxPps = (pkts * 1000000) / usec; - port->stats.rxBps = (bytes * 1000000) / usec; -#endif - - // Note: For a 'capture callback' PCAP reported bytes DOES NOT include - // ETH_FRAME_HDR_SIZE - so don't adjust for it - port->stats.rxPkts++; - port->stats.rxBytes += header->len; - - // Store curr timestamp as last timestamp - port->lastTsRx.tv_sec = header->ts.tv_sec; - port->lastTsRx.tv_usec = header->ts.tv_usec; -} - -void PortInfo::PortMonitorTx::callbackTx(u_char *state, - const struct pcap_pkthdr *header, const u_char *pkt_data) -{ - // This is the LibPcap Callback - which is a 'capture mode' callback - // This callback is called once for EVERY packet - - uint usec; - PortInfo *port = (PortInfo*) state; - - quint64 pkts; - quint64 bytes; - - // Update TxStats and TxRates using PCAP data - usec = (header->ts.tv_sec - port->lastTsTx.tv_sec) * 1000000 + - (header->ts.tv_usec - port->lastTsTx.tv_usec); - //! \todo support Tx Pkt/Bit rate on Linux (libpcap callback) -#if 0 - port->stats.txPps = (pkts * 1000000) / usec; - port->stats.txBps = (bytes * 1000000) / usec; -#endif - - // Note: For a 'capture callback' PCAP reported bytes DOES NOT include - // ETH_FRAME_HDR_SIZE - so don't adjust for it - - port->stats.txPkts++; - port->stats.txBytes += header->len; - - // Store curr timestamp as last timestamp - port->lastTsTx.tv_sec = header->ts.tv_sec; - port->lastTsTx.tv_usec = header->ts.tv_usec; -} -#endif -void PortInfo::PortMonitorRx::run() -{ - int ret; - - qDebug("before pcap_loop rx \n"); -#if 1 - /* Start the main loop */ - ret = pcap_loop(port->devHandleRx, -1, - &PortInfo::PortMonitorRx::callbackRx, (u_char*) port); - - switch(ret) - { - case 0: - qDebug("Unexpected return from pcap_loop()\n"); - break; - case -1: - qDebug("Unsolicited (error) return from pcap_loop()\n"); - break; - case -2: - qDebug("Solicited return from pcap_loop()\n"); - break; - default: - qDebug("Unknown return value from pcap_loop()\n"); - } -#else - while (1) - { - /* Start the main loop */ - ret = pcap_dispatch(port->devHandleRx, -1, - &PortInfo::PortMonitorRx::callbackRx, (u_char*) port); - - switch(ret) - { - case -1: - qDebug("Unsolicited (error) return from pcap_loop() %s\n", - pcap_geterr(port->devHandleRx)); - break; - case -2: - qDebug("Solicited return from pcap_loop()\n"); - break; - default: - //qDebug("%d pkts rcvd\n", ret); - break; - } - } -#endif -} - -void PortInfo::PortMonitorTx::run() -{ - int ret; - - qDebug("before pcap_loopTx\n"); -#if 1 - /* Start the main loop */ - ret = pcap_loop(port->devHandleTx, -1, - &PortInfo::PortMonitorTx::callbackTx, (u_char*) port); - - switch(ret) - { - case 0: - qDebug("Unexpected return from pcap_loop()\n"); - break; - case -1: - qDebug("Unsolicited (error) return from pcap_loop()\n"); - break; - case -2: - qDebug("Solicited return from pcap_loop()\n"); - break; - default: - qDebug("Unknown return value from pcap_loop()\n"); - } -#else - while (1) - { - /* Start the main loop */ - ret = pcap_dispatch(port->devHandleTx, -1, - &PortInfo::PortMonitorTx::callbackTx, (u_char*) port); - - switch(ret) - { - case -1: - qDebug("Unsolicited (error) return from pcap_loop() %s\n", - pcap_geterr(port->devHandleTx)); - break; - case -2: - qDebug("Solicited return from pcap_loop()\n"); - break; - default: - //qDebug("%d pkts rcvd\n", ret); - break; - } - } -#endif -} - -/*--------------- PortTransmitter ---------------*/ - -PortInfo::PortTransmitter::PortTransmitter(PortInfo *port) -{ - this->port = port; -} - -void PortInfo::PortTransmitter::run() -{ - //! \todo (MED) Stream Mode - continuous: define before implement - - // NOTE1: We can't use pcap_sendqueue_transmit() directly even on Win32 - // 'coz of 2 reasons - there's no way of stopping it before all packets - // in the sendQueue are sent out and secondly, stats are available only - // when all packets have been sent - no periodic updates - // - // NOTE2: Transmit on the Rx Handle so that we can receive it back - // on the Tx Handle to do stats - // - // NOTE3: Update pcapExtra counters - port TxStats will be updated in the - // 'stats callback' function so that both Rx and Tx stats are updated - // together - - m_stop = 0; - ost_pcap_sendqueue_list_transmit(port->devHandleRx, port->sendQueueList, - port->returnToQIdx, true, &m_stop, - &port->pcapExtra.txPkts, &port->pcapExtra.txBytes, - QThread::usleep); - m_stop = 0; -} - -void PortInfo::PortTransmitter::stop() -{ - m_stop = 1; -} - -/*--------------- PortCapture ---------------*/ - -PortInfo::PortCapture::PortCapture(PortInfo *port) -{ - this->port = port; - capHandle = NULL; - dumpHandle = NULL; -} - -PortInfo::PortCapture::~PortCapture() -{ -} - -void PortInfo::PortCapture::run() -{ - int ret; - char errbuf[PCAP_ERRBUF_SIZE]; - - capHandle = pcap_open_live(port->dev->name, 65535, - PCAP_OPENFLAG_PROMISCUOUS, 1000 /* ms */, errbuf); - if (capHandle == NULL) - { - qDebug("Error opening port %s: %s\n", - port->dev->name, pcap_geterr(capHandle)); - return; - } - - if (!capFile.isOpen()) - { - if (!capFile.open()) - qFatal("Unable to open temp cap file"); - } - - qDebug("cap file = %s", capFile.fileName().toAscii().constData()); - dumpHandle = pcap_dump_open(capHandle, - capFile.fileName().toAscii().constData()); - - m_stop = 0; - while (m_stop == 0) - { - struct pcap_pkthdr *hdr; - const uchar *data; - - ret = pcap_next_ex(capHandle, &hdr, &data); - switch (ret) - { - case 1: - pcap_dump((uchar*) dumpHandle, hdr, data); - case 0: - continue; - case -1: - qWarning("%s: error reading packet (%d): %s", - __PRETTY_FUNCTION__, ret, pcap_geterr(capHandle)); - break; - case -2: - default: - qFatal("%s: Unexpected return value %d", __PRETTY_FUNCTION__, ret); - } - } - m_stop = 0; - pcap_dump_close(dumpHandle); - pcap_close(capHandle); - dumpHandle = NULL; - capHandle = NULL; -} - -void PortInfo::PortCapture::stop() -{ - m_stop = 1; -} - -QFile* PortInfo::PortCapture::captureFile() -{ - return &capFile; -} - - -/*--------------- MyService ---------------*/ - -int MyService::getStreamIndex(unsigned int portIdx, - unsigned int streamId) -{ - int i; - - // note: index and id are interchageable for port but not for stream - - Q_ASSERT(portIdx < numPorts); - - for (i = 0; i < portInfo[portIdx]->streamList.size(); i++) - { - if (streamId == portInfo[portIdx]->streamList.at(i)->mStreamId.id()) - goto _found; - } - - qDebug("%s: stream id %d not found", __PRETTY_FUNCTION__, streamId); - return -1; - -_found: - return i; -} +#include "portmanager.h" MyService::MyService() { - pcap_if_t *dev; - int i=0; - char errbuf[PCAP_ERRBUF_SIZE]; + PortManager *portManager = PortManager::instance(); + int n = portManager->portCount(); - // Init Data - numPorts = 0; - alldevs = NULL; - - LOG("Retrieving the device list from the local machine\n"); - if (pcap_findalldevs(&alldevs, errbuf) == -1) - { - LOG("Error in pcap_findalldevs_ex: %s\n", errbuf); - goto _fail; - } - - portInfo.clear(); - /* Count, Populate and Print the list */ - for(i=0, dev=alldevs; dev!=NULL; i++, dev=dev->next) - { - portInfo.append(new PortInfo(i, dev)); - numPorts++; - -#if 1 - LOG("%d. %s", i, dev->name); - if (dev->description) - { - LOG(" (%s)\n", dev->description); - } -#endif - } - - if (i == 0) - { - LOG("\nNo interfaces found! Make sure WinPcap is installed.\n"); - goto _fail; - } - -_fail: - return; + for (int i = 0; i < n; i++) + portInfo.append(portManager->port(i)); } MyService::~MyService() { - pcap_freealldevs(alldevs); } -void MyService::getPortIdList( - ::google::protobuf::RpcController* controller, - const ::OstProto::Void* request, - ::OstProto::PortIdList* response, - ::google::protobuf::Closure* done) +void MyService::getPortIdList(::google::protobuf::RpcController* controller, + const ::OstProto::Void* request, + ::OstProto::PortIdList* response, + ::google::protobuf::Closure* done) { - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - for (uint i = 0; i < numPorts; i++) - { - ::OstProto::PortId *p; + for (int i = 0; i < portInfo.size(); i++) + { + ::OstProto::PortId *p; - p = response->add_port_id(); - p->set_id(portInfo[i]->d.port_id().id()); - } + p = response->add_port_id(); + p->set_id(portInfo[i]->id()); + } - done->Run(); + done->Run(); } void MyService::getPortConfig(::google::protobuf::RpcController* controller, -const ::OstProto::PortIdList* request, -::OstProto::PortConfigList* response, -::google::protobuf::Closure* done) + const ::OstProto::PortIdList* request, + ::OstProto::PortConfigList* response, + ::google::protobuf::Closure* done) { - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - for (int i=0; i < request->port_id_size(); i++) - { - unsigned int idx; + for (int i = 0; i < request->port_id_size(); i++) + { + int id; - idx = request->port_id(i).id(); - if (idx < numPorts) - { - OstProto::Port *p; + id = request->port_id(i).id(); + if (id < portInfo.size()) + { + OstProto::Port *p; - p = response->add_port(); - p->CopyFrom(portInfo[idx]->d); - } - } + p = response->add_port(); + portInfo[id]->protoDataCopyInto(p); + } + } - done->Run(); + done->Run(); } void MyService::getStreamIdList(::google::protobuf::RpcController* controller, -const ::OstProto::PortId* request, -::OstProto::StreamIdList* response, -::google::protobuf::Closure* done) + const ::OstProto::PortId* request, + ::OstProto::StreamIdList* response, + ::google::protobuf::Closure* done) { - unsigned int portIdx; + int portId; - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - portIdx = request->id(); - if (portIdx >= numPorts) - { - qDebug("%s: Invalid port id %d", __PRETTY_FUNCTION__, portIdx); - controller->SetFailed("Invalid Port Id"); - goto _exit; //! \todo (LOW): Partial status of RPC - } + portId = request->id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; - response->mutable_port_id()->set_id(portIdx); - for (int j = 0; j < portInfo[portIdx]->streamList.size(); j++) - { - OstProto::StreamId *s; + response->mutable_port_id()->set_id(portId); + for (int i = 0; i < portInfo[portId]->streamCount(); i++) + { + OstProto::StreamId *s; - s = response->add_stream_id(); - s->CopyFrom(portInfo[portIdx]->streamList[j]->mStreamId); - } + s = response->add_stream_id(); + s->set_id(portInfo[portId]->stream(i)->id()); + } + done->Run(); + return; -_exit: - done->Run(); +_invalid_port: + controller->SetFailed("Invalid Port Id"); + done->Run(); } void MyService::getStreamConfig(::google::protobuf::RpcController* controller, -const ::OstProto::StreamIdList* request, -::OstProto::StreamConfigList* response, -::google::protobuf::Closure* done) + const ::OstProto::StreamIdList* request, + ::OstProto::StreamConfigList* response, + ::google::protobuf::Closure* done) { - unsigned int portIdx; + int portId; - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - portIdx = request->port_id().id(); - if (portIdx >= numPorts) - { - controller->SetFailed("invalid portid"); - goto _exit; - } + portId = request->port_id().id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; - response->mutable_port_id()->set_id(portIdx); - for (int i = 0; i < request->stream_id_size(); i++) - { - int streamIndex; - OstProto::Stream *s; + response->mutable_port_id()->set_id(portId); + for (int i = 0; i < request->stream_id_size(); i++) + { + StreamBase *stream; + OstProto::Stream *s; - streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); - if (streamIndex < 0) - continue; //! \todo(LOW): Partial status of RPC + stream = portInfo[portId]->stream(request->stream_id(i).id()); + if (!stream) + continue; //! \todo(LOW): Partial status of RPC - s = response->add_stream(); + s = response->add_stream(); + stream->protoDataCopyInto(*s); + } + done->Run(); + return; - portInfo[portIdx]->streamList[streamIndex]->protoDataCopyInto(*s); - } - -_exit: - done->Run(); +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); } void MyService::addStream(::google::protobuf::RpcController* controller, -const ::OstProto::StreamIdList* request, -::OstProto::Ack* response, -::google::protobuf::Closure* done) + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) { - unsigned int portIdx; + int portId; - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - portIdx = request->port_id().id(); - if (portIdx >= numPorts) - { - controller->SetFailed("invalid portid"); - goto _exit; - } + portId = request->port_id().id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; - for (int i = 0; i < request->stream_id_size(); i++) - { - int streamIndex; - StreamInfo *s = new StreamInfo; + for (int i = 0; i < request->stream_id_size(); i++) + { + StreamBase *stream; - // If stream with same id as in request exists already ==> error!! - streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); - if (streamIndex >= 0) - continue; //! \todo (LOW): Partial status of RPC + // If stream with same id as in request exists already ==> error!! + stream = portInfo[portId]->stream(request->stream_id(i).id()); + if (stream) + continue; //! \todo (LOW): Partial status of RPC - // Append a new "default" stream - actual contents of the new stream is - // expected in a subsequent "modifyStream" request - set the stream id - // now itself however!!! - s->mStreamId.CopyFrom(request->stream_id(i)); - portInfo[portIdx]->streamList.append(s); + // Append a new "default" stream - actual contents of the new stream is + // expected in a subsequent "modifyStream" request - set the stream id + // now itself however!!! + stream = new StreamBase; + stream->setId(request->stream_id(i).id()); + portInfo[portId]->addStream(stream); - //! \todo (LOW): fill-in response "Ack"???? - } - portInfo[portIdx]->setDirty(true); -_exit: - done->Run(); + } + + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); + return; + +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); } void MyService::deleteStream(::google::protobuf::RpcController* controller, -const ::OstProto::StreamIdList* request, -::OstProto::Ack* response, -::google::protobuf::Closure* done) + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) { - unsigned int portIdx; + int portId; - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - portIdx = request->port_id().id(); - if (portIdx >= numPorts) - { - controller->SetFailed("invalid portid"); - goto _exit; - } + portId = request->port_id().id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; - for (int i = 0; i < request->stream_id_size(); i++) - { - int streamIndex; - StreamInfo s; + for (int i = 0; i < request->stream_id_size(); i++) + portInfo[portId]->deleteStream(request->stream_id(i).id()); - streamIndex = getStreamIndex(portIdx, request->stream_id(i).id()); - if (streamIndex < 0) - continue; //! \todo (LOW): Partial status of RPC + //! \todo (LOW): fill-in response "Ack"???? - delete portInfo[portIdx]->streamList.takeAt(streamIndex); + done->Run(); + return; - //! \todo (LOW): fill-in response "Ack"???? - } - portInfo[portIdx]->setDirty(true); -_exit: - done->Run(); +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); } void MyService::modifyStream(::google::protobuf::RpcController* controller, -const ::OstProto::StreamConfigList* request, -::OstProto::Ack* response, -::google::protobuf::Closure* done) + const ::OstProto::StreamConfigList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) { - unsigned int portIdx; + int portId; - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - portIdx = request->port_id().id(); - if (portIdx >= numPorts) - { - controller->SetFailed("invalid portid"); - goto _exit; - } + portId = request->port_id().id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; - for (int i = 0; i < request->stream_size(); i++) - { - int streamIndex; + for (int i = 0; i < request->stream_size(); i++) + { + StreamBase *stream; - streamIndex = getStreamIndex(portIdx, - request->stream(i).stream_id().id()); - if (streamIndex < 0) - continue; //! \todo (LOW): Partial status of RPC + stream = portInfo[portId]->stream(request->stream(i).stream_id().id()); + if (stream) + { + stream->protoDataCopyFrom(request->stream(i)); + portInfo[portId]->setDirty(); + } + } - portInfo[portIdx]->streamList[streamIndex]->protoDataCopyFrom( - request->stream(i)); + //! \todo(LOW): fill-in response "Ack"???? - //! \todo(LOW): fill-in response "Ack"???? - } - portInfo[portIdx]->setDirty(true); -_exit: - done->Run(); + done->Run(); + return; + +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); } void MyService::startTx(::google::protobuf::RpcController* controller, -const ::OstProto::PortIdList* request, -::OstProto::Ack* response, -::google::protobuf::Closure* done) + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) { - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - // If any of the ports in the request are dirty, first update them - for (int i=0; i < request->port_id_size(); i++) - { - uint portIdx; + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; - portIdx = request->port_id(i).id(); - if (portIdx >= numPorts) - continue; //! \todo (LOW): partial RPC? + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? - if (portInfo[portIdx]->isDirty()) - portInfo[portIdx]->update(); - } + portInfo[portId]->startTransmit(); + } - for (int i=0; i < request->port_id_size(); i++) - { - uint portIdx; + //! \todo (LOW): fill-in response "Ack"???? - portIdx = request->port_id(i).id(); - if (portIdx >= numPorts) - continue; //! \todo (LOW): partial RPC? - - portInfo[portIdx]->startTransmit(); - } - - //! \todo (LOW): fill-in response "Ack"???? - - done->Run(); + done->Run(); } void MyService::stopTx(::google::protobuf::RpcController* controller, -const ::OstProto::PortIdList* request, -::OstProto::Ack* response, -::google::protobuf::Closure* done) + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) { - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - for (int i=0; i < request->port_id_size(); i++) - { - uint portIdx; + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; - portIdx = request->port_id(i).id(); - if (portIdx >= numPorts) - continue; //! \todo (LOW): partial RPC? + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? - portInfo[portIdx]->stopTransmit(); - } - //! \todo (LOW): fill-in response "Ack"???? - done->Run(); + portInfo[portId]->stopTransmit(); + } + + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); } void MyService::startCapture(::google::protobuf::RpcController* controller, -const ::OstProto::PortIdList* request, -::OstProto::Ack* response, -::google::protobuf::Closure* done) + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) { - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - for (int i=0; i < request->port_id_size(); i++) - { - uint portIdx; + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; - portIdx = request->port_id(i).id(); - if (portIdx >= numPorts) - continue; //! \todo (LOW): partial RPC? + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? - portInfo[portIdx]->startCapture(); - } + portInfo[portId]->startCapture(); + } - done->Run(); + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); } void MyService::stopCapture(::google::protobuf::RpcController* controller, -const ::OstProto::PortIdList* request, -::OstProto::Ack* response, -::google::protobuf::Closure* done) + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) { - qDebug("In %s", __PRETTY_FUNCTION__); - for (int i=0; i < request->port_id_size(); i++) - { - uint portIdx; + qDebug("In %s", __PRETTY_FUNCTION__); + for (int i=0; i < request->port_id_size(); i++) + { + int portId; - portIdx = request->port_id(i).id(); - if (portIdx >= numPorts) - continue; //! \todo (LOW): partial RPC? + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? - portInfo[portIdx]->stopCapture(); - } + portInfo[portId]->stopCapture(); + } - done->Run(); + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); } void MyService::getCaptureBuffer(::google::protobuf::RpcController* controller, -const ::OstProto::PortId* request, -::OstProto::CaptureBuffer* response, -::google::protobuf::Closure* done) + const ::OstProto::PortId* request, + ::OstProto::CaptureBuffer* response, + ::google::protobuf::Closure* done) { - uint portIdx; - qDebug("In %s", __PRETTY_FUNCTION__); + int portId; - portIdx = request->id(); - if (portIdx >= numPorts) - { - controller->SetFailed("invalid portid"); - goto _exit; - } + qDebug("In %s", __PRETTY_FUNCTION__); - portInfo[portIdx]->stopCapture(); - static_cast(controller)->setBinaryBlob( - portInfo[portIdx]->captureFile()); + portId = request->id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; -_exit: - done->Run(); + portInfo[portId]->stopCapture(); + static_cast(controller)->setBinaryBlob( + portInfo[portId]->captureData()); + + done->Run(); + return; + +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); } void MyService::getStats(::google::protobuf::RpcController* controller, -const ::OstProto::PortIdList* request, -::OstProto::PortStatsList* response, -::google::protobuf::Closure* done) + const ::OstProto::PortIdList* request, + ::OstProto::PortStatsList* response, + ::google::protobuf::Closure* done) { - //qDebug("In %s", __PRETTY_FUNCTION__); + //qDebug("In %s", __PRETTY_FUNCTION__); - for (int i=0; i < request->port_id_size(); i++) - { - uint portidx; - ::OstProto::PortStats *s; - OstProto::PortState *st; + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; + AbstractPort::PortStats stats; + OstProto::PortStats *s; + OstProto::PortState *st; - portidx = request->port_id(i).id(); - if (portidx >= numPorts) - continue; //! \todo(LOW): partial rpc? + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo(LOW): partial rpc? - s = response->add_port_stats(); - s->mutable_port_id()->set_id(request->port_id(i).id()); + s = response->add_port_stats(); + s->mutable_port_id()->set_id(request->port_id(i).id()); + + st = s->mutable_state(); + st->set_link_state(portInfo[portId]->linkState()); + st->set_is_transmit_on(portInfo[portId]->isTransmitOn()); + st->set_is_capture_on(portInfo[portId]->isCaptureOn()); + + portInfo[portId]->stats(&stats); #if 0 - if (portidx == 2) - { - qDebug("<%llu", portInfo[portidx]->epochStats.rxPkts); - qDebug(">%llu", portInfo[portidx]->stats.rxPkts); - } + if (portId == 2) + qDebug(">%llu", stats.rxPkts); #endif - portInfo[portidx]->updateLinkState(); + s->set_rx_pkts(stats.rxPkts); + s->set_rx_bytes(stats.rxBytes); + s->set_rx_pps(stats.rxPps); + s->set_rx_bps(stats.rxBps); - st = s->mutable_state(); - st->set_link_state(portInfo[portidx]->linkState); - st->set_is_transmit_on(portInfo[portidx]->transmitter.isRunning()); - st->set_is_capture_on(portInfo[portidx]->capturer.isRunning()); + s->set_tx_pkts(stats.txPkts); + s->set_tx_bytes(stats.txBytes); + s->set_tx_pps(stats.txPps); + s->set_tx_bps(stats.txBps); + } - s->set_rx_pkts(portInfo[portidx]->stats.rxPkts - - portInfo[portidx]->epochStats.rxPkts); - s->set_rx_bytes(portInfo[portidx]->stats.rxBytes - - portInfo[portidx]->epochStats.rxBytes); - s->set_rx_pkts_nic(portInfo[portidx]->stats.rxPktsNic - - portInfo[portidx]->epochStats.rxPktsNic); - s->set_rx_bytes_nic(portInfo[portidx]->stats.rxBytesNic - - portInfo[portidx]->epochStats.rxBytesNic); - s->set_rx_pps(portInfo[portidx]->stats.rxPps); - s->set_rx_bps(portInfo[portidx]->stats.rxBps); - - s->set_tx_pkts(portInfo[portidx]->stats.txPkts - - portInfo[portidx]->epochStats.txPkts); - s->set_tx_bytes(portInfo[portidx]->stats.txBytes - - portInfo[portidx]->epochStats.txBytes); - s->set_tx_pkts_nic(portInfo[portidx]->stats.txPktsNic - - portInfo[portidx]->epochStats.txPktsNic); - s->set_tx_bytes_nic(portInfo[portidx]->stats.txBytesNic - - portInfo[portidx]->epochStats.txBytesNic); - s->set_tx_pps(portInfo[portidx]->stats.txPps); - s->set_tx_bps(portInfo[portidx]->stats.txBps); - } - - done->Run(); + done->Run(); } void MyService::clearStats(::google::protobuf::RpcController* controller, -const ::OstProto::PortIdList* request, -::OstProto::Ack* response, -::google::protobuf::Closure* done) + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) { - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - for (int i=0; i < request->port_id_size(); i++) - { - uint portIdx; + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; - portIdx = request->port_id(i).id(); - if (portIdx >= numPorts) - continue; //! \todo (LOW): partial RPC? + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? - portInfo[portIdx]->resetStats(); - } - //! \todo (LOW): fill-in response "Ack"???? + portInfo[portId]->resetStats(); + } - done->Run(); + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); } +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/myservice.h b/server/myservice.h index 4be1bdb..5d434ee 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -1,264 +1,85 @@ -#ifndef _MY_SERVICE_H -#define _MY_SERVICE_H - - -#if 0 -#include -#include -#endif - -#include "../common/protocol.pb.h" -#include "../common/streambase.h" -#include -#include -#include -#include -#include - -#include "../rpc/pbhelper.h" -#include "pcapextra.h" +#ifndef _MY_SERVICE_H +#define _MY_SERVICE_H -#ifdef Q_OS_WIN32 -#include -#endif +#include -#ifdef Q_OS_WIN32 -#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 -#endif - -#define MAX_PKT_HDR_SIZE 1536 -#define MAX_STREAM_NAME_SIZE 64 - -//! 7 byte Preamble + 1 byte SFD + 4 byte FCS -#define ETH_FRAME_HDR_SIZE 12 - +#include "../common/protocol.pb.h" -class MyService; - -class StreamInfo : public StreamBase -{ - friend class MyService; - friend class PortInfo; - - OstProto::StreamId mStreamId; - +#define MAX_PKT_HDR_SIZE 1536 +#define MAX_STREAM_NAME_SIZE 64 + +class AbstractPort; + +class MyService: public OstProto::OstService +{ public: - StreamInfo(); - ~StreamInfo(); -}; - - -class PortInfo -{ - friend class MyService; - - class PortMonitorRx: public QThread - { - friend class PortInfo; - - PortInfo *port; -#ifdef Q_OS_WIN32 - PPACKET_OID_DATA oidData; -#endif - public: - PortMonitorRx(PortInfo *port); - static void callbackRx(u_char *state, - const struct pcap_pkthdr *header, const u_char *pkt_data); - void run(); - }; + MyService(); + virtual ~MyService(); - class PortMonitorTx: public QThread - { - friend class PortInfo; - - PortInfo *port; -#ifdef Q_OS_WIN32 - PPACKET_OID_DATA oidData; -#endif - public: - PortMonitorTx(PortInfo *port); - static void callbackTx(u_char *state, - const struct pcap_pkthdr *header, const u_char *pkt_data); - void run(); - }; + /* Methods provided by the service */ + virtual void getPortIdList(::google::protobuf::RpcController* controller, + const ::OstProto::Void* request, + ::OstProto::PortIdList* response, + ::google::protobuf::Closure* done); + virtual void getPortConfig(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::PortConfigList* response, + ::google::protobuf::Closure* done); + virtual void getStreamIdList(::google::protobuf::RpcController* controller, + const ::OstProto::PortId* request, + ::OstProto::StreamIdList* response, + ::google::protobuf::Closure* done); + virtual void getStreamConfig(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::StreamConfigList* response, + ::google::protobuf::Closure* done); + virtual void addStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void deleteStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void modifyStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamConfigList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void startTx(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void stopTx(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void startCapture(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void stopCapture(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void getCaptureBuffer(::google::protobuf::RpcController* controller, + const ::OstProto::PortId* request, + ::OstProto::CaptureBuffer* response, + ::google::protobuf::Closure* done); + virtual void getStats(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::PortStatsList* response, + ::google::protobuf::Closure* done); + virtual void clearStats(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); - class PortTransmitter: public QThread - { - friend class PortInfo; +private: + /*! AbstractPort::id() and index into portInfo[] are same! */ + QList portInfo; - PortInfo *port; - int m_stop; +}; - public: - PortTransmitter(PortInfo *port); - void run(); - void stop(); - }; +#endif - class PortCapture: public QThread - { - friend class PortInfo; - - PortInfo *port; - int m_stop; - pcap_t *capHandle; - pcap_dumper_t *dumpHandle; - QTemporaryFile capFile; - - public: - PortCapture(PortInfo *port); - ~PortCapture(); - void run(); - void stop(); - QFile* captureFile(); - }; - -#ifdef Q_OS_WIN32 - LPADAPTER adapter; - PPACKET_OID_DATA oidData; -#endif - - OstProto::Port d; - OstProto::LinkState linkState; - - struct PortStats - { - quint64 rxPkts; - quint64 rxBytes; - quint64 rxPktsNic; - quint64 rxBytesNic; - quint64 rxPps; - quint64 rxBps; - - quint64 txPkts; - quint64 txBytes; - quint64 txPktsNic; - quint64 txBytesNic; - quint64 txPps; - quint64 txBps; - }; - - //! \todo Need lock for stats access/update - - - //! Stuff we need to maintain since PCAP doesn't as of now. As and when - // PCAP supports it, we'll remove from here - struct PcapExtra - { - - //! PCAP doesn't do any tx stats - quint64 txPkts; - quint64 txBytes; - - }; - - pcap_if_t *dev; - pcap_t *devHandleRx; - pcap_t *devHandleTx; - QList sendQueueList; - int returnToQIdx; // FIXME(MED): combine with sendQList - bool isSendQueueDirty; - PcapExtra pcapExtra; - PortMonitorRx monitorRx; - PortMonitorTx monitorTx; - PortTransmitter transmitter; - PortCapture capturer; - - struct PortStats epochStats; - struct PortStats stats; - struct timeval lastTsRx; //! used for Rate Stats calculations - struct timeval lastTsTx; //! used for Rate Stats calculations - - /*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */ - QList streamList; - -public: - PortInfo(uint id, pcap_if_t *dev); - uint id() { return d.port_id().id(); } - void updateLinkState(); - bool isDirty() { return isSendQueueDirty; } - void setDirty(bool dirty) { isSendQueueDirty = dirty; } - void update(); - void startTransmit(); - void stopTransmit(); - void startCapture(); - void stopCapture(); - QFile* captureFile(); - void resetStats(); -}; - - -class MyService: public OstProto::OstService -{ - uint numPorts; - - /*! PortInfo::d::port_id and index into portInfo[] are same! */ - QList portInfo; - pcap_if_t *alldevs; - - int getStreamIndex(unsigned int portIdx,unsigned int streamId); - -public: - MyService(); - virtual ~MyService(); - - /* Methods provided by the service */ - virtual void getPortIdList(::google::protobuf::RpcController* controller, - const ::OstProto::Void* request, - ::OstProto::PortIdList* response, - ::google::protobuf::Closure* done); - virtual void getPortConfig(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::PortConfigList* response, - ::google::protobuf::Closure* done); - virtual void getStreamIdList(::google::protobuf::RpcController* controller, - const ::OstProto::PortId* request, - ::OstProto::StreamIdList* response, - ::google::protobuf::Closure* done); - virtual void getStreamConfig(::google::protobuf::RpcController* controller, - const ::OstProto::StreamIdList* request, - ::OstProto::StreamConfigList* response, - ::google::protobuf::Closure* done); - virtual void addStream(::google::protobuf::RpcController* controller, - const ::OstProto::StreamIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); - virtual void deleteStream(::google::protobuf::RpcController* controller, - const ::OstProto::StreamIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); - virtual void modifyStream(::google::protobuf::RpcController* controller, - const ::OstProto::StreamConfigList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); - virtual void startTx(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); - virtual void stopTx(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); - virtual void startCapture(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); - virtual void stopCapture(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); - virtual void getCaptureBuffer(::google::protobuf::RpcController* controller, - const ::OstProto::PortId* request, - ::OstProto::CaptureBuffer* response, - ::google::protobuf::Closure* done); - virtual void getStats(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::PortStatsList* response, - ::google::protobuf::Closure* done); - virtual void clearStats(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done); -}; - -#endif +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/pcapextra.cpp b/server/pcapextra.cpp index 197e83b..8274d48 100644 --- a/server/pcapextra.cpp +++ b/server/pcapextra.cpp @@ -1,16 +1,11 @@ +#include "pcapextra.h" + #include // memcpy() #include // malloc(), free() -#include "pcapextra.h" /* NOTE: All code borrowed from WinPcap */ #ifndef Q_OS_WIN32 -int pcap_setmode(pcap_t *p, int mode) -{ - // no STAT mode in libpcap, so just return 0 to indicate success - return 0; -} - pcap_send_queue* pcap_sendqueue_alloc (u_int memsize) { pcap_send_queue *tqueue; @@ -61,111 +56,4 @@ int pcap_sendqueue_queue (pcap_send_queue *queue, } #endif -u_int ost_pcap_sendqueue_list_transmit(pcap_t *p, - QList sendQueueList, int returnToQIdx, int sync, - int *p_stop, quint64* p_pkts, quint64* p_bytes, - void (*pf_usleep)(ulong)) -{ - uint i, ret = 0; - ost_pcap_send_queue sq; - - for(i = 0; i < sendQueueList.size(); i++) - { -_restart: - sq = sendQueueList.at(i); - ret += ost_pcap_sendqueue_transmit(p, sq.sendQueue, sync, - p_stop, p_pkts, p_bytes, pf_usleep); - - if (*p_stop) - return ret; - - //! \todo (HIGH): Timing between subsequent sendQueues - } - - if (returnToQIdx >= 0) - { - i = returnToQIdx; - - //! \todo (HIGH) 1s fixed; Change this to ipg of last stream - (*pf_usleep)(1000000); - goto _restart; - } - - return ret; -} - -u_int ost_pcap_sendqueue_transmit(pcap_t *p, - pcap_send_queue *queue, int sync, - int *p_stop, quint64* p_pkts, quint64* p_bytes, - void (*pf_usleep)(ulong)) -{ - char* PacketBuff = queue->buffer; - int Size = queue->len; - - struct pcap_pkthdr *winpcap_hdr; - struct timeval ts; - char* EndOfUserBuff = (char *)PacketBuff + Size; - int ret; - - // Start from the first packet - winpcap_hdr = (struct pcap_pkthdr*)PacketBuff; - - if((char*)winpcap_hdr + winpcap_hdr->caplen + sizeof(struct pcap_pkthdr) > - EndOfUserBuff ) - { - // Malformed buffer - return 0; - } - - if (sync) - ts = winpcap_hdr->ts; - - while( true ){ - - if (*p_stop) - return (char*)winpcap_hdr - (char*)PacketBuff; - - if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > 65536) - { - // Malformed header - return 0; - } - - // Send the packet - ret = pcap_sendpacket(p, - (unsigned char*)winpcap_hdr + sizeof(struct pcap_pkthdr), - winpcap_hdr->caplen); - - if(ret < 0){ - // Error sending the packet - return (char*)winpcap_hdr - (char*)PacketBuff; - } - - if (p_pkts) (*p_pkts)++; - if (p_bytes) (*p_bytes) += winpcap_hdr->caplen; - - // Step to the next packet in the buffer - //(char*)winpcap_hdr += winpcap_hdr->caplen + sizeof(struct pcap_pkthdr); - winpcap_hdr = (struct pcap_pkthdr*) ((char*)winpcap_hdr + - winpcap_hdr->caplen + sizeof(struct pcap_pkthdr)); - - // Check if the end of the user buffer has been reached - if( (char*)winpcap_hdr >= EndOfUserBuff ) - { - return (char*)winpcap_hdr - (char*)PacketBuff; - } - - if (sync) - { - long usec = (winpcap_hdr->ts.tv_sec-ts.tv_sec)*1000000 + - (winpcap_hdr->ts.tv_usec - ts.tv_usec); - - if (usec) - { - (*pf_usleep)(usec); - ts = winpcap_hdr->ts; - } - } - } -} diff --git a/server/pcapextra.h b/server/pcapextra.h index 5c597df..e0dd23b 100644 --- a/server/pcapextra.h +++ b/server/pcapextra.h @@ -1,36 +1,12 @@ #ifndef _PCAP_EXTRA_H #define _PCAP_EXTRA_H -#include -#include - -#include "pcap.h" - -struct ost_pcap_send_queue -{ - pcap_send_queue *sendQueue; - //! Used to track num of packets (and their sizes) in the - // send queue. Also used to find out actual num of pkts sent - // in case of partial send in pcap_sendqueue_transmit() - QList sendQueueCumLen; -}; - -// Common for all OS - *nix or Win32 -u_int ost_pcap_sendqueue_list_transmit(pcap_t *p, - QList sendQueueList, int returnToQIdx, int sync, - int *p_stop, quint64* p_pkts, quint64* p_bytes, - void (*pf_usleep)(ulong)); - -u_int ost_pcap_sendqueue_transmit (pcap_t *p, - pcap_send_queue *queue, int sync, - int *p_stop, quint64* p_pkts, quint64* p_bytes, - void (*pf_usleep)(ulong)); +#include +#include #ifndef Q_OS_WIN32 -// Only for non Win32 - -#define PCAP_OPENFLAG_PROMISCUOUS 1 +//#define PCAP_OPENFLAG_PROMISCUOUS 1 struct pcap_send_queue { @@ -39,15 +15,11 @@ struct pcap_send_queue char *buffer; }; -int pcap_setmode(pcap_t *p, int mode); -#define MODE_STAT 1 - pcap_send_queue* pcap_sendqueue_alloc (u_int memsize); void pcap_sendqueue_destroy (pcap_send_queue *queue); int pcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); - #endif #endif diff --git a/server/pcapport.cpp b/server/pcapport.cpp new file mode 100644 index 0000000..86a5086 --- /dev/null +++ b/server/pcapport.cpp @@ -0,0 +1,407 @@ +#include "pcapport.h" + +pcap_if_t *PcapPort::deviceList_ = NULL; + +PcapPort::PcapPort(int id, const char *device) + : AbstractPort(id, device) +{ + monitorRx_ = new PortMonitor(device, kDirectionRx, &stats_); + monitorTx_ = new PortMonitor(device, kDirectionTx, &stats_); + transmitter_ = new PortTransmitter(device); + capturer_ = new PortCapturer(device); + + if (!deviceList_) + { + char errbuf[PCAP_ERRBUF_SIZE]; + + if (pcap_findalldevs(&deviceList_, errbuf) == -1) + qDebug("Error in pcap_findalldevs_ex: %s\n", errbuf); + } + + for (pcap_if_t *dev = deviceList_; dev != NULL; dev = dev->next) + { + if (strcmp(device, dev->name) == 0) + { + if (dev->description) + data_.set_description(dev->description); + + //! \todo set port IP addr also + } + } +} + +void PcapPort::init() +{ + if (!monitorTx_->isDirectional()) + transmitter_->useExternalStats(&stats_); + + transmitter_->setHandle(monitorRx_->handle()); + + monitorRx_->start(); + monitorTx_->start(); +} + +PcapPort::~PcapPort() +{ + delete capturer_; + delete transmitter_; + delete monitorTx_; + delete monitorRx_; +} + +PcapPort::PortMonitor::PortMonitor(const char *device, Direction direction, + AbstractPort::PortStats *stats) +{ + int ret; + char errbuf[PCAP_ERRBUF_SIZE]; + + direction_ = direction; + isDirectional_ = true; + stats_ = stats; + handle_ = pcap_open_live(device, 64 /* FIXME */, PCAP_OPENFLAG_PROMISCUOUS, + 1000 /* ms */, errbuf); + + if (handle_ == NULL) + goto _open_error; + + switch (direction_) + { + case kDirectionRx: + ret = pcap_setdirection(handle_, PCAP_D_IN); + break; + case kDirectionTx: + ret = pcap_setdirection(handle_, PCAP_D_OUT); + break; + default: + Q_ASSERT(false); + } + + if (ret < 0) + goto _set_direction_error; + + return; + +_set_direction_error: + qDebug("Error setting direction(%d) %s: %s\n", direction, device, + pcap_geterr(handle_)); + isDirectional_ = false; + return; + +_open_error: + qDebug("Error opening port %s: %s\n", device, pcap_geterr(handle_)); +} + +void PcapPort::PortMonitor::run() +{ + while (1) + { + int ret; + struct pcap_pkthdr *hdr; + const uchar *data; + + ret = pcap_next_ex(handle_, &hdr, &data); + switch (ret) + { + case 1: + switch (direction_) + { + case kDirectionRx: + stats_->rxPkts++; + stats_->rxBytes += hdr->len; + break; + + case kDirectionTx: + if (isDirectional_) + { + stats_->txPkts++; + stats_->txBytes += hdr->len; + } + break; + + default: + Q_ASSERT(false); + } + + //! \todo TODO pkt/bit rates + break; + case 0: + //qDebug("%s: timeout. continuing ...", __PRETTY_FUNCTION__); + continue; + case -1: + qWarning("%s: error reading packet (%d): %s", + __PRETTY_FUNCTION__, ret, pcap_geterr(handle_)); + break; + case -2: + default: + qFatal("%s: Unexpected return value %d", __PRETTY_FUNCTION__, ret); + } + } +} + +PcapPort::PortTransmitter::PortTransmitter(const char *device) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + + returnToQIdx_ = -1; + stop_ = false; + stats_ = new AbstractPort::PortStats; + usingInternalStats_ = true; + handle_ = pcap_open_live(device, 64 /* FIXME */, PCAP_OPENFLAG_PROMISCUOUS, + 1000 /* ms */, errbuf); + + if (handle_ == NULL) + goto _open_error; + + usingInternalHandle_ = true; + + return; + +_open_error: + qDebug("Error opening port %s: %s\n", device, pcap_geterr(handle_)); + usingInternalHandle_ = false; +} + +void PcapPort::PortTransmitter::clearPacketList() +{ + Q_ASSERT(!isRunning()); + // \todo lock for sendQueueList + while(sendQueueList_.size()) + { + pcap_send_queue *sq = sendQueueList_.takeFirst(); + pcap_sendqueue_destroy(sq); + } +} + +bool PcapPort::PortTransmitter::appendToPacketList(long sec, long usec, + const uchar *packet, int length) +{ + bool op = true; + pcap_pkthdr pktHdr; + pcap_send_queue *sendQ; + + pktHdr.caplen = pktHdr.len = length; + pktHdr.ts.tv_sec = sec; + pktHdr.ts.tv_usec = usec; + + if (sendQueueList_.size()) + sendQ = sendQueueList_.last(); + else + sendQ = pcap_sendqueue_alloc(1*1024*1024); + + // Not enough space? Alloc another one! + if ((sendQ->len + length + sizeof(pcap_pkthdr)) > sendQ->maxlen) + { + sendQueueList_.append(sendQ); + + //! \todo (LOW): calculate sendqueue size + sendQ = pcap_sendqueue_alloc(1*1024*1024); + } + + if (pcap_sendqueue_queue(sendQ, &pktHdr, (u_char*) packet) < 0) + op = false; + + sendQueueList_.append(sendQ); + return op; +} + +void PcapPort::PortTransmitter::setHandle(pcap_t *handle) +{ + if (usingInternalHandle_) + pcap_close(handle_); + handle_ = handle; + usingInternalStats_ = false; +} + +void PcapPort::PortTransmitter::useExternalStats(AbstractPort::PortStats *stats) +{ + if (usingInternalStats_); + delete stats_; + stats_ = stats; + usingInternalStats_ = false; +} + +void PcapPort::PortTransmitter::run() +{ + //! \todo (MED) Stream Mode - continuous: define before implement + + // NOTE1: We can't use pcap_sendqueue_transmit() directly even on Win32 + // 'coz of 2 reasons - there's no way of stopping it before all packets + // in the sendQueue are sent out and secondly, stats are available only + // when all packets have been sent - no periodic updates + // + // NOTE2: Transmit on the Rx Handle so that we can receive it back + // on the Tx Handle to do stats + // + // NOTE3: Update pcapExtra counters - port TxStats will be updated in the + // 'stats callback' function so that both Rx and Tx stats are updated + // together + + const int kSyncTransmit = 1; + int i; + + for(i = 0; i < sendQueueList_.size(); i++) + { + int ret; +_restart: + ret = sendQueueTransmit(handle_, sendQueueList_.at(i), kSyncTransmit); + + if (ret < 0) + return; + + //! \todo (HIGH): Timing between subsequent sendQueues + } + + if (returnToQIdx_ >= 0) + { + i = returnToQIdx_; + + //! \todo (HIGH) 1s fixed; Change this to ipg of last stream + QThread::usleep(1000000); + goto _restart; + } +} + +void PcapPort::PortTransmitter::stop() +{ + stop_ = true; +} + +int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p, + pcap_send_queue *queue, int sync) +{ + struct timeval ts; + struct pcap_pkthdr *hdr = (struct pcap_pkthdr*) queue->buffer; + char *end = queue->buffer + queue->len; + + if (sync) + ts = hdr->ts; + + while (1) + { + uchar *pkt = (uchar*)hdr + sizeof(*hdr); + int pktLen = hdr->caplen; + + if (stop_) + { + stop_ = false; + return -2; + } + + if(pktLen > 0) + pcap_sendpacket(p, pkt, pktLen); + + stats_->txPkts++; + stats_->txBytes += pktLen; + + // Step to the next packet in the buffer + hdr = (struct pcap_pkthdr*) ((uchar*)hdr + sizeof(*hdr) + pktLen); + pkt = (uchar*) ((uchar*)hdr + sizeof(*hdr)); + + // Check if the end of the user buffer has been reached + if((char*) hdr >= end) + return 0; + + if (sync) + { + long usec = (hdr->ts.tv_sec - ts.tv_sec) * 1000000 + + (hdr->ts.tv_usec - ts.tv_usec); + + if (usec) + { + QThread::usleep(usec); + ts = hdr->ts; + } + } + } +} + +PcapPort::PortCapturer::PortCapturer(const char *device) +{ + device_ = QString::fromAscii(device); + stop_ = false; + + if (!capFile_.open()) + qWarning("Unable to open temp cap file"); + + qDebug("cap file = %s", capFile_.fileName().toAscii().constData()); + + dumpHandle_ = NULL; + handle_ = NULL; +} + +PcapPort::PortCapturer::~PortCapturer() +{ + capFile_.close(); +} + +void PcapPort::PortCapturer::run() +{ + char errbuf[PCAP_ERRBUF_SIZE]; + + qDebug("In %s", __PRETTY_FUNCTION__); + + if (!capFile_.isOpen()) + { + qWarning("temp cap file is not open"); + return; + } + + handle_ = pcap_open_live(device_.toAscii().constData(), 65535, + PCAP_OPENFLAG_PROMISCUOUS, 1000 /* ms */, errbuf); + if (handle_ == NULL) + { + qDebug("Error opening port %s: %s\n", + device_.toAscii().constData(), pcap_geterr(handle_)); + return; + } + + dumpHandle_ = pcap_dump_open(handle_, + capFile_.fileName().toAscii().constData()); + + while (1) + { + int ret; + struct pcap_pkthdr *hdr; + const uchar *data; + + ret = pcap_next_ex(handle_, &hdr, &data); + switch (ret) + { + case 1: + pcap_dump((uchar*) dumpHandle_, hdr, data); + break; + case 0: + // timeout: just go back to the loop + break; + case -1: + qWarning("%s: error reading packet (%d): %s", + __PRETTY_FUNCTION__, ret, pcap_geterr(handle_)); + break; + case -2: + default: + qFatal("%s: Unexpected return value %d", __PRETTY_FUNCTION__, ret); + } + + if (stop_) + { + stop_ = false; + break; + } + } + pcap_dump_close(dumpHandle_); + pcap_close(handle_); + dumpHandle_ = NULL; + handle_ = NULL; +} + +void PcapPort::PortCapturer::stop() +{ + stop_ = true; +} + +QFile* PcapPort::PortCapturer::captureFile() +{ + return &capFile_; +} + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/pcapport.h b/server/pcapport.h new file mode 100644 index 0000000..8fee855 --- /dev/null +++ b/server/pcapport.h @@ -0,0 +1,121 @@ +#ifndef _SERVER_PCAP_PORT_H +#define _SERVER_PCAP_PORT_H + +#include +#include +#include + +#include "abstractport.h" + +class PcapPort : public AbstractPort +{ +public: + PcapPort(int id, const char *device); + ~PcapPort(); + + void init(); + + virtual void clearPacketList() { + transmitter_->clearPacketList(); + setPacketListLoopMode(false); + } + virtual bool appendToPacketList(long sec, long usec, const uchar *packet, + int length) { + return transmitter_->appendToPacketList(sec, usec, packet, length); + } + virtual void setPacketListLoopMode(bool loop) { + transmitter_->setPacketListLoopMode(loop); + } + + virtual void startTransmit() { + if (isDirty()) + updatePacketList(); + transmitter_->start(); + } + virtual void stopTransmit() { transmitter_->stop(); } + virtual bool isTransmitOn() { return transmitter_->isRunning(); } + + virtual void startCapture() { capturer_->start(); } + virtual void stopCapture() { capturer_->stop(); } + virtual bool isCaptureOn() { return capturer_->isRunning(); } + virtual QIODevice* captureData() { return capturer_->captureFile(); } + +protected: + enum Direction + { + kDirectionRx, + kDirectionTx + }; + + class PortMonitor: public QThread + { + public: + PortMonitor(const char *device, Direction direction, + AbstractPort::PortStats *stats); + void run(); + pcap_t* handle() { return handle_; } + Direction direction() { return direction_; } + bool isDirectional() { return isDirectional_; } + protected: + AbstractPort::PortStats *stats_; + private: + pcap_t *handle_; + Direction direction_; + bool isDirectional_; + }; + + class PortTransmitter: public QThread + { + public: + PortTransmitter(const char *device); + void clearPacketList(); + bool appendToPacketList(long sec, long usec, const uchar *packet, + int length); + void setPacketListLoopMode(bool loop) { + returnToQIdx_ = loop ? 0 : -1; + } + void setHandle(pcap_t *handle); + void useExternalStats(AbstractPort::PortStats *stats); + void run(); + void stop(); + private: + int sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, int sync); + + QList sendQueueList_; + int returnToQIdx_; + bool usingInternalStats_; + AbstractPort::PortStats *stats_; + bool usingInternalHandle_; + pcap_t *handle_; + bool stop_; + }; + + class PortCapturer: public QThread + { + public: + PortCapturer(const char *device); + ~PortCapturer(); + void run(); + void stop(); + QFile* captureFile(); + + private: + QString device_; + bool stop_; + QTemporaryFile capFile_; + pcap_t *handle_; + pcap_dumper_t *dumpHandle_; + }; + + PortMonitor *monitorRx_; + PortMonitor *monitorTx_; +private: + PortTransmitter *transmitter_; + PortCapturer *capturer_; + + static pcap_if_t *deviceList_; +}; + +#endif + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/portmanager.cpp b/server/portmanager.cpp new file mode 100644 index 0000000..bd7fd78 --- /dev/null +++ b/server/portmanager.cpp @@ -0,0 +1,57 @@ +#include "portmanager.h" + +#include + +#include "winpcapport.h" + +PortManager *PortManager::instance_ = NULL; + +PortManager::PortManager() +{ + int i; + pcap_if_t *deviceList; + pcap_if_t *device; + char errbuf[PCAP_ERRBUF_SIZE]; + + qDebug("Retrieving the device list from the local machine\n"); + + if (pcap_findalldevs(&deviceList, errbuf) == -1) + qDebug("Error in pcap_findalldevs_ex: %s\n", errbuf); + + for(device = deviceList, i = 0; device != NULL; device = device->next, i++) + { + AbstractPort *port; + +#ifdef Q_OS_WIN32 + port = new WinPcapPort(i, device->name); +#else + port = new PcapPort(i, device->name); +#endif + + port->init(); + portList_.append(port); + + qDebug("%d. %s", i, device->name); + if (device->description) + qDebug(" (%s)\n", device->description); + } + + pcap_freealldevs(deviceList); + + return; +} + +PortManager::~PortManager() +{ +} + +PortManager* PortManager::instance() +{ + if (!instance_) + instance_ = new PortManager; + + return instance_; +} + + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/portmanager.h b/server/portmanager.h new file mode 100644 index 0000000..c71c6a6 --- /dev/null +++ b/server/portmanager.h @@ -0,0 +1,26 @@ +#ifndef _SERVER_PORT_MANAGER_H +#define _SERVER_PORT_MANAGER_H + +#include +#include "abstractport.h" + +class PortManager +{ +public: + PortManager(); + ~PortManager(); + + int portCount() { return portList_.size(); } + AbstractPort* port(int id) { return portList_[id]; } + + static PortManager* instance(); + +private: + QList portList_; + + static PortManager *instance_; +}; + +#endif + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp new file mode 100644 index 0000000..7e04a42 --- /dev/null +++ b/server/winpcapport.cpp @@ -0,0 +1,144 @@ +#include "winpcapport.h" + +const uint OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114; + +WinPcapPort::WinPcapPort(int id, const char *device) + : PcapPort(id, device) +{ + delete monitorRx_; + delete monitorTx_; + + monitorRx_ = new PortMonitor(device, kDirectionRx, &stats_); + monitorTx_ = new PortMonitor(device, kDirectionTx, &stats_); + + adapter_ = PacketOpenAdapter((CHAR*)device); + if (!adapter_) + qFatal("Unable to open adapter %s", device); + linkStateOid_ = (PPACKET_OID_DATA) malloc(sizeof(PACKET_OID_DATA) + + sizeof(uint)); + if (!linkStateOid_) + qFatal("failed to alloc oidData"); +} + +WinPcapPort::~WinPcapPort() +{ +} + +OstProto::LinkState WinPcapPort::linkState() +{ + memset(linkStateOid_, 0, sizeof(PACKET_OID_DATA) + sizeof(uint)); + + linkStateOid_->Oid = OID_GEN_MEDIA_CONNECT_STATUS; + linkStateOid_->Length = sizeof(uint); + + if (PacketRequest(adapter_, 0, linkStateOid_)) + { + uint state; + + if (linkStateOid_->Length == sizeof(state)) + { + memcpy((void*)&state, (void*)linkStateOid_->Data, + linkStateOid_->Length); + if (state == 0) + linkState_ = OstProto::LinkStateUp; + else if (state == 1) + linkState_ = OstProto::LinkStateDown; + } + } + + return linkState_; +} + +WinPcapPort::PortMonitor::PortMonitor(const char *device, Direction direction, + AbstractPort::PortStats *stats) + : PcapPort::PortMonitor(device, direction, stats) +{ + pcap_setmode(handle(), MODE_STAT); +} + +void WinPcapPort::PortMonitor::run() +{ + struct timeval lastTs; + quint64 lastTxPkts = 0; + quint64 lastTxBytes = 0; + + qWarning("in %s", __PRETTY_FUNCTION__); + + lastTs.tv_sec = 0; + lastTs.tv_usec = 0; + + while (1) + { + int ret; + struct pcap_pkthdr *hdr; + const uchar *data; + + ret = pcap_next_ex(handle(), &hdr, &data); + switch (ret) + { + case 1: + { + quint64 pkts = *((quint64*)(data + 0)); + quint64 bytes = *((quint64*)(data + 8)); + + // TODO: is it 12 or 16? + bytes -= pkts * 12; + + uint usec = (hdr->ts.tv_sec - lastTs.tv_sec) * 1000000 + + (hdr->ts.tv_usec - lastTs.tv_usec); + + switch (direction()) + { + case kDirectionRx: + stats_->rxPkts += pkts; + stats_->rxBytes += bytes; + stats_->rxPps = (pkts * 1000000) / usec; + stats_->rxBps = (bytes * 1000000) / usec; + break; + + case kDirectionTx: + if (isDirectional()) + { + stats_->txPkts += pkts; + stats_->txBytes += bytes; + } + else + { + // Assuming stats_->txXXX are updated externally + quint64 txPkts = stats_->txPkts; + quint64 txBytes = stats_->txBytes; + + pkts = txPkts - lastTxPkts; + bytes = txBytes - lastTxBytes; + + lastTxPkts = txPkts; + lastTxBytes = txBytes; + } + stats_->txPps = (pkts * 1000000) / usec; + stats_->txBps = (bytes * 1000000) / usec; + break; + + default: + Q_ASSERT(false); + } + + break; + } + case 0: + //qDebug("%s: timeout. continuing ...", __PRETTY_FUNCTION__); + continue; + case -1: + qWarning("%s: error reading packet (%d): %s", + __PRETTY_FUNCTION__, ret, pcap_geterr(handle())); + break; + case -2: + default: + qFatal("%s: Unexpected return value %d", __PRETTY_FUNCTION__, ret); + } + lastTs.tv_sec = hdr->ts.tv_sec; + lastTs.tv_usec = hdr->ts.tv_usec; + QThread::msleep(1000); + } +} + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/winpcapport.h b/server/winpcapport.h new file mode 100644 index 0000000..100ad2a --- /dev/null +++ b/server/winpcapport.h @@ -0,0 +1,31 @@ +#ifndef _SERVER_WIN_PCAP_PORT_H +#define _SERVER_WIN_PCAP_PORT_H + +#include "pcapport.h" + +#include + +class WinPcapPort : public PcapPort +{ +public: + WinPcapPort(int id, const char *device); + ~WinPcapPort(); + + virtual OstProto::LinkState linkState(); + +protected: + class PortMonitor: public PcapPort::PortMonitor + { + public: + PortMonitor(const char *device, Direction direction, + AbstractPort::PortStats *stats); + void run(); + }; +private: + LPADAPTER adapter_; + PPACKET_OID_DATA linkStateOid_ ; +}; + +#endif + +/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ From c7d90ff1ab040cbd6fb4b3e940340ebfb5c228f9 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 28 Dec 2009 08:31:28 +0000 Subject: [PATCH 36/98] - All tabs converted to spaces in all files - .vimrc added to reflect settings used in the project --- .vimrc | 5 + client/dumpview.cpp | 530 ++++++------ client/dumpview.h | 54 +- client/hexlineedit.cpp | 18 +- client/hexlineedit.h | 2 +- client/main.cpp | 4 +- client/mainwindow.cpp | 52 +- client/mainwindow.h | 18 +- client/modeltest.cpp | 6 +- client/ostinato.pro | 76 +- client/packetmodel.cpp | 300 +++---- client/packetmodel.h | 42 +- client/port.cpp | 208 ++--- client/port.h | 124 +-- client/portgroup.cpp | 914 ++++++++++----------- client/portgroup.h | 130 +-- client/portgrouplist.cpp | 92 +-- client/portgrouplist.h | 42 +- client/portmodel.cpp | 396 ++++----- client/portmodel.h | 48 +- client/portstatsfilterdialog.cpp | 144 ++-- client/portstatsfilterdialog.h | 28 +- client/portstatsmodel.cpp | 366 ++++----- client/portstatsmodel.h | 142 ++-- client/portstatswindow.cpp | 188 ++--- client/portstatswindow.h | 26 +- client/portswindow.cpp | 544 ++++++------- client/portswindow.h | 52 +- client/stream.cpp | 58 +- client/stream.h | 10 +- client/streamconfigdialog.cpp | 1306 +++++++++++++++--------------- client/streamconfigdialog.h | 126 +-- client/streamlistdelegate.cpp | 230 +++--- client/streamlistdelegate.h | 20 +- client/streammodel.cpp | 350 ++++---- client/streammodel.h | 66 +- common/abstractprotocol.cpp | 588 +++++++------- common/abstractprotocol.h | 150 ++-- common/comboprotocol.h | 298 +++---- common/dot2llc.h | 2 +- common/dot2llc.proto | 4 +- common/dot2snap.h | 2 +- common/dot2snap.proto | 4 +- common/dot3.cpp | 150 ++-- common/dot3.h | 54 +- common/dot3.proto | 4 +- common/eth2.cpp | 158 ++-- common/eth2.h | 54 +- common/eth2.proto | 4 +- common/ip4.cpp | 1124 ++++++++++++------------- common/ip4.h | 118 +-- common/ip4.proto | 64 +- common/llc.cpp | 196 ++--- common/llc.h | 58 +- common/llc.proto | 8 +- common/mac.cpp | 392 ++++----- common/mac.h | 76 +- common/mac.proto | 32 +- common/ostproto.pro | 140 ++-- common/payload.cpp | 268 +++--- common/payload.h | 66 +- common/payload.proto | 22 +- common/protocol.proto | 240 +++--- common/protocollist.cpp | 4 +- common/protocollist.h | 2 +- common/protocollistiterator.cpp | 82 +- common/protocollistiterator.h | 36 +- common/protocolmanager.cpp | 164 ++-- common/protocolmanager.h | 28 +- common/sample.cpp | 634 +++++++-------- common/sample.h | 84 +- common/sample.proto | 14 +- common/snap.cpp | 190 ++--- common/snap.h | 58 +- common/snap.proto | 6 +- common/streambase.cpp | 368 ++++----- common/streambase.h | 138 ++-- common/svlan.cpp | 26 +- common/svlan.h | 18 +- common/svlan.proto | 2 +- common/tcp.cpp | 690 ++++++++-------- common/tcp.h | 92 +-- common/tcp.proto | 24 +- common/udp.cpp | 420 +++++----- common/udp.h | 68 +- common/udp.proto | 14 +- common/userscript.proto | 4 +- common/vlan.cpp | 304 +++---- common/vlan.h | 64 +- common/vlan.proto | 12 +- common/vlanstack.h | 2 +- common/vlanstack.proto | 4 +- rpc/pbhelper.h | 220 ++--- rpc/pbrpcchannel.cpp | 416 +++++----- rpc/pbrpcchannel.h | 100 +-- rpc/pbrpccommon.h | 56 +- rpc/pbrpccontroller.h | 34 +- rpc/rpcserver.cpp | 338 ++++---- rpc/rpcserver.h | 34 +- server/drone.cpp | 70 +- server/drone.h | 12 +- server/drone.pro | 12 +- server/drone_main.cpp | 20 +- server/pcapextra.cpp | 62 +- server/pcapextra.h | 10 +- 105 files changed, 7967 insertions(+), 7962 deletions(-) create mode 100644 .vimrc diff --git a/.vimrc b/.vimrc new file mode 100644 index 0000000..fd28004 --- /dev/null +++ b/.vimrc @@ -0,0 +1,5 @@ +set shiftwidth=4 +set tabstop=8 +set softtabstop=4 +set expandtab +set cindent diff --git a/client/dumpview.cpp b/client/dumpview.cpp index 3393d5b..d846164 100644 --- a/client/dumpview.cpp +++ b/client/dumpview.cpp @@ -4,384 +4,384 @@ DumpView::DumpView(QWidget *parent) { - int w, h; + int w, h; - // NOTE: Monospaced fonts only !!!!!!!!!!! - setFont(QFont("Courier")); - w = fontMetrics().width('X'); - h = fontMetrics().height(); + // NOTE: Monospaced fonts only !!!!!!!!!!! + setFont(QFont("Courier")); + w = fontMetrics().width('X'); + h = fontMetrics().height(); - mLineHeight = h; - mCharWidth = w; + mLineHeight = h; + mCharWidth = w; - mSelectedRow = mSelectedCol = -1; + mSelectedRow = mSelectedCol = -1; - // calculate width for offset column and the whitespace that follows it - // 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ - mOffsetPaneTopRect = QRect(0, 0, w*4, h); - mDumpPaneTopRect = QRect(mOffsetPaneTopRect.right()+w*3, 0, - w*((8*3-1)+2+(8*3-1)), h); - mAsciiPaneTopRect = QRect(mDumpPaneTopRect.right()+w*3, 0, - w*(8+1+8), h); - qDebug("DumpView::DumpView"); + // calculate width for offset column and the whitespace that follows it + // 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ + mOffsetPaneTopRect = QRect(0, 0, w*4, h); + mDumpPaneTopRect = QRect(mOffsetPaneTopRect.right()+w*3, 0, + w*((8*3-1)+2+(8*3-1)), h); + mAsciiPaneTopRect = QRect(mDumpPaneTopRect.right()+w*3, 0, + w*(8+1+8), h); + qDebug("DumpView::DumpView"); } QModelIndex DumpView::indexAt( const QPoint &point ) const { #if 0 - int x = point.x(); - int row, col; + int x = point.x(); + int row, col; - if (x > mAsciiPaneTopRect.left()) - { - col = (x - mAsciiPaneTopRect.left()) / mCharWidth; - if (col == 8) // don't select whitespace - goto _exit; - else if (col > 8) // adjust for whitespace - col--; - } - else if (x > mDumpPaneTopRect.left()) - { - col = (x - mDumpPaneTopRect.left()) / (mCharWidth*3); - } - row = point.y()/mLineHeight; + if (x > mAsciiPaneTopRect.left()) + { + col = (x - mAsciiPaneTopRect.left()) / mCharWidth; + if (col == 8) // don't select whitespace + goto _exit; + else if (col > 8) // adjust for whitespace + col--; + } + else if (x > mDumpPaneTopRect.left()) + { + col = (x - mDumpPaneTopRect.left()) / (mCharWidth*3); + } + row = point.y()/mLineHeight; - if ((col < 16) && (row < ((data.size()+16)/16))) - { - selrow = row; - selcol = col; - } - else - goto _exit; + if ((col < 16) && (row < ((data.size()+16)/16))) + { + selrow = row; + selcol = col; + } + else + goto _exit; - // last row check col - if ((row == (((data.size()+16)/16) - 1)) && (col >= (data.size() % 16))) - goto _exit; + // last row check col + if ((row == (((data.size()+16)/16) - 1)) && (col >= (data.size() % 16))) + goto _exit; - qDebug("dumpview::selection(%d, %d)", selrow, selcol); + qDebug("dumpview::selection(%d, %d)", selrow, selcol); - offset = selrow * 16 + selcol; + offset = selrow * 16 + selcol; #if 0 - for(int i = 0; i < model()->rowCount(parent); i++) - { - QModelIndex index = model()->index(i, 0, parent); + for(int i = 0; i < model()->rowCount(parent); i++) + { + QModelIndex index = model()->index(i, 0, parent); - if (model()->hasChildren(index)) - indexAtOffset(offset, index); // Non Leaf - else - if ( - dump.append(model()->data(index, Qt::UserRole).toByteArray()); // Leaf - // FIXME: Use RawValueRole instead of UserRole - } + if (model()->hasChildren(index)) + indexAtOffset(offset, index); // Non Leaf + else + if ( + dump.append(model()->data(index, Qt::UserRole).toByteArray()); // Leaf + // FIXME: Use RawValueRole instead of UserRole + } #endif } _exit: - // Clear existing selection - selrow = -1; + // Clear existing selection + selrow = -1; #endif - return QModelIndex(); + return QModelIndex(); } void DumpView::scrollTo( const QModelIndex &index, ScrollHint hint ) { - // FIXME: implement scrolling + // FIXME: implement scrolling } QRect DumpView::visualRect( const QModelIndex &index ) const { - // FIXME: calculate actual rect - return rect(); + // FIXME: calculate actual rect + return rect(); } //protected: int DumpView::horizontalOffset() const { - return horizontalScrollBar()->value(); + return horizontalScrollBar()->value(); } bool DumpView::isIndexHidden( const QModelIndex &index ) const { - return false; + return false; } QModelIndex DumpView::moveCursor( CursorAction cursorAction, - Qt::KeyboardModifiers modifiers ) + Qt::KeyboardModifiers modifiers ) { - // FIXME(MED): need to implement movement using cursor - return currentIndex(); + // FIXME(MED): need to implement movement using cursor + return currentIndex(); } void DumpView::setSelection( const QRect &rect, - QItemSelectionModel::SelectionFlags flags ) + QItemSelectionModel::SelectionFlags flags ) { - // FIXME(HI): calculate indexes using rect - selectionModel()->select(QModelIndex(), flags); + // FIXME(HI): calculate indexes using rect + selectionModel()->select(QModelIndex(), flags); } int DumpView::verticalOffset() const { - return verticalScrollBar()->value(); + return verticalScrollBar()->value(); } QRegion DumpView::visualRegionForSelection( const QItemSelection &selection ) const { - // FIXME(HI) - return QRegion(rect()); + // FIXME(HI) + return QRegion(rect()); } //protected slots: void DumpView::dataChanged( const QModelIndex &topLeft, - const QModelIndex &bottomRight ) + const QModelIndex &bottomRight ) { - // FIXME(HI) - update(); + // FIXME(HI) + update(); } void DumpView::selectionChanged( const QItemSelection &selected, - const QItemSelection &deselected ) + const QItemSelection &deselected ) { - // FIXME(HI) - update(); + // FIXME(HI) + update(); } void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize, - QModelIndex parent) + QModelIndex parent) { - // FIXME: Use new enum instead of Qt::UserRole - //! \todo (low): generalize this for any model not just our pkt model + // FIXME: Use new enum instead of Qt::UserRole + //! \todo (low): generalize this for any model not just our pkt model - Q_ASSERT(!parent.isValid()); + Q_ASSERT(!parent.isValid()); - qDebug("!!!! %d $$$$", dump.size()); + qDebug("!!!! %d $$$$", dump.size()); - for(int i = 0; i < model()->rowCount(parent); i++) - { - QModelIndex index = model()->index(i, 0, parent); + for(int i = 0; i < model()->rowCount(parent); i++) + { + QModelIndex index = model()->index(i, 0, parent); - Q_ASSERT(index.isValid()); + Q_ASSERT(index.isValid()); - // Assumption: protocol data is in bytes (not bits) - qDebug("%d: %d bytes", i, model()->data(index, Qt::UserRole).toByteArray().size()); - dump.append(model()->data(index, Qt::UserRole).toByteArray()); + // Assumption: protocol data is in bytes (not bits) + qDebug("%d: %d bytes", i, model()->data(index, Qt::UserRole).toByteArray().size()); + dump.append(model()->data(index, Qt::UserRole).toByteArray()); - } + } - if (selectionModel()->selectedIndexes().size()) - { - int j, bits; - QModelIndex index; + if (selectionModel()->selectedIndexes().size()) + { + int j, bits; + QModelIndex index; - Q_ASSERT(selectionModel()->selectedIndexes().size() == 1); - index = selectionModel()->selectedIndexes().at(0); + Q_ASSERT(selectionModel()->selectedIndexes().size() == 1); + index = selectionModel()->selectedIndexes().at(0); - if (index.parent().isValid()) - { - // Field + if (index.parent().isValid()) + { + // Field - // SelOfs = SUM(protocol sizes before selected field's protocol) + - // SUM(field sizes before selected field) + // SelOfs = SUM(protocol sizes before selected field's protocol) + + // SUM(field sizes before selected field) - selOfs = 0; - j = index.parent().row() - 1; - while (j >= 0) - { - selOfs += model()->data(index.parent().sibling(j,0), - Qt::UserRole).toByteArray().size(); - j--; - } + selOfs = 0; + j = index.parent().row() - 1; + while (j >= 0) + { + selOfs += model()->data(index.parent().sibling(j,0), + Qt::UserRole).toByteArray().size(); + j--; + } - bits = 0; - j = index.row() - 1; - while (j >= 0) - { - bits += model()->data(index.sibling(j,0), Qt::UserRole+1). - toInt(); - j--; - } - selOfs += bits/8; - selSize = model()->data(index, Qt::UserRole).toByteArray().size(); - } - else - { - // Protocol - selOfs = 0; - j = index.row() - 1; - while (j >= 0) - { - selOfs += model()->data(index.sibling(j,0), Qt::UserRole). - toByteArray().size(); - j--; - } - selSize = model()->data(index, Qt::UserRole).toByteArray().size(); - } - } + bits = 0; + j = index.row() - 1; + while (j >= 0) + { + bits += model()->data(index.sibling(j,0), Qt::UserRole+1). + toInt(); + j--; + } + selOfs += bits/8; + selSize = model()->data(index, Qt::UserRole).toByteArray().size(); + } + else + { + // Protocol + selOfs = 0; + j = index.row() - 1; + while (j >= 0) + { + selOfs += model()->data(index.sibling(j,0), Qt::UserRole). + toByteArray().size(); + j--; + } + selSize = model()->data(index, Qt::UserRole).toByteArray().size(); + } + } } // TODO(LOW): rewrite this function - it's a mess! void DumpView::paintEvent(QPaintEvent* event) { - QStylePainter painter(viewport()); - QRect offsetRect = mOffsetPaneTopRect; - QRect dumpRect = mDumpPaneTopRect; - QRect asciiRect = mAsciiPaneTopRect; - QPalette pal = palette(); - static QByteArray data; - //QByteArray ba; - int selOfs = -1, selSize; - int curSelOfs, curSelSize; + QStylePainter painter(viewport()); + QRect offsetRect = mOffsetPaneTopRect; + QRect dumpRect = mDumpPaneTopRect; + QRect asciiRect = mAsciiPaneTopRect; + QPalette pal = palette(); + static QByteArray data; + //QByteArray ba; + int selOfs = -1, selSize; + int curSelOfs, curSelSize; - qDebug("dumpview::paintEvent"); + qDebug("dumpview::paintEvent"); - // FIXME(LOW): unable to set the self widget's font in constructor - painter.setFont(QFont("Courier")); + // FIXME(LOW): unable to set the self widget's font in constructor + painter.setFont(QFont("Courier")); - // set a white background - painter.fillRect(rect(), QBrush(QColor(Qt::white))); + // set a white background + painter.fillRect(rect(), QBrush(QColor(Qt::white))); - if (model()) - { - data.clear(); - populateDump(data, selOfs, selSize); - } + if (model()) + { + data.clear(); + populateDump(data, selOfs, selSize); + } - // display the offset, dump and ascii panes 8 + 8 bytes on a line - for (int i = 0; i < data.size(); i+=16) - { - QString dumpStr, asciiStr; + // display the offset, dump and ascii panes 8 + 8 bytes on a line + for (int i = 0; i < data.size(); i+=16) + { + QString dumpStr, asciiStr; - //ba = data.mid(i, 16); + //ba = data.mid(i, 16); - // display offset - painter.drawItemText(offsetRect, Qt::AlignLeft | Qt::AlignTop, pal, - true, QString("%1").arg(i, 4, 16, QChar('0')), QPalette::WindowText); - // construct the dumpStr and asciiStr - for (int j = i; (j < (i+16)) && (j < data.size()); j++) - { - unsigned char c = data.at(j); + // display offset + painter.drawItemText(offsetRect, Qt::AlignLeft | Qt::AlignTop, pal, + true, QString("%1").arg(i, 4, 16, QChar('0')), QPalette::WindowText); + // construct the dumpStr and asciiStr + for (int j = i; (j < (i+16)) && (j < data.size()); j++) + { + unsigned char c = data.at(j); - // extra space after 8 bytes - if (((j+8) % 16) == 0) - { - dumpStr.append(" "); - asciiStr.append(" "); - } + // extra space after 8 bytes + if (((j+8) % 16) == 0) + { + dumpStr.append(" "); + asciiStr.append(" "); + } - dumpStr.append(QString("%1").arg((uint)c, 2, 16, QChar('0')). - toUpper()).append(" "); + dumpStr.append(QString("%1").arg((uint)c, 2, 16, QChar('0')). + toUpper()).append(" "); - if (isPrintable(c)) - asciiStr.append(QChar(c)); - else - asciiStr.append(QChar('.')); - } + if (isPrintable(c)) + asciiStr.append(QChar(c)); + else + asciiStr.append(QChar('.')); + } - // display dump - painter.drawItemText(dumpRect, Qt::AlignLeft | Qt::AlignTop, pal, - true, dumpStr, QPalette::WindowText); + // display dump + painter.drawItemText(dumpRect, Qt::AlignLeft | Qt::AlignTop, pal, + true, dumpStr, QPalette::WindowText); - // display ascii - painter.drawItemText(asciiRect, Qt::AlignLeft | Qt::AlignTop, pal, - true, asciiStr, QPalette::WindowText); + // display ascii + painter.drawItemText(asciiRect, Qt::AlignLeft | Qt::AlignTop, pal, + true, asciiStr, QPalette::WindowText); - // if no selection, skip selection painting - if (selOfs < 0) - goto _next; + // if no selection, skip selection painting + if (selOfs < 0) + goto _next; - // Check overlap between current row and selection - { - QRect r1(i, 0, qMin(16, data.size()-i), 8); - QRect s1(selOfs, 0, selSize, 8); - if (r1.intersects(s1)) - { - QRect t = r1.intersected(s1); + // Check overlap between current row and selection + { + QRect r1(i, 0, qMin(16, data.size()-i), 8); + QRect s1(selOfs, 0, selSize, 8); + if (r1.intersects(s1)) + { + QRect t = r1.intersected(s1); - curSelOfs = t.x(); - curSelSize = t.width(); - } - else - curSelSize = 0; + curSelOfs = t.x(); + curSelSize = t.width(); + } + else + curSelSize = 0; - } + } - // overpaint selection on current row (if any) - if (curSelSize > 0) - { - QRect r; - QString selectedAsciiStr, selectedDumpStr; + // overpaint selection on current row (if any) + if (curSelSize > 0) + { + QRect r; + QString selectedAsciiStr, selectedDumpStr; - qDebug("dumpview::paintEvent - Highlighted (%d, %d)", - curSelOfs, curSelSize); + qDebug("dumpview::paintEvent - Highlighted (%d, %d)", + curSelOfs, curSelSize); - // construct the dumpStr and asciiStr - for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++) - { - unsigned char c = data.at(k); + // construct the dumpStr and asciiStr + for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++) + { + unsigned char c = data.at(k); - // extra space after 8 bytes - if (((k+8) % 16) == 0) - { - // Avoid adding space at the start for fields starting - // at second column 8 byte boundary - if (k!=curSelOfs) - { - selectedDumpStr.append(" "); - selectedAsciiStr.append(" "); - } - } + // extra space after 8 bytes + if (((k+8) % 16) == 0) + { + // Avoid adding space at the start for fields starting + // at second column 8 byte boundary + if (k!=curSelOfs) + { + selectedDumpStr.append(" "); + selectedAsciiStr.append(" "); + } + } - selectedDumpStr.append(QString("%1").arg((uint)c, 2, 16, - QChar('0')).toUpper()).append(" "); + selectedDumpStr.append(QString("%1").arg((uint)c, 2, 16, + QChar('0')).toUpper()).append(" "); - if (isPrintable(c)) - selectedAsciiStr.append(QChar(c)); - else - selectedAsciiStr.append(QChar('.')); - } + if (isPrintable(c)) + selectedAsciiStr.append(QChar(c)); + else + selectedAsciiStr.append(QChar('.')); + } - // display dump - r = dumpRect; - if ((curSelOfs - i) < 8) - r.translate(mCharWidth*(curSelOfs-i)*3, 0); - else - r.translate(mCharWidth*((curSelOfs-i)*3+1), 0); + // display dump + r = dumpRect; + if ((curSelOfs - i) < 8) + r.translate(mCharWidth*(curSelOfs-i)*3, 0); + else + r.translate(mCharWidth*((curSelOfs-i)*3+1), 0); - // adjust width taking care of selection stretching between - // the two 8byte columns - if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) - r.setWidth((curSelSize * 3 + 1) * mCharWidth); - else - r.setWidth((curSelSize * 3) * mCharWidth); + // adjust width taking care of selection stretching between + // the two 8byte columns + if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) + r.setWidth((curSelSize * 3 + 1) * mCharWidth); + else + r.setWidth((curSelSize * 3) * mCharWidth); - painter.fillRect(r, pal.highlight()); - painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, - true, selectedDumpStr, QPalette::HighlightedText); + painter.fillRect(r, pal.highlight()); + painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, + true, selectedDumpStr, QPalette::HighlightedText); - // display ascii - r = asciiRect; - if ((curSelOfs - i) < 8) - r.translate(mCharWidth*(curSelOfs-i)*1, 0); - else - r.translate(mCharWidth*((curSelOfs-i)*1+1), 0); + // display ascii + r = asciiRect; + if ((curSelOfs - i) < 8) + r.translate(mCharWidth*(curSelOfs-i)*1, 0); + else + r.translate(mCharWidth*((curSelOfs-i)*1+1), 0); - // adjust width taking care of selection stretching between - // the two 8byte columns - if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) - r.setWidth((curSelSize * 1 + 1) * mCharWidth); - else - r.setWidth((curSelSize * 1) * mCharWidth); + // adjust width taking care of selection stretching between + // the two 8byte columns + if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) + r.setWidth((curSelSize * 1 + 1) * mCharWidth); + else + r.setWidth((curSelSize * 1) * mCharWidth); - painter.fillRect(r, pal.highlight()); - painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, - true, selectedAsciiStr, QPalette::HighlightedText); - } + painter.fillRect(r, pal.highlight()); + painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, + true, selectedAsciiStr, QPalette::HighlightedText); + } -_next: - // move the rects down - offsetRect.translate(0, mLineHeight); - dumpRect.translate(0, mLineHeight); - asciiRect.translate(0, mLineHeight); - } +_next: + // move the rects down + offsetRect.translate(0, mLineHeight); + dumpRect.translate(0, mLineHeight); + asciiRect.translate(0, mLineHeight); + } } diff --git a/client/dumpview.h b/client/dumpview.h index e362103..db17002 100644 --- a/client/dumpview.h +++ b/client/dumpview.h @@ -3,40 +3,40 @@ class DumpView: public QAbstractItemView { -public: - DumpView(QWidget *parent=0); +public: + DumpView(QWidget *parent=0); - QModelIndex indexAt( const QPoint &point ) const; - void scrollTo( const QModelIndex &index, ScrollHint hint = EnsureVisible ); - QRect visualRect( const QModelIndex &index ) const; + QModelIndex indexAt( const QPoint &point ) const; + void scrollTo( const QModelIndex &index, ScrollHint hint = EnsureVisible ); + QRect visualRect( const QModelIndex &index ) const; protected: - int horizontalOffset() const; - bool isIndexHidden( const QModelIndex &index ) const; - QModelIndex moveCursor( CursorAction cursorAction, - Qt::KeyboardModifiers modifiers ); - void setSelection( const QRect &rect, QItemSelectionModel::SelectionFlags flags ); - int verticalOffset() const; - QRegion visualRegionForSelection( const QItemSelection &selection ) const; + int horizontalOffset() const; + bool isIndexHidden( const QModelIndex &index ) const; + QModelIndex moveCursor( CursorAction cursorAction, + Qt::KeyboardModifiers modifiers ); + void setSelection( const QRect &rect, QItemSelectionModel::SelectionFlags flags ); + int verticalOffset() const; + QRegion visualRegionForSelection( const QItemSelection &selection ) const; protected slots: - void dataChanged( const QModelIndex &topLeft, - const QModelIndex &bottomRight ); - void selectionChanged( const QItemSelection &selected, - const QItemSelection &deselected ); - void paintEvent(QPaintEvent *event); + void dataChanged( const QModelIndex &topLeft, + const QModelIndex &bottomRight ); + void selectionChanged( const QItemSelection &selected, + const QItemSelection &deselected ); + void paintEvent(QPaintEvent *event); private: - void populateDump(QByteArray &dump, int &selOfs, int &selSize, - QModelIndex parent = QModelIndex()); - bool inline isPrintable(char c) - {if ((c > 48) && (c < 126)) return true; else return false; } + void populateDump(QByteArray &dump, int &selOfs, int &selSize, + QModelIndex parent = QModelIndex()); + bool inline isPrintable(char c) + {if ((c > 48) && (c < 126)) return true; else return false; } private: - QRect mOffsetPaneTopRect; - QRect mDumpPaneTopRect; - QRect mAsciiPaneTopRect; - int mSelectedRow, mSelectedCol; - int mLineHeight; - int mCharWidth; + QRect mOffsetPaneTopRect; + QRect mDumpPaneTopRect; + QRect mAsciiPaneTopRect; + int mSelectedRow, mSelectedCol; + int mLineHeight; + int mCharWidth; }; diff --git a/client/hexlineedit.cpp b/client/hexlineedit.cpp index dcb6c20..5f099d0 100644 --- a/client/hexlineedit.cpp +++ b/client/hexlineedit.cpp @@ -4,9 +4,9 @@ QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets); HexLineEdit::HexLineEdit( QWidget * parent) - : QLineEdit(parent) + : QLineEdit(parent) { - //QLineEdit::QLineEdit(parent); + //QLineEdit::QLineEdit(parent); } void HexLineEdit::focusOutEvent( QFocusEvent *e ) @@ -40,15 +40,15 @@ void HexLineEdit::focusOutEvent( QFocusEvent *e ) emit focusOut(); #else #define uintToHexStr(num, bytesize) \ - QString("%1").arg((num), (bytesize)*2 , 16, QChar('0')) + QString("%1").arg((num), (bytesize)*2 , 16, QChar('0')) - bool isOk; - ulong num; + bool isOk; + ulong num; - qDebug("before = %s\n", text().toAscii().data()); - num = text().remove(QChar(' ')).toULong(&isOk, 16); - setText(uintToHexStr(num, 4)); - qDebug("after = %s\n", text().toAscii().data()); + qDebug("before = %s\n", text().toAscii().data()); + num = text().remove(QChar(' ')).toULong(&isOk, 16); + setText(uintToHexStr(num, 4)); + qDebug("after = %s\n", text().toAscii().data()); #undef uintToHexStr #endif } diff --git a/client/hexlineedit.h b/client/hexlineedit.h index 7c5811e..937d263 100644 --- a/client/hexlineedit.h +++ b/client/hexlineedit.h @@ -8,7 +8,7 @@ class HexLineEdit : public QLineEdit Q_OBJECT public: // Constructors - HexLineEdit ( QWidget * parent); + HexLineEdit ( QWidget * parent); protected: void focusOutEvent( QFocusEvent *e ); diff --git a/client/main.cpp b/client/main.cpp index 2f9b385..9a9a5d8 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -4,8 +4,8 @@ int main(int argc, char* argv[]) { - QApplication app(argc, argv); - MainWindow mainWin; + QApplication app(argc, argv); + MainWindow mainWin; mainWin.show(); return app.exec(); diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 9b2d12a..2aee434 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -12,54 +12,54 @@ #include #include -PortGroupList *pgl; +PortGroupList *pgl; MainWindow::MainWindow(QWidget *parent) - : QMainWindow (parent) + : QMainWindow (parent) { - localServer_ = new QProcess(this); - localServer_->start("drone.exe"); + localServer_ = new QProcess(this); + localServer_->start("drone.exe"); - pgl = new PortGroupList; + pgl = new PortGroupList; - portsWindow = new PortsWindow(pgl, this); - statsWindow = new PortStatsWindow(pgl, this); - portsDock = new QDockWidget(tr("Ports"), this); - statsDock = new QDockWidget(tr("Stats"), this); + portsWindow = new PortsWindow(pgl, this); + statsWindow = new PortStatsWindow(pgl, this); + portsDock = new QDockWidget(tr("Ports"), this); + statsDock = new QDockWidget(tr("Stats"), this); - setupUi(this); + setupUi(this); - statsDock->setWidget(statsWindow); + statsDock->setWidget(statsWindow); addDockWidget(Qt::BottomDockWidgetArea, statsDock); - portsDock->setWidget(portsWindow); + portsDock->setWidget(portsWindow); addDockWidget(Qt::TopDockWidgetArea, portsDock); - connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close())); + connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close())); #if 0 - { - DbgThread *dbg = new DbgThread(pgl); - dbg->start(); - } + { + DbgThread *dbg = new DbgThread(pgl); + dbg->start(); + } #endif } MainWindow::~MainWindow() { - delete pgl; - localServer_->terminate(); - localServer_->waitForFinished(); - delete localServer_; + delete pgl; + localServer_->terminate(); + localServer_->waitForFinished(); + delete localServer_; } void MainWindow::on_actionHelpAbout_triggered() { - QDialog *aboutDialog = new QDialog; + QDialog *aboutDialog = new QDialog; - Ui::About about; - about.setupUi(aboutDialog); + Ui::About about; + about.setupUi(aboutDialog); - aboutDialog->exec(); + aboutDialog->exec(); - delete aboutDialog; + delete aboutDialog; } diff --git a/client/mainwindow.h b/client/mainwindow.h index 5132385..53c8eac 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -12,21 +12,21 @@ class QProcess; class MainWindow : public QMainWindow, private Ui::MainWindow { - Q_OBJECT + Q_OBJECT private: - QProcess *localServer_; - PortsWindow *portsWindow; - PortStatsWindow *statsWindow; - QDockWidget *portsDock; - QDockWidget *statsDock; + QProcess *localServer_; + PortsWindow *portsWindow; + PortStatsWindow *statsWindow; + QDockWidget *portsDock; + QDockWidget *statsDock; public: - MainWindow(QWidget *parent = 0); - ~MainWindow(); + MainWindow(QWidget *parent = 0); + ~MainWindow(); public slots: - void on_actionHelpAbout_triggered(); + void on_actionHelpAbout_triggered(); }; #endif diff --git a/client/modeltest.cpp b/client/modeltest.cpp index 58685b0..2598c58 100644 --- a/client/modeltest.cpp +++ b/client/modeltest.cpp @@ -250,9 +250,9 @@ void ModelTest::parent() // that is the first level index. if (model->rowCount(topIndex) > 0) { QModelIndex childIndex = model->index(0, 0, topIndex); - qDebug("topIndex RCI %x %x %llx", topIndex.row(), topIndex.column(), topIndex.internalId()); - qDebug("topIndex I %llx", topIndex.internalId()); - qDebug("childIndex RCI %x %x %llx", childIndex.row(), childIndex.column(), childIndex.internalId()); + qDebug("topIndex RCI %x %x %llx", topIndex.row(), topIndex.column(), topIndex.internalId()); + qDebug("topIndex I %llx", topIndex.internalId()); + qDebug("childIndex RCI %x %x %llx", childIndex.row(), childIndex.column(), childIndex.internalId()); Q_ASSERT(model->parent(childIndex) == topIndex); } diff --git a/client/ostinato.pro b/client/ostinato.pro index ff54e47..b0dd570 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -10,48 +10,48 @@ unix:LIBS += -L"../rpc" -lpbrpc POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" RESOURCES += ostinato.qrc HEADERS += \ - dumpview.h \ - hexlineedit.h \ - mainwindow.h \ - packetmodel.h \ - port.h \ - portgroup.h \ - portgrouplist.h \ - portmodel.h \ - portstatsmodel.h \ - portstatsfilterdialog.h \ - portstatswindow.h \ - portswindow.h \ - streamconfigdialog.h \ - streamlistdelegate.h \ - streammodel.h + dumpview.h \ + hexlineedit.h \ + mainwindow.h \ + packetmodel.h \ + port.h \ + portgroup.h \ + portgrouplist.h \ + portmodel.h \ + portstatsmodel.h \ + portstatsfilterdialog.h \ + portstatswindow.h \ + portswindow.h \ + streamconfigdialog.h \ + streamlistdelegate.h \ + streammodel.h FORMS += \ - about.ui \ - mainwindow.ui \ - portstatsfilter.ui \ - portstatswindow.ui \ - portswindow.ui \ - streamconfigdialog.ui + about.ui \ + mainwindow.ui \ + portstatsfilter.ui \ + portstatswindow.ui \ + portswindow.ui \ + streamconfigdialog.ui SOURCES += \ - dumpview.cpp \ - stream.cpp \ - hexlineedit.cpp \ - main.cpp \ - mainwindow.cpp \ - packetmodel.cpp \ - port.cpp \ - portgroup.cpp \ - portgrouplist.cpp \ - portmodel.cpp \ - portstatsmodel.cpp \ - portstatsfilterdialog.cpp \ - portstatswindow.cpp \ - portswindow.cpp \ - streamconfigdialog.cpp \ - streamlistdelegate.cpp \ - streammodel.cpp + dumpview.cpp \ + stream.cpp \ + hexlineedit.cpp \ + main.cpp \ + mainwindow.cpp \ + packetmodel.cpp \ + port.cpp \ + portgroup.cpp \ + portgrouplist.cpp \ + portmodel.cpp \ + portstatsmodel.cpp \ + portstatsfilterdialog.cpp \ + portstatswindow.cpp \ + portswindow.cpp \ + streamconfigdialog.cpp \ + streamlistdelegate.cpp \ + streammodel.cpp # TODO(LOW): Test only include(modeltest.pri) diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 6b7b834..a3aee4d 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -10,211 +10,211 @@ PacketModel::PacketModel(QObject *parent) void PacketModel::setSelectedProtocols(ProtocolListIterator &iter) { - QList currentProtocols; + QList currentProtocols; - iter.toFront(); - while (iter.hasNext()) - currentProtocols.append(iter.next()); + iter.toFront(); + while (iter.hasNext()) + currentProtocols.append(iter.next()); - if (mSelectedProtocols != currentProtocols) - { - mSelectedProtocols = currentProtocols; - reset(); - } + if (mSelectedProtocols != currentProtocols) + { + mSelectedProtocols = currentProtocols; + reset(); + } } int PacketModel::rowCount(const QModelIndex &parent) const { - IndexId parentId; + IndexId parentId; - // qDebug("in %s", __FUNCTION__); + // qDebug("in %s", __FUNCTION__); - // Parent == Invalid i.e. Invisible Root. - // ==> Children are Protocol (Top Level) Items - if (!parent.isValid()) - return mSelectedProtocols.size(); + // Parent == Invalid i.e. Invisible Root. + // ==> Children are Protocol (Top Level) Items + if (!parent.isValid()) + return mSelectedProtocols.size(); - // Parent - Valid Item - parentId.w = parent.internalId(); - switch(parentId.ws.type) - { - case ITYP_PROTOCOL: - return mSelectedProtocols.at(parentId.ws.protocol)->frameFieldCount(); - case ITYP_FIELD: - return 0; - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } + // Parent - Valid Item + parentId.w = parent.internalId(); + switch(parentId.ws.type) + { + case ITYP_PROTOCOL: + return mSelectedProtocols.at(parentId.ws.protocol)->frameFieldCount(); + case ITYP_FIELD: + return 0; + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } - Q_ASSERT(1 == 0); // Unreachable code - qWarning("%s: Catch all - need to investigate", __FUNCTION__); - return 0; // catch all + Q_ASSERT(1 == 0); // Unreachable code + qWarning("%s: Catch all - need to investigate", __FUNCTION__); + return 0; // catch all } int PacketModel::columnCount(const QModelIndex &parent) const { - return 1; + return 1; } QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) const { - QModelIndex index; - IndexId id, parentId; + QModelIndex index; + IndexId id, parentId; - if (!hasIndex(row, col, parent)) - goto _exit; + if (!hasIndex(row, col, parent)) + goto _exit; - // Parent is Invisible Root - // Request for a Protocol Item - if (!parent.isValid()) - { - id.w = 0; - id.ws.type = ITYP_PROTOCOL; - id.ws.protocol = row; - index = createIndex(row, col, id.w); - goto _exit; - } + // Parent is Invisible Root + // Request for a Protocol Item + if (!parent.isValid()) + { + id.w = 0; + id.ws.type = ITYP_PROTOCOL; + id.ws.protocol = row; + index = createIndex(row, col, id.w); + goto _exit; + } - // Parent is a Valid Item - parentId.w = parent.internalId(); - id.w = parentId.w; - switch(parentId.ws.type) - { - case ITYP_PROTOCOL: - id.ws.type = ITYP_FIELD; - index = createIndex(row, col, id.w); - goto _exit; + // Parent is a Valid Item + parentId.w = parent.internalId(); + id.w = parentId.w; + switch(parentId.ws.type) + { + case ITYP_PROTOCOL: + id.ws.type = ITYP_FIELD; + index = createIndex(row, col, id.w); + goto _exit; - case ITYP_FIELD: - Q_ASSERT(1 == 0); // Unreachable code - goto _exit; + case ITYP_FIELD: + Q_ASSERT(1 == 0); // Unreachable code + goto _exit; - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } - Q_ASSERT(1 == 0); // Unreachable code + Q_ASSERT(1 == 0); // Unreachable code _exit: - return index; + return index; } QModelIndex PacketModel::parent(const QModelIndex &index) const { - QModelIndex parentIndex; - IndexId id, parentId; + QModelIndex parentIndex; + IndexId id, parentId; - if (!index.isValid()) - return QModelIndex(); + if (!index.isValid()) + return QModelIndex(); - id.w = index.internalId(); - parentId.w = id.w; - switch(id.ws.type) - { - case ITYP_PROTOCOL: - // return invalid index for invisible root - goto _exit; + id.w = index.internalId(); + parentId.w = id.w; + switch(id.ws.type) + { + case ITYP_PROTOCOL: + // return invalid index for invisible root + goto _exit; - case ITYP_FIELD: - parentId.ws.type = ITYP_PROTOCOL; - parentIndex = createIndex(id.ws.protocol, 0, parentId.w); - goto _exit; + case ITYP_FIELD: + parentId.ws.type = ITYP_PROTOCOL; + parentIndex = createIndex(id.ws.protocol, 0, parentId.w); + goto _exit; - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } - Q_ASSERT(1 == 1); // Unreachable code + Q_ASSERT(1 == 1); // Unreachable code _exit: - return parentIndex; + return parentIndex; } QVariant PacketModel::data(const QModelIndex &index, int role) const { - IndexId id; - int fieldIdx = 0; + IndexId id; + int fieldIdx = 0; - if (!index.isValid()) - return QVariant(); + if (!index.isValid()) + return QVariant(); - id.w = index.internalId(); + id.w = index.internalId(); - if (id.ws.type == ITYP_FIELD) - { - const AbstractProtocol *p = mSelectedProtocols.at(id.ws.protocol); - int n = index.row() + 1; + if (id.ws.type == ITYP_FIELD) + { + const AbstractProtocol *p = mSelectedProtocols.at(id.ws.protocol); + int n = index.row() + 1; - while (n) - { - if (!(p->fieldFlags(fieldIdx).testFlag( - AbstractProtocol::FieldIsMeta))) - n--; - fieldIdx++; - } - fieldIdx--; - } + while (n) + { + if (!(p->fieldFlags(fieldIdx).testFlag( + AbstractProtocol::FieldIsMeta))) + n--; + fieldIdx++; + } + fieldIdx--; + } - // FIXME(HI): Relook at this completely - if (role == Qt::UserRole) - { - switch(id.ws.type) - { - case ITYP_PROTOCOL: - qDebug("*** %d/%d", id.ws.protocol, mSelectedProtocols.size()); - return mSelectedProtocols.at(id.ws.protocol)-> - protocolFrameValue(); + // FIXME(HI): Relook at this completely + if (role == Qt::UserRole) + { + switch(id.ws.type) + { + case ITYP_PROTOCOL: + qDebug("*** %d/%d", id.ws.protocol, mSelectedProtocols.size()); + return mSelectedProtocols.at(id.ws.protocol)-> + protocolFrameValue(); - case ITYP_FIELD: - return mSelectedProtocols.at(id.ws.protocol)->fieldData( - fieldIdx, AbstractProtocol::FieldFrameValue); + case ITYP_FIELD: + return mSelectedProtocols.at(id.ws.protocol)->fieldData( + fieldIdx, AbstractProtocol::FieldFrameValue); - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } - return QByteArray(); - } + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + return QByteArray(); + } - // FIXME: Use a new enum here instead of UserRole - if (role == (Qt::UserRole+1)) - { - switch(id.ws.type) - { - case ITYP_PROTOCOL: - return mSelectedProtocols.at(id.ws.protocol)-> - protocolFrameValue().size(); + // FIXME: Use a new enum here instead of UserRole + if (role == (Qt::UserRole+1)) + { + switch(id.ws.type) + { + case ITYP_PROTOCOL: + return mSelectedProtocols.at(id.ws.protocol)-> + protocolFrameValue().size(); - case ITYP_FIELD: - return mSelectedProtocols.at(id.ws.protocol)->fieldData( - fieldIdx, AbstractProtocol::FieldBitSize); + case ITYP_FIELD: + return mSelectedProtocols.at(id.ws.protocol)->fieldData( + fieldIdx, AbstractProtocol::FieldBitSize); - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } - return QVariant(); - } + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + return QVariant(); + } - if (role != Qt::DisplayRole) - return QVariant(); + if (role != Qt::DisplayRole) + return QVariant(); - switch(id.ws.type) - { - case ITYP_PROTOCOL: - return QString("%1 (%2)") - .arg(mSelectedProtocols.at(id.ws.protocol)->shortName()) - .arg(mSelectedProtocols.at(id.ws.protocol)->name()); + switch(id.ws.type) + { + case ITYP_PROTOCOL: + return QString("%1 (%2)") + .arg(mSelectedProtocols.at(id.ws.protocol)->shortName()) + .arg(mSelectedProtocols.at(id.ws.protocol)->name()); - case ITYP_FIELD: - return mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, - AbstractProtocol::FieldName).toString() + QString(" : ") + - mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, - AbstractProtocol::FieldTextValue).toString(); + case ITYP_FIELD: + return mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, + AbstractProtocol::FieldName).toString() + QString(" : ") + + mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, + AbstractProtocol::FieldTextValue).toString(); - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } - Q_ASSERT(1 == 1); // Unreachable code + Q_ASSERT(1 == 1); // Unreachable code - return QVariant(); + return QVariant(); } diff --git a/client/packetmodel.h b/client/packetmodel.h index c6b0cfc..2568724 100644 --- a/client/packetmodel.h +++ b/client/packetmodel.h @@ -10,31 +10,31 @@ class PacketModel: public QAbstractItemModel { public: - PacketModel(QObject *parent = 0); - void setSelectedProtocols(ProtocolListIterator &iter); + PacketModel(QObject *parent = 0); + void setSelectedProtocols(ProtocolListIterator &iter); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const { return QVariant(); } ; - QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; - QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const { return QVariant(); } ; + QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; + QModelIndex parent(const QModelIndex &index) const; private: - typedef union _IndexId - { - quint32 w; - struct - { - quint16 type; -#define ITYP_PROTOCOL 1 -#define ITYP_FIELD 2 - quint16 protocol; // protocol is valid for both ITYPs - } ws; - } IndexId; + typedef union _IndexId + { + quint32 w; + struct + { + quint16 type; +#define ITYP_PROTOCOL 1 +#define ITYP_FIELD 2 + quint16 protocol; // protocol is valid for both ITYPs + } ws; + } IndexId; - QList mSelectedProtocols; + QList mSelectedProtocols; }; #endif diff --git a/client/port.cpp b/client/port.cpp index 87f0e07..8f708f1 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -9,15 +9,15 @@ uint Port::mAllocStreamId = 0; uint Port::newStreamId() { - return mAllocStreamId++; + return mAllocStreamId++; } Port::Port(quint32 id, quint32 portGroupId) { - mPortId = id; - d.mutable_port_id()->set_id(id); - stats.mutable_port_id()->set_id(id); - mPortGroupId = portGroupId; + mPortId = id; + d.mutable_port_id()->set_id(id); + stats.mutable_port_id()->set_id(id); + mPortGroupId = portGroupId; } Port::~Port() @@ -26,172 +26,172 @@ Port::~Port() void Port::updatePortConfig(OstProto::Port *port) { - d.MergeFrom(*port); + d.MergeFrom(*port); } void Port::updateStreamOrdinalsFromIndex() { - for (int i=0; i < mStreams.size(); i++) - mStreams[i]->setOrdinal(i); + for (int i=0; i < mStreams.size(); i++) + mStreams[i]->setOrdinal(i); } void Port::reorderStreamsByOrdinals() { - qSort(mStreams); + qSort(mStreams); } bool Port::newStreamAt(int index) { - Stream *s = new Stream; + Stream *s = new Stream; - if (index > mStreams.size()) - return false; + if (index > mStreams.size()) + return false; - s->setId(newStreamId()); - mStreams.insert(index, s); - updateStreamOrdinalsFromIndex(); + s->setId(newStreamId()); + mStreams.insert(index, s); + updateStreamOrdinalsFromIndex(); - return true; + return true; } bool Port::deleteStreamAt(int index) { - if (index >= mStreams.size()) - return false; + if (index >= mStreams.size()) + return false; - delete mStreams.takeAt(index); - updateStreamOrdinalsFromIndex(); + delete mStreams.takeAt(index); + updateStreamOrdinalsFromIndex(); - return true; + return true; } bool Port::insertStream(uint streamId) { - Stream *s = new Stream; + Stream *s = new Stream; - s->setId(streamId); + s->setId(streamId); - // FIXME(MED): If a stream with id already exists, what do we do? - mStreams.append(s); + // FIXME(MED): If a stream with id already exists, what do we do? + mStreams.append(s); - // Update mAllocStreamId to take into account the stream id received - // from server - if (mAllocStreamId <= streamId) - mAllocStreamId = streamId + 1; + // Update mAllocStreamId to take into account the stream id received + // from server + if (mAllocStreamId <= streamId) + mAllocStreamId = streamId + 1; - return true; + return true; } bool Port::updateStream(uint streamId, OstProto::Stream *stream) { - int i, streamIndex; + int i, streamIndex; - for (i = 0; i < mStreams.size(); i++) - { - if (streamId == mStreams[i]->id()) - goto _found; - } + for (i = 0; i < mStreams.size(); i++) + { + if (streamId == mStreams[i]->id()) + goto _found; + } - qDebug("%s: Invalid stream id %d", __FUNCTION__, streamId); - return false; + qDebug("%s: Invalid stream id %d", __FUNCTION__, streamId); + return false; _found: - streamIndex = i; + streamIndex = i; - mStreams[streamIndex]->protoDataCopyFrom(*stream); - reorderStreamsByOrdinals(); + mStreams[streamIndex]->protoDataCopyFrom(*stream); + reorderStreamsByOrdinals(); - return true; + return true; } void Port::getDeletedStreamsSinceLastSync( - OstProto::StreamIdList &streamIdList) + OstProto::StreamIdList &streamIdList) { - streamIdList.clear_stream_id(); - for (int i = 0; i < mLastSyncStreamList.size(); i++) - { - int j; + streamIdList.clear_stream_id(); + for (int i = 0; i < mLastSyncStreamList.size(); i++) + { + int j; - for (j = 0; j < mStreams.size(); j++) - { - if (mLastSyncStreamList[i] == mStreams[j]->id()) - break; - } + for (j = 0; j < mStreams.size(); j++) + { + if (mLastSyncStreamList[i] == mStreams[j]->id()) + break; + } - if (j < mStreams.size()) - { - // stream still exists! - continue; - } - else - { - // stream has been deleted since last sync - OstProto::StreamId *s; + if (j < mStreams.size()) + { + // stream still exists! + continue; + } + else + { + // stream has been deleted since last sync + OstProto::StreamId *s; - s = streamIdList.add_stream_id(); - s->set_id(mLastSyncStreamList.at(i)); - } - } + s = streamIdList.add_stream_id(); + s->set_id(mLastSyncStreamList.at(i)); + } + } } void Port::getNewStreamsSinceLastSync( - OstProto::StreamIdList &streamIdList) + OstProto::StreamIdList &streamIdList) { - streamIdList.clear_stream_id(); - for (int i = 0; i < mStreams.size(); i++) - { - if (mLastSyncStreamList.contains(mStreams[i]->id())) - { - // existing stream! - continue; - } - else - { - // new stream! - OstProto::StreamId *s; + streamIdList.clear_stream_id(); + for (int i = 0; i < mStreams.size(); i++) + { + if (mLastSyncStreamList.contains(mStreams[i]->id())) + { + // existing stream! + continue; + } + else + { + // new stream! + OstProto::StreamId *s; - s = streamIdList.add_stream_id(); - s->set_id(mStreams[i]->id()); - } - } + s = streamIdList.add_stream_id(); + s->set_id(mStreams[i]->id()); + } + } } void Port::getModifiedStreamsSinceLastSync( - OstProto::StreamConfigList &streamConfigList) + OstProto::StreamConfigList &streamConfigList) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - //streamConfigList.mutable_port_id()->set_id(mPortId); - for (int i = 0; i < mStreams.size(); i++) - { - OstProto::Stream *s; + //streamConfigList.mutable_port_id()->set_id(mPortId); + for (int i = 0; i < mStreams.size(); i++) + { + OstProto::Stream *s; - s = streamConfigList.add_stream(); - mStreams[i]->protoDataCopyInto(*s); - } - qDebug("Done %s", __FUNCTION__); + s = streamConfigList.add_stream(); + mStreams[i]->protoDataCopyInto(*s); + } + qDebug("Done %s", __FUNCTION__); } void Port::when_syncComplete() { - qSort(mStreams); + qSort(mStreams); - mLastSyncStreamList.clear(); - for (int i=0; iid()); + mLastSyncStreamList.clear(); + for (int i=0; iid()); } void Port::updateStats(OstProto::PortStats *portStats) { - OstProto::PortState oldState; + OstProto::PortState oldState; - oldState = stats.state(); - stats.MergeFrom(*portStats); + oldState = stats.state(); + stats.MergeFrom(*portStats); - if (oldState.link_state() != stats.state().link_state()) - { - qDebug("portstate changed"); - emit portDataChanged(mPortGroupId, mPortId); - } + if (oldState.link_state() != stats.state().link_state()) + { + qDebug("portstate changed"); + emit portDataChanged(mPortGroupId, mPortId); + } } diff --git a/client/port.h b/client/port.h index 9be12ed..09e025a 100644 --- a/client/port.h +++ b/client/port.h @@ -10,88 +10,88 @@ class Port : public QObject { - Q_OBJECT + Q_OBJECT - static uint mAllocStreamId; - OstProto::Port d; - OstProto::PortStats stats; + static uint mAllocStreamId; + OstProto::Port d; + OstProto::PortStats stats; - // FIXME(HI): consider removing mPortId as it is duplicated inside 'd' - quint32 mPortId; - quint32 mPortGroupId; - QString mUserAlias; // user defined + // FIXME(HI): consider removing mPortId as it is duplicated inside 'd' + quint32 mPortId; + quint32 mPortGroupId; + QString mUserAlias; // user defined - QList mLastSyncStreamList; - QList mStreams; // sorted by stream's ordinal value + QList mLastSyncStreamList; + QList mStreams; // sorted by stream's ordinal value - uint newStreamId(); - void updateStreamOrdinalsFromIndex(); - void reorderStreamsByOrdinals(); + uint newStreamId(); + void updateStreamOrdinalsFromIndex(); + void reorderStreamsByOrdinals(); public: - enum AdminStatus { AdminDisable, AdminEnable }; - enum ControlMode { ControlShared, ControlExclusive }; + enum AdminStatus { AdminDisable, AdminEnable }; + enum ControlMode { ControlShared, ControlExclusive }; - // FIXME(HIGH): default args is a hack for QList operations on Port - Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF); - ~Port(); + // FIXME(HIGH): default args is a hack for QList operations on Port + Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF); + ~Port(); - quint32 portGroupId() const { return mPortGroupId; } - const QString& userAlias() const { return mUserAlias; } + quint32 portGroupId() const { return mPortGroupId; } + const QString& userAlias() const { return mUserAlias; } - quint32 id() const - { return d.port_id().id(); } - const QString name() const - { return QString().fromStdString(d.name()); } - const QString description() const - { return QString().fromStdString(d.description()); } - AdminStatus adminStatus() - { return (d.is_enabled()?AdminEnable:AdminDisable); } - ControlMode controlMode() - { return (d.is_exclusive_control()?ControlExclusive:ControlShared); } + quint32 id() const + { return d.port_id().id(); } + const QString name() const + { return QString().fromStdString(d.name()); } + const QString description() const + { return QString().fromStdString(d.description()); } + AdminStatus adminStatus() + { return (d.is_enabled()?AdminEnable:AdminDisable); } + ControlMode controlMode() + { return (d.is_exclusive_control()?ControlExclusive:ControlShared); } - //void setAdminEnable(AdminStatus status) { mAdminStatus = status; } - void setAlias(QString &alias) { mUserAlias = alias; } - //void setExclusive(bool flag); + //void setAdminEnable(AdminStatus status) { mAdminStatus = status; } + void setAlias(QString &alias) { mUserAlias = alias; } + //void setExclusive(bool flag); - int numStreams() { return mStreams.size(); } - Stream* streamByIndex(int index) - { - Q_ASSERT(index < mStreams.size()); - return mStreams[index]; - } - OstProto::LinkState linkState() - { return stats.state().link_state(); } + int numStreams() { return mStreams.size(); } + Stream* streamByIndex(int index) + { + Q_ASSERT(index < mStreams.size()); + return mStreams[index]; + } + OstProto::LinkState linkState() + { return stats.state().link_state(); } - OstProto::PortStats getStats() { return stats; } + OstProto::PortStats getStats() { return stats; } - // FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal - void updatePortConfig(OstProto::Port *port); - - //! Used by StreamModel - //@{ - bool newStreamAt(int index); - bool deleteStreamAt(int index); - //@} + // FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal + void updatePortConfig(OstProto::Port *port); + + //! Used by StreamModel + //@{ + bool newStreamAt(int index); + bool deleteStreamAt(int index); + //@} - //! Used by MyService::Stub to update from config received from server - //@{ - bool insertStream(uint streamId); - bool updateStream(uint streamId, OstProto::Stream *stream); - //@} + //! Used by MyService::Stub to update from config received from server + //@{ + bool insertStream(uint streamId); + bool updateStream(uint streamId, OstProto::Stream *stream); + //@} - void getDeletedStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); - void getNewStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); - void getModifiedStreamsSinceLastSync( - OstProto::StreamConfigList &streamConfigList); + void getDeletedStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); + void getNewStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); + void getModifiedStreamsSinceLastSync( + OstProto::StreamConfigList &streamConfigList); - void when_syncComplete(); + void when_syncComplete(); - void updateStats(OstProto::PortStats *portStats); + void updateStats(OstProto::PortStats *portStats); signals: - void portDataChanged(int portGroupId, int portId); + void portDataChanged(int portGroupId, int portId); }; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 4a2843c..e26d2a1 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -4,45 +4,45 @@ #include "portgroup.h" -quint32 PortGroup::mPortGroupAllocId = 0; +quint32 PortGroup::mPortGroupAllocId = 0; PortGroup::PortGroup(QHostAddress ip, quint16 port) { - // Allocate an id for self - mPortGroupId = PortGroup::mPortGroupAllocId++; + // Allocate an id for self + mPortGroupId = PortGroup::mPortGroupAllocId++; - rpcChannel = new PbRpcChannel(ip, port); + rpcChannel = new PbRpcChannel(ip, port); - /*! - \todo (HIGH) RPC Controller should be allocated and deleted for each RPC invocation - as implemented currently, if a RPC is invoked before the previous completes, - rpc controller is overwritten due to the Reset() call - maybe we need to pass the - pointer to the controller to the callback function also? - */ - rpcController = new PbRpcController; - rpcControllerStats = new PbRpcController; - isGetStatsPending_ = false; - serviceStub = new OstProto::OstService::Stub(rpcChannel, - OstProto::OstService::STUB_OWNS_CHANNEL); + /*! + \todo (HIGH) RPC Controller should be allocated and deleted for each RPC invocation + as implemented currently, if a RPC is invoked before the previous completes, + rpc controller is overwritten due to the Reset() call - maybe we need to pass the + pointer to the controller to the callback function also? + */ + rpcController = new PbRpcController; + rpcControllerStats = new PbRpcController; + isGetStatsPending_ = false; + serviceStub = new OstProto::OstService::Stub(rpcChannel, + OstProto::OstService::STUB_OWNS_CHANNEL); - // FIXME(LOW):Can't for my life figure out why this ain't working! - //QMetaObject::connectSlotsByName(this); - connect(rpcChannel, SIGNAL(stateChanged(QAbstractSocket::SocketState)), - this, SLOT(on_rpcChannel_stateChanged())); - connect(rpcChannel, SIGNAL(connected()), - this, SLOT(on_rpcChannel_connected())); - connect(rpcChannel, SIGNAL(disconnected()), - this, SLOT(on_rpcChannel_disconnected())); - connect(rpcChannel, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(on_rpcChannel_error(QAbstractSocket::SocketError))); + // FIXME(LOW):Can't for my life figure out why this ain't working! + //QMetaObject::connectSlotsByName(this); + connect(rpcChannel, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(on_rpcChannel_stateChanged())); + connect(rpcChannel, SIGNAL(connected()), + this, SLOT(on_rpcChannel_connected())); + connect(rpcChannel, SIGNAL(disconnected()), + this, SLOT(on_rpcChannel_disconnected())); + connect(rpcChannel, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_rpcChannel_error(QAbstractSocket::SocketError))); } PortGroup::~PortGroup() { - qDebug("PortGroup Destructor"); - // Disconnect and free rpc channel etc. - PortGroup::disconnectFromHost(); - delete serviceStub; + qDebug("PortGroup Destructor"); + // Disconnect and free rpc channel etc. + PortGroup::disconnectFromHost(); + delete serviceStub; } @@ -51,668 +51,668 @@ PortGroup::~PortGroup() // ------------------------------------------------ void PortGroup::on_rpcChannel_stateChanged() { - qDebug("state changed"); - emit portGroupDataChanged(mPortGroupId); + qDebug("state changed"); + emit portGroupDataChanged(mPortGroupId); } void PortGroup::on_rpcChannel_connected() { - OstProto::Void void_; - OstProto::PortIdList *portIdList; - - qDebug("connected\n"); - emit portGroupDataChanged(mPortGroupId); + OstProto::Void void_; + OstProto::PortIdList *portIdList; + + qDebug("connected\n"); + emit portGroupDataChanged(mPortGroupId); - qDebug("requesting portlist ..."); - portIdList = new OstProto::PortIdList(); - rpcController->Reset(); - serviceStub->getPortIdList(rpcController, &void_, portIdList, - NewCallback(this, &PortGroup::processPortIdList, portIdList)); + qDebug("requesting portlist ..."); + portIdList = new OstProto::PortIdList(); + rpcController->Reset(); + serviceStub->getPortIdList(rpcController, &void_, portIdList, + NewCallback(this, &PortGroup::processPortIdList, portIdList)); } void PortGroup::on_rpcChannel_disconnected() { - qDebug("disconnected\n"); - emit portListAboutToBeChanged(mPortGroupId); + qDebug("disconnected\n"); + emit portListAboutToBeChanged(mPortGroupId); - while (!mPorts.isEmpty()) - delete mPorts.takeFirst(); + while (!mPorts.isEmpty()) + delete mPorts.takeFirst(); - emit portListChanged(mPortGroupId); - emit portGroupDataChanged(mPortGroupId); + emit portListChanged(mPortGroupId); + emit portGroupDataChanged(mPortGroupId); } void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) { - qDebug("error\n"); - emit portGroupDataChanged(mPortGroupId); + qDebug("error\n"); + emit portGroupDataChanged(mPortGroupId); } void PortGroup::when_configApply(int portIndex, uint *cookie) { - uint *op; - OstProto::Ack *ack; + uint *op; + OstProto::Ack *ack; - Q_ASSERT(portIndex < mPorts.size()); + Q_ASSERT(portIndex < mPorts.size()); - if (state() != QAbstractSocket::ConnectedState) - { - if (cookie != NULL) - delete cookie; - return; - } + if (state() != QAbstractSocket::ConnectedState) + { + if (cookie != NULL) + delete cookie; + return; + } - if (cookie == NULL) - { - // cookie[0]: op [0 - delete, 1 - add, 2 - modify, 3 - Done!] - // cookie[1]: *ack - cookie = new uint[2]; - ack = new OstProto::Ack; + if (cookie == NULL) + { + // cookie[0]: op [0 - delete, 1 - add, 2 - modify, 3 - Done!] + // cookie[1]: *ack + cookie = new uint[2]; + ack = new OstProto::Ack; - cookie[0] = (uint) 0; - cookie[1] = (uint) ack; - } - else - { - ack = (OstProto::Ack*) cookie[1]; - } + cookie[0] = (uint) 0; + cookie[1] = (uint) ack; + } + else + { + ack = (OstProto::Ack*) cookie[1]; + } - Q_ASSERT(cookie != NULL); - op = &cookie[0]; + Q_ASSERT(cookie != NULL); + op = &cookie[0]; - switch (*op) - { - case 0: - { - OstProto::StreamIdList streamIdList; + switch (*op) + { + case 0: + { + OstProto::StreamIdList streamIdList; - qDebug("applying 'deleted streams' ..."); + qDebug("applying 'deleted streams' ..."); - streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - mPorts[portIndex]->getDeletedStreamsSinceLastSync(streamIdList); + streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getDeletedStreamsSinceLastSync(streamIdList); - (*op)++; - rpcController->Reset(); - serviceStub->deleteStream(rpcController, &streamIdList, ack, - ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); - break; - } + (*op)++; + rpcController->Reset(); + serviceStub->deleteStream(rpcController, &streamIdList, ack, + ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); + break; + } - case 1: - { - OstProto::StreamIdList streamIdList; + case 1: + { + OstProto::StreamIdList streamIdList; - qDebug("applying 'new streams' ..."); + qDebug("applying 'new streams' ..."); - streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - mPorts[portIndex]->getNewStreamsSinceLastSync(streamIdList); + streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getNewStreamsSinceLastSync(streamIdList); - (*op)++; - rpcController->Reset(); - serviceStub->addStream(rpcController, &streamIdList, ack, - ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); - break; - } + (*op)++; + rpcController->Reset(); + serviceStub->addStream(rpcController, &streamIdList, ack, + ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); + break; + } - case 2: - { - OstProto::StreamConfigList streamConfigList; + case 2: + { + OstProto::StreamConfigList streamConfigList; - qDebug("applying 'modified streams' ..."); + qDebug("applying 'modified streams' ..."); - streamConfigList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - mPorts[portIndex]->getModifiedStreamsSinceLastSync(streamConfigList); + streamConfigList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getModifiedStreamsSinceLastSync(streamConfigList); - (*op)++; - rpcController->Reset(); - serviceStub->modifyStream(rpcController, &streamConfigList, ack, - ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); - break; - } + (*op)++; + rpcController->Reset(); + serviceStub->modifyStream(rpcController, &streamConfigList, ack, + ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); + break; + } - case 3: - qDebug("apply completed"); - mPorts[portIndex]->when_syncComplete(); - delete cookie; - break; + case 3: + qDebug("apply completed"); + mPorts[portIndex]->when_syncComplete(); + delete cookie; + break; - default: - qDebug("%s: Unknown Op!!!", __FUNCTION__); - break; - } + default: + qDebug("%s: Unknown Op!!!", __FUNCTION__); + break; + } } void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) { - qDebug("got a portlist ..."); + qDebug("got a portlist ..."); - if (rpcController->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _error_exit; - } + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } - emit portListAboutToBeChanged(mPortGroupId); + emit portListAboutToBeChanged(mPortGroupId); - for(int i = 0; i < portIdList->port_id_size(); i++) - { - Port *p; - - p = new Port(portIdList->port_id(i).id(), mPortGroupId); - connect(p, SIGNAL(portDataChanged(int, int)), - this, SIGNAL(portGroupDataChanged(int, int))); - qDebug("before port append\n"); - mPorts.append(p); - } + for(int i = 0; i < portIdList->port_id_size(); i++) + { + Port *p; + + p = new Port(portIdList->port_id(i).id(), mPortGroupId); + connect(p, SIGNAL(portDataChanged(int, int)), + this, SIGNAL(portGroupDataChanged(int, int))); + qDebug("before port append\n"); + mPorts.append(p); + } - emit portListChanged(mPortGroupId); + emit portListChanged(mPortGroupId); - this->portIdList.CopyFrom(*portIdList); + this->portIdList.CopyFrom(*portIdList); - // Request PortConfigList - { - OstProto::PortConfigList *portConfigList; - - qDebug("requesting port config list ..."); - portConfigList = new OstProto::PortConfigList(); - rpcController->Reset(); - serviceStub->getPortConfig(rpcController, - portIdList, portConfigList, NewCallback(this, - &PortGroup::processPortConfigList, portConfigList)); - } + // Request PortConfigList + { + OstProto::PortConfigList *portConfigList; + + qDebug("requesting port config list ..."); + portConfigList = new OstProto::PortConfigList(); + rpcController->Reset(); + serviceStub->getPortConfig(rpcController, + portIdList, portConfigList, NewCallback(this, + &PortGroup::processPortConfigList, portConfigList)); + } - goto _exit; + goto _exit; _error_exit: _exit: - delete portIdList; + delete portIdList; } void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - if (rpcController->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _error_exit; - } + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } - emit portListAboutToBeChanged(mPortGroupId); + emit portListAboutToBeChanged(mPortGroupId); - for(int i = 0; i < portConfigList->port_size(); i++) - { - uint id; + for(int i = 0; i < portConfigList->port_size(); i++) + { + uint id; - id = portConfigList->port(i).port_id().id(); - // FIXME: don't mix port id & index into mPorts[] - mPorts[id]->updatePortConfig(portConfigList->mutable_port(i)); - } + id = portConfigList->port(i).port_id().id(); + // FIXME: don't mix port id & index into mPorts[] + mPorts[id]->updatePortConfig(portConfigList->mutable_port(i)); + } - emit portListChanged(mPortGroupId); + emit portListChanged(mPortGroupId); - // FIXME: check if we need new signals since we are not changing the - // number of ports, just the port data + // FIXME: check if we need new signals since we are not changing the + // number of ports, just the port data - if (numPorts() > 0) - getStreamIdList(); + if (numPorts() > 0) + getStreamIdList(); _error_exit: - delete portConfigList; + delete portConfigList; } void PortGroup::getStreamIdList(int portIndex, - OstProto::StreamIdList *streamIdList) + OstProto::StreamIdList *streamIdList) { - ::OstProto::PortId portId; + ::OstProto::PortId portId; - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - if (streamIdList == NULL) - { - // First invocation (uses default params) - - // request StreamIdList for first port + if (streamIdList == NULL) + { + // First invocation (uses default params) - + // request StreamIdList for first port - Q_ASSERT(portIndex == 0); - Q_ASSERT(numPorts() > 0); - streamIdList = new ::OstProto::StreamIdList(); + Q_ASSERT(portIndex == 0); + Q_ASSERT(numPorts() > 0); + streamIdList = new ::OstProto::StreamIdList(); - goto _request; - } + goto _request; + } - qDebug("got a streamIdlist ..."); + qDebug("got a streamIdlist ..."); - if (rpcController->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _next_port; // FIXME(MED): Partial RPC - } + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _next_port; // FIXME(MED): Partial RPC + } - Q_ASSERT(portIndex < numPorts()); + Q_ASSERT(portIndex < numPorts()); - if (streamIdList->port_id().id() != mPorts[portIndex]->id()) - { - qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", - __FUNCTION__, streamIdList->port_id().id(), mPorts[portIndex]->id(), - portIndex); - goto _next_port; // FIXME(MED): Partial RPC - } + if (streamIdList->port_id().id() != mPorts[portIndex]->id()) + { + qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", + __FUNCTION__, streamIdList->port_id().id(), mPorts[portIndex]->id(), + portIndex); + goto _next_port; // FIXME(MED): Partial RPC + } - // FIXME(MED): need to mPorts.clear()??? - for(int i = 0; i < streamIdList->stream_id_size(); i++) - { - uint streamId; + // FIXME(MED): need to mPorts.clear()??? + for(int i = 0; i < streamIdList->stream_id_size(); i++) + { + uint streamId; - streamId = streamIdList->stream_id(i).id(); - mPorts[portIndex]->insertStream(streamId); - } + streamId = streamIdList->stream_id(i).id(); + mPorts[portIndex]->insertStream(streamId); + } _next_port: - // FIXME(HI): ideally we shd use signals/slots but this means - // we will have to use Port* instead of Port with QList<> - - // need to find a way for this - mPorts[portIndex]->when_syncComplete(); - portIndex++; - if (portIndex >= numPorts()) - { - // We're done for all ports !!! + // FIXME(HI): ideally we shd use signals/slots but this means + // we will have to use Port* instead of Port with QList<> - + // need to find a way for this + mPorts[portIndex]->when_syncComplete(); + portIndex++; + if (portIndex >= numPorts()) + { + // We're done for all ports !!! - // FIXME(HI): some way to reset streammodel + // FIXME(HI): some way to reset streammodel - delete streamIdList; + delete streamIdList; - if (numPorts() > 0) - getStreamConfigList(); + if (numPorts() > 0) + getStreamConfigList(); - goto _exit; - } + goto _exit; + } _request: - portId.set_id(mPorts[portIndex]->id()); - streamIdList->Clear(); + portId.set_id(mPorts[portIndex]->id()); + streamIdList->Clear(); - rpcController->Reset(); - serviceStub->getStreamIdList(rpcController, &portId, streamIdList, - NewCallback(this, &PortGroup::getStreamIdList, - portIndex, streamIdList)); + rpcController->Reset(); + serviceStub->getStreamIdList(rpcController, &portId, streamIdList, + NewCallback(this, &PortGroup::getStreamIdList, + portIndex, streamIdList)); - goto _exit; + goto _exit; _exit: - return; + return; } void PortGroup::getStreamConfigList(int portIndex, - OstProto::StreamConfigList *streamConfigList) + OstProto::StreamConfigList *streamConfigList) { - OstProto::StreamIdList streamIdList; + OstProto::StreamIdList streamIdList; - qDebug("In %s", __PRETTY_FUNCTION__); + qDebug("In %s", __PRETTY_FUNCTION__); - if (streamConfigList == NULL) - { - // First invocation using default params - // - request for first port + if (streamConfigList == NULL) + { + // First invocation using default params + // - request for first port - Q_ASSERT(portIndex == 0); - Q_ASSERT(numPorts() > 0); + Q_ASSERT(portIndex == 0); + Q_ASSERT(numPorts() > 0); - streamConfigList = new OstProto::StreamConfigList; + streamConfigList = new OstProto::StreamConfigList; - goto _request; - } + goto _request; + } - qDebug("got a streamconfiglist"); + qDebug("got a streamconfiglist"); - if (rpcController->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _next_port; - } + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _next_port; + } - Q_ASSERT(portIndex < numPorts()); + Q_ASSERT(portIndex < numPorts()); - if (streamConfigList->port_id().id() != mPorts[portIndex]->id()) - { - qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", - __FUNCTION__, streamConfigList->port_id().id(), - mPorts[portIndex]->id(), portIndex); - goto _next_port; // FIXME(MED): Partial RPC - } + if (streamConfigList->port_id().id() != mPorts[portIndex]->id()) + { + qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", + __FUNCTION__, streamConfigList->port_id().id(), + mPorts[portIndex]->id(), portIndex); + goto _next_port; // FIXME(MED): Partial RPC + } - // FIXME(MED): need to mStreams.clear()??? - for(int i = 0; i < streamConfigList->stream_size(); i++) - { - uint streamId; + // FIXME(MED): need to mStreams.clear()??? + for(int i = 0; i < streamConfigList->stream_size(); i++) + { + uint streamId; - streamId = streamConfigList->stream(i).stream_id().id(); - mPorts[portIndex]->updateStream(streamId, - streamConfigList->mutable_stream(i)); - } + streamId = streamConfigList->stream(i).stream_id().id(); + mPorts[portIndex]->updateStream(streamId, + streamConfigList->mutable_stream(i)); + } _next_port: - portIndex++; + portIndex++; - if (portIndex >= numPorts()) - { - // We're done for all ports !!! + if (portIndex >= numPorts()) + { + // We're done for all ports !!! - // FIXME(HI): some way to reset streammodel + // FIXME(HI): some way to reset streammodel - delete streamConfigList; - goto _exit; - } + delete streamConfigList; + goto _exit; + } _request: - qDebug("requesting stream config list ..."); + qDebug("requesting stream config list ..."); - streamIdList.Clear(); - streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - for (int j = 0; j < mPorts[portIndex]->numStreams(); j++) - { - OstProto::StreamId *s; + streamIdList.Clear(); + streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + for (int j = 0; j < mPorts[portIndex]->numStreams(); j++) + { + OstProto::StreamId *s; - s = streamIdList.add_stream_id(); - s->set_id(mPorts[portIndex]->streamByIndex(j)->id()); - } - streamConfigList->Clear(); + s = streamIdList.add_stream_id(); + s->set_id(mPorts[portIndex]->streamByIndex(j)->id()); + } + streamConfigList->Clear(); - rpcController->Reset(); - serviceStub->getStreamConfig(rpcController, - &streamIdList, streamConfigList, NewCallback(this, - &PortGroup::getStreamConfigList, portIndex, streamConfigList)); + rpcController->Reset(); + serviceStub->getStreamConfig(rpcController, + &streamIdList, streamConfigList, NewCallback(this, + &PortGroup::getStreamConfigList, portIndex, streamConfigList)); _exit: - return; + return; } void PortGroup::processModifyStreamAck(OstProto::Ack *ack) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - qDebug("Modify Successful!!"); + qDebug("Modify Successful!!"); - // TODO(HI): Apply Button should now be disabled???!!!!??? + // TODO(HI): Apply Button should now be disabled???!!!!??? } void PortGroup::startTx(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; + OstProto::PortIdList portIdList; + OstProto::Ack *ack; - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - if (state() != QAbstractSocket::ConnectedState) - return; + if (state() != QAbstractSocket::ConnectedState) + return; - ack = new OstProto::Ack; - if (portList == NULL) - goto _exit; - else - { - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } - } + ack = new OstProto::Ack; + if (portList == NULL) + goto _exit; + else + { + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + } - serviceStub->startTx(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStartTxAck, ack)); + serviceStub->startTx(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStartTxAck, ack)); _exit: - return; + return; } void PortGroup::stopTx(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; + OstProto::PortIdList portIdList; + OstProto::Ack *ack; - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - if (state() != QAbstractSocket::ConnectedState) - goto _exit; + if (state() != QAbstractSocket::ConnectedState) + goto _exit; - if ((portList == NULL) || (portList->size() == 0)) - goto _exit; + if ((portList == NULL) || (portList->size() == 0)) + goto _exit; - ack = new OstProto::Ack; + ack = new OstProto::Ack; - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } - rpcController->Reset(); - serviceStub->stopTx(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStopTxAck, ack)); + rpcController->Reset(); + serviceStub->stopTx(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStopTxAck, ack)); _exit: - return; + return; } void PortGroup::startCapture(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; + OstProto::PortIdList portIdList; + OstProto::Ack *ack; - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - if (state() != QAbstractSocket::ConnectedState) - return; + if (state() != QAbstractSocket::ConnectedState) + return; - if ((portList == NULL) || (portList->size() == 0)) - goto _exit; + if ((portList == NULL) || (portList->size() == 0)) + goto _exit; - ack = new OstProto::Ack; + ack = new OstProto::Ack; - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } - rpcController->Reset(); - serviceStub->startCapture(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStartCaptureAck, ack)); + rpcController->Reset(); + serviceStub->startCapture(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStartCaptureAck, ack)); _exit: - return; + return; } void PortGroup::stopCapture(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; + OstProto::PortIdList portIdList; + OstProto::Ack *ack; - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - if (state() != QAbstractSocket::ConnectedState) - return; + if (state() != QAbstractSocket::ConnectedState) + return; - if ((portList == NULL) || (portList->size() == 0)) - goto _exit; + if ((portList == NULL) || (portList->size() == 0)) + goto _exit; - ack = new OstProto::Ack; - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } + ack = new OstProto::Ack; + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } - rpcController->Reset(); - serviceStub->stopCapture(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStopCaptureAck, ack)); + rpcController->Reset(); + serviceStub->stopCapture(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStopCaptureAck, ack)); _exit: - return; + return; } void PortGroup::viewCapture(QList *portList) { - static QTemporaryFile *capFile = NULL; + static QTemporaryFile *capFile = NULL; - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - if (state() != QAbstractSocket::ConnectedState) - goto _exit; + if (state() != QAbstractSocket::ConnectedState) + goto _exit; - if ((portList == NULL) || (portList->size() != 1)) - goto _exit; + if ((portList == NULL) || (portList->size() != 1)) + goto _exit; - if (capFile) - delete capFile; + if (capFile) + delete capFile; - /*! \todo (MED) unable to reuse the same file 'coz capFile->resize(0) is - not working - it fails everytime */ - capFile = new QTemporaryFile(); - capFile->open(); - qDebug("Temp CapFile = %s", capFile->fileName().toAscii().constData()); + /*! \todo (MED) unable to reuse the same file 'coz capFile->resize(0) is + not working - it fails everytime */ + capFile = new QTemporaryFile(); + capFile->open(); + qDebug("Temp CapFile = %s", capFile->fileName().toAscii().constData()); - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId portId; - OstProto::CaptureBuffer *buf; + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId portId; + OstProto::CaptureBuffer *buf; - portId.set_id(portList->at(i)); + portId.set_id(portList->at(i)); - buf = new OstProto::CaptureBuffer; - rpcController->Reset(); - rpcController->setBinaryBlob(capFile); - serviceStub->getCaptureBuffer(rpcController, &portId, buf, - NewCallback(this, &PortGroup::processViewCaptureAck, buf, (QFile*) capFile)); - } + buf = new OstProto::CaptureBuffer; + rpcController->Reset(); + rpcController->setBinaryBlob(capFile); + serviceStub->getCaptureBuffer(rpcController, &portId, buf, + NewCallback(this, &PortGroup::processViewCaptureAck, buf, (QFile*) capFile)); + } _exit: - return; + return; } -void PortGroup::processStartTxAck(OstProto::Ack *ack) +void PortGroup::processStartTxAck(OstProto::Ack *ack) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - delete ack; + delete ack; } -void PortGroup::processStopTxAck(OstProto::Ack *ack) +void PortGroup::processStopTxAck(OstProto::Ack *ack) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - delete ack; + delete ack; } -void PortGroup::processStartCaptureAck(OstProto::Ack *ack) +void PortGroup::processStartCaptureAck(OstProto::Ack *ack) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - delete ack; + delete ack; } -void PortGroup::processStopCaptureAck(OstProto::Ack *ack) +void PortGroup::processStopCaptureAck(OstProto::Ack *ack) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - delete ack; + delete ack; } void PortGroup::processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - capFile->flush(); - capFile->close(); + capFile->flush(); + capFile->close(); - if (!QProcess::startDetached("C:/Program Files/Wireshark/wireshark.exe", - QStringList() << capFile->fileName())) - qDebug("Failed starting Wireshark"); + if (!QProcess::startDetached("C:/Program Files/Wireshark/wireshark.exe", + QStringList() << capFile->fileName())) + qDebug("Failed starting Wireshark"); - delete buf; + delete buf; } void PortGroup::getPortStats() { - OstProto::PortStatsList *portStatsList; + OstProto::PortStatsList *portStatsList; - //qDebug("In %s", __FUNCTION__); + //qDebug("In %s", __FUNCTION__); - if (state() != QAbstractSocket::ConnectedState) - return; + if (state() != QAbstractSocket::ConnectedState) + return; - if (isGetStatsPending_) - return; + if (isGetStatsPending_) + return; - portStatsList = new OstProto::PortStatsList; - rpcControllerStats->Reset(); - isGetStatsPending_ = true; - serviceStub->getStats(rpcControllerStats, &portIdList, portStatsList, - NewCallback(this, &PortGroup::processPortStatsList, portStatsList)); + portStatsList = new OstProto::PortStatsList; + rpcControllerStats->Reset(); + isGetStatsPending_ = true; + serviceStub->getStats(rpcControllerStats, &portIdList, portStatsList, + NewCallback(this, &PortGroup::processPortStatsList, portStatsList)); } void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList) { - //qDebug("In %s", __FUNCTION__); + //qDebug("In %s", __FUNCTION__); - if (rpcControllerStats->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _error_exit; - } + if (rpcControllerStats->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } - for(int i = 0; i < portStatsList->port_stats_size(); i++) - { - uint id; + for(int i = 0; i < portStatsList->port_stats_size(); i++) + { + uint id; - id = portStatsList->port_stats(i).port_id().id(); - // FIXME: don't mix port id & index into mPorts[] - mPorts[id]->updateStats(portStatsList->mutable_port_stats(i)); - } + id = portStatsList->port_stats(i).port_id().id(); + // FIXME: don't mix port id & index into mPorts[] + mPorts[id]->updateStats(portStatsList->mutable_port_stats(i)); + } - emit statsChanged(mPortGroupId); + emit statsChanged(mPortGroupId); _error_exit: - delete portStatsList; - isGetStatsPending_ = false; + delete portStatsList; + isGetStatsPending_ = false; } void PortGroup::clearPortStats(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; + OstProto::PortIdList portIdList; + OstProto::Ack *ack; - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - if (state() != QAbstractSocket::ConnectedState) - return; + if (state() != QAbstractSocket::ConnectedState) + return; - ack = new OstProto::Ack; - if (portList == NULL) - portIdList.CopyFrom(this->portIdList); - else - { - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; + ack = new OstProto::Ack; + if (portList == NULL) + portIdList.CopyFrom(this->portIdList); + else + { + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } - } + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + } - rpcController->Reset(); - serviceStub->clearStats(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processClearStatsAck, ack)); + rpcController->Reset(); + serviceStub->clearStats(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processClearStatsAck, ack)); } -void PortGroup::processClearStatsAck(OstProto::Ack *ack) +void PortGroup::processClearStatsAck(OstProto::Ack *ack) { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - // Refresh stats immediately after a stats clear/reset - getPortStats(); + // Refresh stats immediately after a stats clear/reset + getPortStats(); - delete ack; + delete ack; } diff --git a/client/portgroup.h b/client/portgroup.h index f4d8e99..a503910 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -15,104 +15,104 @@ LOW - Allow hostnames in addition to IP Address as "server address" */ -#define DEFAULT_SERVER_PORT 7878 +#define DEFAULT_SERVER_PORT 7878 class QFile; class PortGroup : public QObject { - Q_OBJECT + Q_OBJECT private: - quint32 mPortGroupId; - static quint32 mPortGroupAllocId; - QString mUserAlias; // user defined + quint32 mPortGroupId; + static quint32 mPortGroupAllocId; + QString mUserAlias; // user defined #if 0 // PB - QTcpSocket *mpSocket; - QHostAddress mServerAddress; - quint16 mServerPort; + QTcpSocket *mpSocket; + QHostAddress mServerAddress; + quint16 mServerPort; #endif - PbRpcChannel *rpcChannel; - PbRpcController *rpcController; - PbRpcController *rpcControllerStats; - bool isGetStatsPending_; - ::OstProto::OstService::Stub *serviceStub; + PbRpcChannel *rpcChannel; + PbRpcController *rpcController; + PbRpcController *rpcControllerStats; + bool isGetStatsPending_; + ::OstProto::OstService::Stub *serviceStub; - ::OstProto::PortIdList portIdList; + ::OstProto::PortIdList portIdList; public: // FIXME(HIGH): member access - QList mPorts; + QList mPorts; public: - PortGroup(QHostAddress ip = QHostAddress::LocalHost, - quint16 port = DEFAULT_SERVER_PORT); - ~PortGroup(); + PortGroup(QHostAddress ip = QHostAddress::LocalHost, + quint16 port = DEFAULT_SERVER_PORT); + ~PortGroup(); - void connectToHost() { rpcChannel->establish(); } - void connectToHost(QHostAddress ip, quint16 port) - { rpcChannel->establish(ip, port); } - void disconnectFromHost() { rpcChannel->tearDown(); } + void connectToHost() { rpcChannel->establish(); } + void connectToHost(QHostAddress ip, quint16 port) + { rpcChannel->establish(ip, port); } + void disconnectFromHost() { rpcChannel->tearDown(); } - int numPorts() const { return mPorts.size(); } - quint32 id() const { return mPortGroupId; } + int numPorts() const { return mPorts.size(); } + quint32 id() const { return mPortGroupId; } - const QString& userAlias() const { return mUserAlias; } - void setUserAlias(QString alias) { mUserAlias = alias; }; + const QString& userAlias() const { return mUserAlias; } + void setUserAlias(QString alias) { mUserAlias = alias; }; - const QHostAddress& serverAddress() const - { return rpcChannel->serverAddress(); } - quint16 serverPort() const - { return rpcChannel->serverPort(); } - QAbstractSocket::SocketState state() const - { return rpcChannel->state(); } + const QHostAddress& serverAddress() const + { return rpcChannel->serverAddress(); } + quint16 serverPort() const + { return rpcChannel->serverPort(); } + QAbstractSocket::SocketState state() const + { return rpcChannel->state(); } - void processPortIdList(OstProto::PortIdList *portIdList); - void processPortConfigList(OstProto::PortConfigList *portConfigList); + void processPortIdList(OstProto::PortIdList *portIdList); + void processPortConfigList(OstProto::PortConfigList *portConfigList); - void getStreamIdList(int portIndex = 0, - OstProto::StreamIdList *streamIdList = NULL); - void getStreamConfigList(int portIndex = 0, - OstProto::StreamConfigList *streamConfigList = NULL); + void getStreamIdList(int portIndex = 0, + OstProto::StreamIdList *streamIdList = NULL); + void getStreamConfigList(int portIndex = 0, + OstProto::StreamConfigList *streamConfigList = NULL); - void processModifyStreamAck(OstProto::Ack *ack); + void processModifyStreamAck(OstProto::Ack *ack); - void startTx(QList *portList = NULL); - void processStartTxAck(OstProto::Ack *ack); - void stopTx(QList *portList = NULL); - void processStopTxAck(OstProto::Ack *ack); + void startTx(QList *portList = NULL); + void processStartTxAck(OstProto::Ack *ack); + void stopTx(QList *portList = NULL); + void processStopTxAck(OstProto::Ack *ack); - void startCapture(QList *portList = NULL); - void processStartCaptureAck(OstProto::Ack *ack); - void stopCapture(QList *portList = NULL); - void processStopCaptureAck(OstProto::Ack *ack); - void viewCapture(QList *portList = NULL); - void processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile); + void startCapture(QList *portList = NULL); + void processStartCaptureAck(OstProto::Ack *ack); + void stopCapture(QList *portList = NULL); + void processStopCaptureAck(OstProto::Ack *ack); + void viewCapture(QList *portList = NULL); + void processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile); - void getPortStats(); - void processPortStatsList(OstProto::PortStatsList *portStatsList); - void clearPortStats(QList *portList = NULL); - void processClearStatsAck(OstProto::Ack *ack); + void getPortStats(); + void processPortStatsList(OstProto::PortStatsList *portStatsList); + void clearPortStats(QList *portList = NULL); + void processClearStatsAck(OstProto::Ack *ack); signals: - void portGroupDataChanged(int portGroupId, int portId = 0xFFFF); - void portListAboutToBeChanged(quint32 portGroupId); - void portListChanged(quint32 portGroupId); - void statsChanged(quint32 portGroupId); + void portGroupDataChanged(int portGroupId, int portId = 0xFFFF); + void portListAboutToBeChanged(quint32 portGroupId); + void portListChanged(quint32 portGroupId); + void statsChanged(quint32 portGroupId); private slots: - void on_rpcChannel_stateChanged(); - void on_rpcChannel_connected(); - void on_rpcChannel_disconnected(); - void on_rpcChannel_error(QAbstractSocket::SocketError socketError); + void on_rpcChannel_stateChanged(); + void on_rpcChannel_connected(); + void on_rpcChannel_disconnected(); + void on_rpcChannel_error(QAbstractSocket::SocketError socketError); public slots: - void when_configApply(int portIndex, uint *cookie = NULL); + void when_configApply(int portIndex, uint *cookie = NULL); #if 0 // PB - void on_rpcChannel_when_dataAvail(); + void on_rpcChannel_when_dataAvail(); #endif private: #if 0 // PB - void ProcessCapabilityInfo(const char *msg, qint32 size); - void ProcessMsg(const char *msg, quint32 size); + void ProcessCapabilityInfo(const char *msg, qint32 size); + void ProcessMsg(const char *msg, quint32 size); #endif }; diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index e5aa69e..3e67d01 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -4,85 +4,85 @@ #include PortGroupList::PortGroupList() - : mPortGroupListModel(this), - mStreamListModel(this), - mPortStatsModel(this, this) + : mPortGroupListModel(this), + mStreamListModel(this), + mPortStatsModel(this, this) { - PortGroup *pg; + PortGroup *pg; - // TODO(LOW): Remove - new ModelTest(getStreamModel()); - new ModelTest(getPortModel()); - new ModelTest(getPortStatsModel()); - - // Add the "Local" Port Group - pg = new PortGroup; - addPortGroup(*pg); + // TODO(LOW): Remove + new ModelTest(getStreamModel()); + new ModelTest(getPortModel()); + new ModelTest(getPortStatsModel()); + + // Add the "Local" Port Group + pg = new PortGroup; + addPortGroup(*pg); } bool PortGroupList::isPortGroup(const QModelIndex& index) { - return mPortGroupListModel.isPortGroup(index); + return mPortGroupListModel.isPortGroup(index); } bool PortGroupList::isPort(const QModelIndex& index) { - return mPortGroupListModel.isPort(index); + return mPortGroupListModel.isPort(index); } PortGroup& PortGroupList::portGroup(const QModelIndex& index) { - Q_ASSERT(mPortGroupListModel.isPortGroup(index)); + Q_ASSERT(mPortGroupListModel.isPortGroup(index)); - return *(mPortGroups[index.row()]); + return *(mPortGroups[index.row()]); } Port& PortGroupList::port(const QModelIndex& index) { - Q_ASSERT(mPortGroupListModel.isPort(index)); - return (*mPortGroups.at(index.parent().row())->mPorts[index.row()]); + Q_ASSERT(mPortGroupListModel.isPort(index)); + return (*mPortGroups.at(index.parent().row())->mPorts[index.row()]); } void PortGroupList::addPortGroup(PortGroup &portGroup) { - mPortGroupListModel.portGroupAboutToBeAppended(); + mPortGroupListModel.portGroupAboutToBeAppended(); - connect(&portGroup, SIGNAL(portGroupDataChanged(int, int)), - &mPortGroupListModel, SLOT(when_portGroupDataChanged(int, int))); + connect(&portGroup, SIGNAL(portGroupDataChanged(int, int)), + &mPortGroupListModel, SLOT(when_portGroupDataChanged(int, int))); #if 0 - connect(&portGroup, SIGNAL(portListAboutToBeChanged(quint32)), - &mPortGroupListModel, SLOT(triggerLayoutAboutToBeChanged())); - connect(&portGroup, SIGNAL(portListChanged(quint32)), - &mPortGroupListModel, SLOT(triggerLayoutChanged())); + connect(&portGroup, SIGNAL(portListAboutToBeChanged(quint32)), + &mPortGroupListModel, SLOT(triggerLayoutAboutToBeChanged())); + connect(&portGroup, SIGNAL(portListChanged(quint32)), + &mPortGroupListModel, SLOT(triggerLayoutChanged())); #endif - connect(&portGroup, SIGNAL(portListChanged(quint32)), - &mPortGroupListModel, SLOT(when_portListChanged())); + connect(&portGroup, SIGNAL(portListChanged(quint32)), + &mPortGroupListModel, SLOT(when_portListChanged())); - connect(&portGroup, SIGNAL(portListChanged(quint32)), - &mPortStatsModel, SLOT(when_portListChanged())); + connect(&portGroup, SIGNAL(portListChanged(quint32)), + &mPortStatsModel, SLOT(when_portListChanged())); - connect(&portGroup, SIGNAL(statsChanged(quint32)), - &mPortStatsModel, SLOT(when_portGroup_stats_update(quint32))); + connect(&portGroup, SIGNAL(statsChanged(quint32)), + &mPortStatsModel, SLOT(when_portGroup_stats_update(quint32))); - mPortGroups.append(&portGroup); - portGroup.connectToHost(); + mPortGroups.append(&portGroup); + portGroup.connectToHost(); - mPortGroupListModel.portGroupAppended(); + mPortGroupListModel.portGroupAppended(); - mPortStatsModel.when_portListChanged(); + mPortStatsModel.when_portListChanged(); } void PortGroupList::removePortGroup(PortGroup &portGroup) { - mPortGroupListModel.portGroupAboutToBeRemoved(&portGroup); + mPortGroupListModel.portGroupAboutToBeRemoved(&portGroup); - PortGroup* pg = mPortGroups.takeAt(mPortGroups.indexOf(&portGroup)); - qDebug("after takeAt()"); - mPortGroupListModel.portGroupRemoved(); + PortGroup* pg = mPortGroups.takeAt(mPortGroups.indexOf(&portGroup)); + qDebug("after takeAt()"); + mPortGroupListModel.portGroupRemoved(); - delete pg; + delete pg; - mPortStatsModel.when_portListChanged(); + mPortStatsModel.when_portListChanged(); } //.................... @@ -90,9 +90,9 @@ void PortGroupList::removePortGroup(PortGroup &portGroup) //.................... int PortGroupList::indexOfPortGroup(quint32 portGroupId) { - for (int i = 0; i < mPortGroups.size(); i++) { - if (mPortGroups.value(i)->id() == portGroupId) - return i; - } - return -1; + for (int i = 0; i < mPortGroups.size(); i++) { + if (mPortGroups.value(i)->id() == portGroupId) + return i; + } + return -1; } diff --git a/client/portgrouplist.h b/client/portgrouplist.h index 89256eb..e5e398b 100644 --- a/client/portgrouplist.h +++ b/client/portgrouplist.h @@ -13,39 +13,39 @@ class StreamModel; class PortGroupList : public QObject { - Q_OBJECT + Q_OBJECT - friend class PortModel; - friend class StreamModel; - friend class PortStatsModel; + friend class PortModel; + friend class StreamModel; + friend class PortStatsModel; - QList mPortGroups; - PortModel mPortGroupListModel; - StreamModel mStreamListModel; - PortStatsModel mPortStatsModel; + QList mPortGroups; + PortModel mPortGroupListModel; + StreamModel mStreamListModel; + PortStatsModel mPortStatsModel; // Methods public: - PortGroupList(); + PortGroupList(); - PortModel* getPortModel() { return &mPortGroupListModel; } - PortStatsModel* getPortStatsModel() { return &mPortStatsModel; } - StreamModel* getStreamModel() { return &mStreamListModel; } + PortModel* getPortModel() { return &mPortGroupListModel; } + PortStatsModel* getPortStatsModel() { return &mPortStatsModel; } + StreamModel* getStreamModel() { return &mStreamListModel; } - bool isPortGroup(const QModelIndex& index); - bool isPort(const QModelIndex& index); - PortGroup& portGroup(const QModelIndex& index); - Port& port(const QModelIndex& index); + bool isPortGroup(const QModelIndex& index); + bool isPort(const QModelIndex& index); + PortGroup& portGroup(const QModelIndex& index); + Port& port(const QModelIndex& index); - int numPortGroups() { return mPortGroups.size(); } - PortGroup& portGroupByIndex(int index) { return *(mPortGroups[index]); } + int numPortGroups() { return mPortGroups.size(); } + PortGroup& portGroupByIndex(int index) { return *(mPortGroups[index]); } - void addPortGroup(PortGroup &portGroup); - void removePortGroup(PortGroup &portGroup); + void addPortGroup(PortGroup &portGroup); + void removePortGroup(PortGroup &portGroup); private: - int indexOfPortGroup(quint32 portGroupId); + int indexOfPortGroup(quint32 portGroupId); }; diff --git a/client/portmodel.cpp b/client/portmodel.cpp index 480b642..ff5c482 100644 --- a/client/portmodel.cpp +++ b/client/portmodel.cpp @@ -3,260 +3,260 @@ #include #if 0 -#define DBG0(x) qDebug(x) -#define DBG1(x, p1) qDebug(x, (p1)) +#define DBG0(x) qDebug(x) +#define DBG1(x, p1) qDebug(x, (p1)) #else -#define DBG0(x) {} -#define DBG1(x, p1) {} +#define DBG0(x) {} +#define DBG1(x, p1) {} #endif PortModel::PortModel(PortGroupList *p, QObject *parent) - : QAbstractItemModel(parent) + : QAbstractItemModel(parent) { - pgl = p; + pgl = p; } int PortModel::rowCount(const QModelIndex &parent) const { - // qDebug("RowCount Enter\n"); - if (!parent.isValid()) - { - // Top Level Item - //qDebug("RowCount (Top) Exit: %d\n", pgl->mPortGroups.size()); - return pgl->mPortGroups.size(); - } - // qDebug("RowCount non top %d, %d, %llx\n", - // parent.row(), parent.column(), parent.internalId()); + // qDebug("RowCount Enter\n"); + if (!parent.isValid()) + { + // Top Level Item + //qDebug("RowCount (Top) Exit: %d\n", pgl->mPortGroups.size()); + return pgl->mPortGroups.size(); + } + // qDebug("RowCount non top %d, %d, %llx\n", + // parent.row(), parent.column(), parent.internalId()); - quint16 pg = (parent.internalId() >> 16) & 0xFFFF; - quint16 p = parent.internalId() & 0xFFFF; - if (p == 0xFFFF) - { + quint16 pg = (parent.internalId() >> 16) & 0xFFFF; + quint16 p = parent.internalId() & 0xFFFF; + if (p == 0xFFFF) + { #if 0 // wrong code? - int count = 0; - foreach(PortGroup *pg, pgl->mPortGroups) - { - count += pg->numPorts(); - } - //qDebug("RowCount (Mid) Exit: %d\n", count); - return count; + int count = 0; + foreach(PortGroup *pg, pgl->mPortGroups) + { + count += pg->numPorts(); + } + //qDebug("RowCount (Mid) Exit: %d\n", count); + return count; #endif - if (parent.column() == 0) - return pgl->mPortGroups.value(pgl->indexOfPortGroup(pg))->numPorts(); - else - return 0; - } - else - { - // Leaf Item - return 0; - } + if (parent.column() == 0) + return pgl->mPortGroups.value(pgl->indexOfPortGroup(pg))->numPorts(); + else + return 0; + } + else + { + // Leaf Item + return 0; + } } int PortModel::columnCount(const QModelIndex &parent ) const { - return 1; // FIXME: hardcoding + return 1; // FIXME: hardcoding } Qt::ItemFlags PortModel::flags(const QModelIndex &index) const { - return QAbstractItemModel::flags(index); // FIXME: no need for this func + return QAbstractItemModel::flags(index); // FIXME: no need for this func } QVariant PortModel::data(const QModelIndex &index, int role) const { - DBG0("Enter PortModel data\n"); + DBG0("Enter PortModel data\n"); - // Check for a valid index - if (!index.isValid()) - return QVariant(); + // Check for a valid index + if (!index.isValid()) + return QVariant(); - DBG1("PortModel::data(index).row = %d", index.row()); - DBG1("PortModel::data(index).column = %0d", index.column()); - DBG1("PortModel::data(index).internalId = %08llx", index.internalId()); + DBG1("PortModel::data(index).row = %d", index.row()); + DBG1("PortModel::data(index).column = %0d", index.column()); + DBG1("PortModel::data(index).internalId = %08llx", index.internalId()); - QModelIndex parent = index.parent(); + QModelIndex parent = index.parent(); - if (!parent.isValid()) - { - // Top Level Item - PortGroup - if ((role == Qt::DisplayRole)) - { - DBG0("Exit PortModel data 1\n"); - return QString("Port Group %1: %2 [%3:%4] (%5)"). - arg(pgl->mPortGroups.at(index.row())->id()). - arg(pgl->mPortGroups.at(index.row())->userAlias()). - arg(pgl->mPortGroups.at(index.row())->serverAddress().toString()). - arg(pgl->mPortGroups.at(index.row())->serverPort()). - arg(pgl->mPortGroups.value(index.row())->numPorts()); - } - else if ((role == Qt::DecorationRole)) - { - DBG0("Exit PortModel data 2\n"); - switch(pgl->mPortGroups.at(index.row())->state()) - { - case QAbstractSocket::UnconnectedState: - return QIcon(":/icons/bullet_red.png"); + if (!parent.isValid()) + { + // Top Level Item - PortGroup + if ((role == Qt::DisplayRole)) + { + DBG0("Exit PortModel data 1\n"); + return QString("Port Group %1: %2 [%3:%4] (%5)"). + arg(pgl->mPortGroups.at(index.row())->id()). + arg(pgl->mPortGroups.at(index.row())->userAlias()). + arg(pgl->mPortGroups.at(index.row())->serverAddress().toString()). + arg(pgl->mPortGroups.at(index.row())->serverPort()). + arg(pgl->mPortGroups.value(index.row())->numPorts()); + } + else if ((role == Qt::DecorationRole)) + { + DBG0("Exit PortModel data 2\n"); + switch(pgl->mPortGroups.at(index.row())->state()) + { + case QAbstractSocket::UnconnectedState: + return QIcon(":/icons/bullet_red.png"); - case QAbstractSocket::HostLookupState: - return QIcon(":/icons/bullet_yellow.png"); + case QAbstractSocket::HostLookupState: + return QIcon(":/icons/bullet_yellow.png"); - case QAbstractSocket::ConnectingState: - case QAbstractSocket::ClosingState: - return QIcon(":/icons/bullet_orange.png"); + case QAbstractSocket::ConnectingState: + case QAbstractSocket::ClosingState: + return QIcon(":/icons/bullet_orange.png"); - case QAbstractSocket::ConnectedState: - return QIcon(":/icons/bullet_green.png"); + case QAbstractSocket::ConnectedState: + return QIcon(":/icons/bullet_green.png"); - case QAbstractSocket::BoundState: - case QAbstractSocket::ListeningState: - default: - return QIcon(":/icons/bullet_error.png"); - } - } - else - { - DBG0("Exit PortModel data 3\n"); - return QVariant(); - } - } - else - { - // Non Top Level - Port - if ((role == Qt::DisplayRole)) - { - DBG0("Exit PortModel data 4\n"); - if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) - return QVariant(); + case QAbstractSocket::BoundState: + case QAbstractSocket::ListeningState: + default: + return QIcon(":/icons/bullet_error.png"); + } + } + else + { + DBG0("Exit PortModel data 3\n"); + return QVariant(); + } + } + else + { + // Non Top Level - Port + if ((role == Qt::DisplayRole)) + { + DBG0("Exit PortModel data 4\n"); + if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) + return QVariant(); - return QString("Port %1: %2 [%3] (%4)"). - arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()]->id()). - arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()]->name()). - arg(QHostAddress("0.0.0.0").toString()). // FIXME(LOW) - arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()]->description()); - } - else if ((role == Qt::DecorationRole)) - { - DBG0("Exit PortModel data 5\n"); - if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) - return QVariant(); - switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()]->linkState()) - { - case OstProto::LinkStateUnknown: - return QIcon(":/icons/bullet_white.png"); - case OstProto::LinkStateDown: - return QIcon(":/icons/bullet_red.png"); - case OstProto::LinkStateUp: - return QIcon(":/icons/bullet_green.png"); - default: - qFatal("unexpected/unimplemented port oper state"); - } - } - else - { - DBG0("Exit PortModel data 6\n"); - return QVariant(); - } - } + return QString("Port %1: %2 [%3] (%4)"). + arg(pgl->mPortGroups.at( + parent.row())->mPorts[index.row()]->id()). + arg(pgl->mPortGroups.at( + parent.row())->mPorts[index.row()]->name()). + arg(QHostAddress("0.0.0.0").toString()). // FIXME(LOW) + arg(pgl->mPortGroups.at( + parent.row())->mPorts[index.row()]->description()); + } + else if ((role == Qt::DecorationRole)) + { + DBG0("Exit PortModel data 5\n"); + if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) + return QVariant(); + switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()]->linkState()) + { + case OstProto::LinkStateUnknown: + return QIcon(":/icons/bullet_white.png"); + case OstProto::LinkStateDown: + return QIcon(":/icons/bullet_red.png"); + case OstProto::LinkStateUp: + return QIcon(":/icons/bullet_green.png"); + default: + qFatal("unexpected/unimplemented port oper state"); + } + } + else + { + DBG0("Exit PortModel data 6\n"); + return QVariant(); + } + } - return QVariant(); + return QVariant(); } QVariant PortModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (role != Qt::DisplayRole) - return QVariant(); + if (role != Qt::DisplayRole) + return QVariant(); - if (orientation == Qt::Horizontal) - return QVariant(); - else - return QString("Name"); + if (orientation == Qt::Horizontal) + return QVariant(); + else + return QString("Name"); } QModelIndex PortModel::index (int row, int col, - const QModelIndex & parent) const + const QModelIndex & parent) const { - if (!hasIndex(row, col, parent)) - return QModelIndex(); - - //qDebug("index: R=%d, C=%d, PR=%d, PC=%d, PID=%llx\n", - // row, col, parent.row(), parent.column(), parent.internalId()); + if (!hasIndex(row, col, parent)) + return QModelIndex(); + + //qDebug("index: R=%d, C=%d, PR=%d, PC=%d, PID=%llx\n", + // row, col, parent.row(), parent.column(), parent.internalId()); - if (!parent.isValid()) - { - // Top Level Item - quint16 pg = pgl->mPortGroups.value(row)->id(), p = 0xFFFF; - quint32 id = (pg << 16) | p; - //qDebug("index (top) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); + if (!parent.isValid()) + { + // Top Level Item + quint16 pg = pgl->mPortGroups.value(row)->id(), p = 0xFFFF; + quint32 id = (pg << 16) | p; + //qDebug("index (top) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); - return createIndex(row, col, id); - } - else - { - quint16 pg = parent.internalId() >> 16; - quint16 p = pgl->mPortGroups.value(parent.row())->mPorts.value(row)->id(); - quint32 id = (pg << 16) | p; - //qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); + return createIndex(row, col, id); + } + else + { + quint16 pg = parent.internalId() >> 16; + quint16 p = pgl->mPortGroups.value(parent.row())->mPorts.value(row)->id(); + quint32 id = (pg << 16) | p; + //qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); - return createIndex(row, col, id); - } + return createIndex(row, col, id); + } } QModelIndex PortModel::parent(const QModelIndex &index) const { - if (!index.isValid()) - return QModelIndex(); - - //qDebug("parent: R=%d, C=%d ID=%llx\n", - // index.row(), index.column(), index.internalId()); + if (!index.isValid()) + return QModelIndex(); + + //qDebug("parent: R=%d, C=%d ID=%llx\n", + // index.row(), index.column(), index.internalId()); - quint16 pg = index.internalId() >> 16; - quint16 p = index.internalId() & 0x0000FFFF; + quint16 pg = index.internalId() >> 16; + quint16 p = index.internalId() & 0x0000FFFF; - //qDebug("parent dbg: PG=%d, P=%d\n", pg, p); + //qDebug("parent dbg: PG=%d, P=%d\n", pg, p); - if (p == 0xFFFF) - { - //qDebug("parent ret: NULL\n"); - // Top Level Item - PG - return QModelIndex(); - } + if (p == 0xFFFF) + { + //qDebug("parent ret: NULL\n"); + // Top Level Item - PG + return QModelIndex(); + } - quint32 id = (pg << 16) | 0xFFFF; - //qDebug("parent ret: R=%d, C=%d, ID=%x\n", pg, 0, id); + quint32 id = (pg << 16) | 0xFFFF; + //qDebug("parent ret: R=%d, C=%d, ID=%x\n", pg, 0, id); - return createIndex(pgl->indexOfPortGroup(pg), 0, id); + return createIndex(pgl->indexOfPortGroup(pg), 0, id); } bool PortModel::isPortGroup(const QModelIndex& index) { - if ((index.internalId() & 0xFFFF) == 0xFFFF) - return true; - else - return false; + if ((index.internalId() & 0xFFFF) == 0xFFFF) + return true; + else + return false; } bool PortModel::isPort(const QModelIndex& index) { - if ((index.internalId() & 0xFFFF) != 0xFFFF) - return true; - else - return false; + if ((index.internalId() & 0xFFFF) != 0xFFFF) + return true; + else + return false; } quint32 PortModel::portGroupId(const QModelIndex& index) { - return (index.internalId()) >> 16 & 0xFFFF; + return (index.internalId()) >> 16 & 0xFFFF; } quint32 PortModel::portId(const QModelIndex& index) { - return (index.internalId()) & 0xFFFF; + return (index.internalId()) & 0xFFFF; } @@ -266,46 +266,46 @@ quint32 PortModel::portId(const QModelIndex& index) // ---------------------------------------------- void PortModel::when_portGroupDataChanged(int portGroupId, int portId) { - QModelIndex index; - int row; + QModelIndex index; + int row; - if (portId == 0xFFFF) - row = pgl->indexOfPortGroup(portGroupId); - else - row = portId; + if (portId == 0xFFFF) + row = pgl->indexOfPortGroup(portGroupId); + else + row = portId; - index = createIndex(row, 0, (portGroupId << 16) | portId); + index = createIndex(row, 0, (portGroupId << 16) | portId); - emit dataChanged(index, index); + emit dataChanged(index, index); } void PortModel::portGroupAboutToBeAppended() { - int row; + int row; - row = pgl->mPortGroups.size(); - beginInsertRows(QModelIndex(), row, row); + row = pgl->mPortGroups.size(); + beginInsertRows(QModelIndex(), row, row); } void PortModel::portGroupAppended() { - endInsertRows(); + endInsertRows(); } void PortModel::portGroupAboutToBeRemoved(PortGroup *portGroup) { - int row; + int row; - row = pgl->mPortGroups.indexOf(portGroup); - beginRemoveRows(QModelIndex(), row, row); + row = pgl->mPortGroups.indexOf(portGroup); + beginRemoveRows(QModelIndex(), row, row); } void PortModel::portGroupRemoved() { - endRemoveRows(); + endRemoveRows(); } void PortModel::when_portListChanged() { - reset(); + reset(); } diff --git a/client/portmodel.h b/client/portmodel.h index bd4b791..eea9763 100644 --- a/client/portmodel.h +++ b/client/portmodel.h @@ -8,42 +8,42 @@ class PortGroup; class PortModel : public QAbstractItemModel { - Q_OBJECT + Q_OBJECT - friend class PortGroupList; + friend class PortGroupList; - PortGroupList *pgl; + PortGroupList *pgl; - public: - PortModel(PortGroupList *p, QObject *parent = 0); + public: + PortModel(PortGroupList *p, QObject *parent = 0); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; - QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; + QModelIndex parent(const QModelIndex &index) const; - bool isPortGroup(const QModelIndex& index); - bool isPort(const QModelIndex& index); - quint32 portGroupId(const QModelIndex& index); - quint32 portId(const QModelIndex& index); + bool isPortGroup(const QModelIndex& index); + bool isPort(const QModelIndex& index); + quint32 portGroupId(const QModelIndex& index); + quint32 portId(const QModelIndex& index); private slots: - void when_portGroupDataChanged(int portGroupId, int portId); + void when_portGroupDataChanged(int portGroupId, int portId); - void portGroupAboutToBeAppended(); - void portGroupAppended(); - void portGroupAboutToBeRemoved(PortGroup *portGroup); - void portGroupRemoved(); + void portGroupAboutToBeAppended(); + void portGroupAppended(); + void portGroupAboutToBeRemoved(PortGroup *portGroup); + void portGroupRemoved(); - void when_portListChanged(); + void when_portListChanged(); #if 0 - void triggerLayoutAboutToBeChanged(); - void triggerLayoutChanged(); + void triggerLayoutAboutToBeChanged(); + void triggerLayoutChanged(); #endif }; diff --git a/client/portstatsfilterdialog.cpp b/client/portstatsfilterdialog.cpp index 6c97d85..b21bd37 100644 --- a/client/portstatsfilterdialog.cpp +++ b/client/portstatsfilterdialog.cpp @@ -2,110 +2,110 @@ PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent) { - setupUi(this); + setupUi(this); - mUnselected.setSortRole(PositionRole); + mUnselected.setSortRole(PositionRole); - lvUnselected->setModel(&mUnselected); - lvSelected->setModel(&mSelected); + lvUnselected->setModel(&mUnselected); + lvSelected->setModel(&mSelected); } QList PortStatsFilterDialog::getItemList(bool* ok, - QAbstractItemModel *model, Qt::Orientation orientation, - QList initial) + QAbstractItemModel *model, Qt::Orientation orientation, + QList initial) { - QList ret; + QList ret; - uint count = (orientation == Qt::Vertical) ? - model->rowCount() : model->columnCount(); + uint count = (orientation == Qt::Vertical) ? + model->rowCount() : model->columnCount(); - *ok = false; + *ok = false; - mUnselected.clear(); - mSelected.clear(); + mUnselected.clear(); + mSelected.clear(); - for (uint i = 0; i < count; i++) - { - QStandardItem *item; - - item = new QStandardItem(model->headerData(i, orientation).toString()); - item->setData(i, PositionRole); - item->setFlags(Qt::ItemIsSelectable - | Qt::ItemIsDragEnabled - //| Qt::ItemIsDropEnabled - | Qt::ItemIsEnabled); + for (uint i = 0; i < count; i++) + { + QStandardItem *item; + + item = new QStandardItem(model->headerData(i, orientation).toString()); + item->setData(i, PositionRole); + item->setFlags(Qt::ItemIsSelectable + | Qt::ItemIsDragEnabled + //| Qt::ItemIsDropEnabled + | Qt::ItemIsEnabled); - if (initial.contains(i)) - mSelected.appendRow(item); - else - mUnselected.appendRow(item); - } + if (initial.contains(i)) + mSelected.appendRow(item); + else + mUnselected.appendRow(item); + } - // No need to sort right now 'coz we have inserted items in order + // No need to sort right now 'coz we have inserted items in order - if (exec() == QDialog::Accepted) - { - uint count = mSelected.rowCount(); - for (uint i = 0; i < count; i++) - { - QModelIndex index = mSelected.index(i, 0, QModelIndex()); - QStandardItem *item = mSelected.itemFromIndex(index); - ret.append(item->data(PositionRole).toInt()); - } - *ok = true; - } + if (exec() == QDialog::Accepted) + { + uint count = mSelected.rowCount(); + for (uint i = 0; i < count; i++) + { + QModelIndex index = mSelected.index(i, 0, QModelIndex()); + QStandardItem *item = mSelected.itemFromIndex(index); + ret.append(item->data(PositionRole).toInt()); + } + *ok = true; + } - return ret; + return ret; } void PortStatsFilterDialog::on_tbSelectIn_clicked() { - QStandardItem *item; - while (lvUnselected->selectionModel()->selectedIndexes().size()) - { - item = mUnselected.takeItem(lvUnselected->selectionModel()-> - selectedIndexes().at(0).row()); - if (mUnselected.removeRow(lvUnselected->selectionModel()-> - selectedIndexes().at(0).row())) - mSelected.appendRow(item); - } + QStandardItem *item; + while (lvUnselected->selectionModel()->selectedIndexes().size()) + { + item = mUnselected.takeItem(lvUnselected->selectionModel()-> + selectedIndexes().at(0).row()); + if (mUnselected.removeRow(lvUnselected->selectionModel()-> + selectedIndexes().at(0).row())) + mSelected.appendRow(item); + } } void PortStatsFilterDialog::on_tbSelectOut_clicked() { - QStandardItem *item; + QStandardItem *item; - while (lvSelected->selectionModel()->selectedIndexes().size()) - { - item = mSelected.takeItem(lvSelected->selectionModel()-> - selectedIndexes().at(0).row()); - if (mSelected.removeRow(lvSelected->selectionModel()-> - selectedIndexes().at(0).row())) - { - mUnselected.appendRow(item); - mUnselected.sort(0); - } - } + while (lvSelected->selectionModel()->selectedIndexes().size()) + { + item = mSelected.takeItem(lvSelected->selectionModel()-> + selectedIndexes().at(0).row()); + if (mSelected.removeRow(lvSelected->selectionModel()-> + selectedIndexes().at(0).row())) + { + mUnselected.appendRow(item); + mUnselected.sort(0); + } + } } void PortStatsFilterDialog::on_lvUnselected_doubleClicked(const QModelIndex &index) { - QStandardItem *item; + QStandardItem *item; - item = mUnselected.takeItem(lvUnselected->currentIndex().row()); - if (mUnselected.removeRow(lvUnselected->currentIndex().row())) - mSelected.appendRow(item); + item = mUnselected.takeItem(lvUnselected->currentIndex().row()); + if (mUnselected.removeRow(lvUnselected->currentIndex().row())) + mSelected.appendRow(item); } void PortStatsFilterDialog::on_lvSelected_doubleClicked(const QModelIndex &index) { - QStandardItem *item; + QStandardItem *item; - item = mSelected.takeItem(lvSelected->currentIndex().row()); - if (mSelected.removeRow(lvSelected->currentIndex().row())) - { - mUnselected.appendRow(item); - mUnselected.sort(0); - } + item = mSelected.takeItem(lvSelected->currentIndex().row()); + if (mSelected.removeRow(lvSelected->currentIndex().row())) + { + mUnselected.appendRow(item); + mUnselected.sort(0); + } } diff --git a/client/portstatsfilterdialog.h b/client/portstatsfilterdialog.h index cabbf0c..ce8016c 100644 --- a/client/portstatsfilterdialog.h +++ b/client/portstatsfilterdialog.h @@ -9,26 +9,26 @@ class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog { - Q_OBJECT + Q_OBJECT public: - PortStatsFilterDialog(QWidget *parent = 0); - QList getItemList(bool* ok, QAbstractItemModel *model, - Qt::Orientation orientation = Qt::Vertical, - QList initial = QList()); + PortStatsFilterDialog(QWidget *parent = 0); + QList getItemList(bool* ok, QAbstractItemModel *model, + Qt::Orientation orientation = Qt::Vertical, + QList initial = QList()); private: - enum ItemRole { - PositionRole = Qt::UserRole + 1 - }; - QStandardItemModel mUnselected; - QStandardItemModel mSelected; + enum ItemRole { + PositionRole = Qt::UserRole + 1 + }; + QStandardItemModel mUnselected; + QStandardItemModel mSelected; private slots: - void on_tbSelectIn_clicked(); - void on_tbSelectOut_clicked(); - void on_lvUnselected_doubleClicked(const QModelIndex &index); - void on_lvSelected_doubleClicked(const QModelIndex &index); + void on_tbSelectIn_clicked(); + void on_tbSelectOut_clicked(); + void on_lvUnselected_doubleClicked(const QModelIndex &index); + void on_lvSelected_doubleClicked(const QModelIndex &index); }; #endif diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index ce75846..5aec2b6 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -4,241 +4,241 @@ #include PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent) - : QAbstractTableModel(parent) + : QAbstractTableModel(parent) { - QTimer *timer; + QTimer *timer; - pgl = p; + pgl = p; - timer = new QTimer(); - connect(timer, SIGNAL(timeout()), this, SLOT(updateStats())); - timer->start(1000); + timer = new QTimer(); + connect(timer, SIGNAL(timeout()), this, SLOT(updateStats())); + timer->start(1000); } int PortStatsModel::rowCount(const QModelIndex &parent) const { - if (parent.isValid()) - return 0; + if (parent.isValid()) + return 0; - if (numPorts.isEmpty()) - return 0; + if (numPorts.isEmpty()) + return 0; - if (numPorts.last() == 0) - return 0; + if (numPorts.last() == 0) + return 0; - return (int) e_STAT_MAX; + return (int) e_STAT_MAX; } int PortStatsModel::columnCount(const QModelIndex &parent ) const { - if (parent.isValid()) - return 0; - else - if (numPorts.isEmpty()) - return 0; - else - return numPorts.last(); + if (parent.isValid()) + return 0; + else + if (numPorts.isEmpty()) + return 0; + else + return numPorts.last(); } void PortStatsModel::getDomainIndexes(const QModelIndex &index, - uint &portGroupIdx, uint &portIdx) const + uint &portGroupIdx, uint &portIdx) const { - int portNum; + int portNum; - // TODO(LOW): Optimize using binary search: see qLowerBound() - portNum = index.column() + 1; - for (portGroupIdx = 0; portGroupIdx < (uint) numPorts.size(); portGroupIdx++) - if (portNum <= numPorts.at(portGroupIdx)) - break; + // TODO(LOW): Optimize using binary search: see qLowerBound() + portNum = index.column() + 1; + for (portGroupIdx = 0; portGroupIdx < (uint) numPorts.size(); portGroupIdx++) + if (portNum <= numPorts.at(portGroupIdx)) + break; - if (portGroupIdx) - { - if (numPorts.at(portGroupIdx -1)) - portIdx = (portNum - 1) % numPorts.at(portGroupIdx - 1); - else - portIdx = portNum - 1; - } - else - portIdx = portNum - 1; + if (portGroupIdx) + { + if (numPorts.at(portGroupIdx -1)) + portIdx = (portNum - 1) % numPorts.at(portGroupIdx - 1); + else + portIdx = portNum - 1; + } + else + portIdx = portNum - 1; - //qDebug("PSM: %d - %d, %d", index.column(), portGroupIdx, portIdx); + //qDebug("PSM: %d - %d, %d", index.column(), portGroupIdx, portIdx); } QVariant PortStatsModel::data(const QModelIndex &index, int role) const { - uint pgidx, pidx; - int row; + uint pgidx, pidx; + int row; - // Check for a valid index - if (!index.isValid()) - return QVariant(); + // Check for a valid index + if (!index.isValid()) + return QVariant(); - // Check for row/column limits - row = index.row(); - if (row >= e_STAT_MAX) - return QVariant(); + // Check for row/column limits + row = index.row(); + if (row >= e_STAT_MAX) + return QVariant(); - if (numPorts.isEmpty()) - return QVariant(); + if (numPorts.isEmpty()) + return QVariant(); - if (index.column() >= (numPorts.last())) - return QVariant(); + if (index.column() >= (numPorts.last())) + return QVariant(); - getDomainIndexes(index, pgidx, pidx); + getDomainIndexes(index, pgidx, pidx); - // Check role - if (role == Qt::DisplayRole) - { - OstProto::PortStats stats; + // Check role + if (role == Qt::DisplayRole) + { + OstProto::PortStats stats; - stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx]->getStats(); + stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx]->getStats(); - switch(row) - { - // States - case e_LINK_STATE: - return LinkStateName.at(stats.state().link_state()); + switch(row) + { + // States + case e_LINK_STATE: + return LinkStateName.at(stats.state().link_state()); - case e_TRANSMIT_STATE: - return BoolStateName.at(stats.state().is_transmit_on()); + case e_TRANSMIT_STATE: + return BoolStateName.at(stats.state().is_transmit_on()); - case e_CAPTURE_STATE: - return BoolStateName.at(stats.state().is_capture_on()); + case e_CAPTURE_STATE: + return BoolStateName.at(stats.state().is_capture_on()); - // Statistics - case e_STAT_FRAMES_RCVD: - return stats.rx_pkts(); + // Statistics + case e_STAT_FRAMES_RCVD: + return stats.rx_pkts(); - case e_STAT_FRAMES_SENT: - return stats.tx_pkts(); + case e_STAT_FRAMES_SENT: + return stats.tx_pkts(); - case e_STAT_FRAME_SEND_RATE: - return stats.tx_pps(); + case e_STAT_FRAME_SEND_RATE: + return stats.tx_pps(); - case e_STAT_FRAME_RECV_RATE: - return stats.rx_pps(); + case e_STAT_FRAME_RECV_RATE: + return stats.rx_pps(); - case e_STAT_BYTES_RCVD: - return stats.rx_bytes(); + case e_STAT_BYTES_RCVD: + return stats.rx_bytes(); - case e_STAT_BYTES_SENT: - return stats.tx_bytes(); + case e_STAT_BYTES_SENT: + return stats.tx_bytes(); - case e_STAT_BYTE_SEND_RATE: - return stats.tx_bps(); + case e_STAT_BYTE_SEND_RATE: + return stats.tx_bps(); - case e_STAT_BYTE_RECV_RATE: - return stats.rx_bps(); + case e_STAT_BYTE_RECV_RATE: + return stats.rx_bps(); #if 0 - case e_STAT_FRAMES_RCVD_NIC: - return stats.rx_pkts_nic(); + case e_STAT_FRAMES_RCVD_NIC: + return stats.rx_pkts_nic(); - case e_STAT_FRAMES_SENT_NIC: - return stats.tx_pkts_nic(); + case e_STAT_FRAMES_SENT_NIC: + return stats.tx_pkts_nic(); - case e_STAT_BYTES_RCVD_NIC: - return stats.rx_bytes_nic(); + case e_STAT_BYTES_RCVD_NIC: + return stats.rx_bytes_nic(); - case e_STAT_BYTES_SENT_NIC: - return stats.tx_bytes_nic(); + case e_STAT_BYTES_SENT_NIC: + return stats.tx_bytes_nic(); #endif - default: - qWarning("%s: Unhandled stats id %d\n", __FUNCTION__, - index.row()); - return 0; - } - } - else if (role == Qt::TextAlignmentRole) - { - if (row >= e_STATE_START && row <= e_STATE_END) - return Qt::AlignHCenter; - else if (row >= e_STATISTICS_START && row <= e_STATISTICS_END) - return Qt::AlignRight; - else - return QVariant(); - } - else - return QVariant(); + default: + qWarning("%s: Unhandled stats id %d\n", __FUNCTION__, + index.row()); + return 0; + } + } + else if (role == Qt::TextAlignmentRole) + { + if (row >= e_STATE_START && row <= e_STATE_END) + return Qt::AlignHCenter; + else if (row >= e_STATISTICS_START && row <= e_STATISTICS_END) + return Qt::AlignRight; + else + return QVariant(); + } + else + return QVariant(); } QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, int role) const { #ifdef Q_OS_WIN32 - // TODO(MED): The limitations should be the server's not the client's! - // Ideally we shd enhance the protocol to convey limitation(s), if any, - // from server to client - if (role == Qt::ToolTipRole) - { - if (orientation == Qt::Horizontal) - { - return QString("Limitation(s)" - "

Frames/Bytes Receieved: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
" - "Frames/Bytes Sent: Only Ostinato Tx pkts (Tx by others NOT included)

" - "

Rx/Tx Rates are derived from the above and hence subject to same limitations

" - ); - } - else - return QVariant(); - } + // TODO(MED): The limitations should be the server's not the client's! + // Ideally we shd enhance the protocol to convey limitation(s), if any, + // from server to client + if (role == Qt::ToolTipRole) + { + if (orientation == Qt::Horizontal) + { + return QString("Limitation(s)" + "

Frames/Bytes Receieved: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
" + "Frames/Bytes Sent: Only Ostinato Tx pkts (Tx by others NOT included)

" + "

Rx/Tx Rates are derived from the above and hence subject to same limitations

" + ); + } + else + return QVariant(); + } #endif - if (role != Qt::DisplayRole) - return QVariant(); + if (role != Qt::DisplayRole) + return QVariant(); - if (orientation == Qt::Horizontal) - { - uint portGroupIdx, portIdx; + if (orientation == Qt::Horizontal) + { + uint portGroupIdx, portIdx; - getDomainIndexes(index(0, section), portGroupIdx, portIdx); + getDomainIndexes(index(0, section), portGroupIdx, portIdx); #ifdef Q_OS_WIN32 - return QString("Port %1-%2 (*)").arg(portGroupIdx).arg(portIdx); + return QString("Port %1-%2 (*)").arg(portGroupIdx).arg(portIdx); #else - return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx); + return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx); #endif - } - else - return PortStatName.at(section); + } + else + return PortStatName.at(section); } void PortStatsModel::portListFromIndex(QModelIndexList indices, - QList &portList) + QList &portList) { - int i, j; - QModelIndexList selectedCols(indices); + int i, j; + QModelIndexList selectedCols(indices); - portList.clear(); + portList.clear(); - //selectedCols = indices.selectedColumns(); - for (i = 0; i < selectedCols.size(); i++) - { - uint portGroupIdx, portIdx; + //selectedCols = indices.selectedColumns(); + for (i = 0; i < selectedCols.size(); i++) + { + uint portGroupIdx, portIdx; - getDomainIndexes(selectedCols.at(i), portGroupIdx, portIdx); - for (j = 0; j < portList.size(); j++) - { - if (portList[j].portGroupId == portGroupIdx) - break; - } + getDomainIndexes(selectedCols.at(i), portGroupIdx, portIdx); + for (j = 0; j < portList.size(); j++) + { + if (portList[j].portGroupId == portGroupIdx) + break; + } - if (j >= portList.size()) - { - // PortGroup Not found - PortGroupAndPortList p; + if (j >= portList.size()) + { + // PortGroup Not found + PortGroupAndPortList p; - p.portGroupId = portGroupIdx; - p.portList.append(portIdx); + p.portGroupId = portGroupIdx; + p.portList.append(portIdx); - portList.append(p); - } - else - { - // PortGroup found + portList.append(p); + } + else + { + // PortGroup found - portList[j].portList.append(portIdx); - } - } + portList[j].portList.append(portIdx); + } + } } // @@ -246,43 +246,43 @@ void PortStatsModel::portListFromIndex(QModelIndexList indices, // void PortStatsModel::when_portListChanged() { - int i, count = 0; + int i, count = 0; - // recalc numPorts - while (numPorts.size()) - numPorts.removeFirst(); + // recalc numPorts + while (numPorts.size()) + numPorts.removeFirst(); - for (i = 0; i < pgl->mPortGroups.size(); i++) - { - count += pgl->mPortGroups.at(i)->numPorts(); - numPorts.append(count); - } + for (i = 0; i < pgl->mPortGroups.size(); i++) + { + count += pgl->mPortGroups.at(i)->numPorts(); + numPorts.append(count); + } - reset(); + reset(); } void PortStatsModel::on_portStatsUpdate(int port, void*stats) { - QModelIndex topLeft = index(port, 0, QModelIndex()); - QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex()); + QModelIndex topLeft = index(port, 0, QModelIndex()); + QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex()); - emit dataChanged(topLeft, bottomRight); + emit dataChanged(topLeft, bottomRight); } void PortStatsModel::updateStats() { - // Request each portgroup to fetch updated stats - the port group - // raises a signal once updated stats are available - for (int i = 0; i < pgl->mPortGroups.size(); i++) - pgl->mPortGroups[i]->getPortStats(); + // Request each portgroup to fetch updated stats - the port group + // raises a signal once updated stats are available + for (int i = 0; i < pgl->mPortGroups.size(); i++) + pgl->mPortGroups[i]->getPortStats(); } void PortStatsModel::when_portGroup_stats_update(quint32 portGroupId) { - // FIXME(MED): update only the changed ports, not all + // FIXME(MED): update only the changed ports, not all - QModelIndex topLeft = index(0, 0, QModelIndex()); - QModelIndex bottomRight = index(rowCount(), columnCount(), QModelIndex()); + QModelIndex topLeft = index(0, 0, QModelIndex()); + QModelIndex bottomRight = index(rowCount(), columnCount(), QModelIndex()); - emit dataChanged(topLeft, bottomRight); + emit dataChanged(topLeft, bottomRight); } diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h index 02f02dd..e253e22 100644 --- a/client/portstatsmodel.h +++ b/client/portstatsmodel.h @@ -5,112 +5,112 @@ #include typedef enum { - // State - e_STATE_START = 0, + // State + e_STATE_START = 0, - e_LINK_STATE = e_STATE_START, - e_TRANSMIT_STATE, - e_CAPTURE_STATE, + e_LINK_STATE = e_STATE_START, + e_TRANSMIT_STATE, + e_CAPTURE_STATE, - e_STATE_END = e_CAPTURE_STATE, + e_STATE_END = e_CAPTURE_STATE, - // Statistics - e_STATISTICS_START, + // Statistics + e_STATISTICS_START, - e_STAT_FRAMES_RCVD = e_STATISTICS_START, - e_STAT_FRAMES_SENT, - e_STAT_FRAME_SEND_RATE, - e_STAT_FRAME_RECV_RATE, - e_STAT_BYTES_RCVD, - e_STAT_BYTES_SENT, - e_STAT_BYTE_SEND_RATE, - e_STAT_BYTE_RECV_RATE, + e_STAT_FRAMES_RCVD = e_STATISTICS_START, + e_STAT_FRAMES_SENT, + e_STAT_FRAME_SEND_RATE, + e_STAT_FRAME_RECV_RATE, + e_STAT_BYTES_RCVD, + e_STAT_BYTES_SENT, + e_STAT_BYTE_SEND_RATE, + e_STAT_BYTE_RECV_RATE, #if 0 - e_STAT_FRAMES_RCVD_NIC, - e_STAT_FRAMES_SENT_NIC, - e_STAT_BYTES_RCVD_NIC, - e_STAT_BYTES_SENT_NIC, + e_STAT_FRAMES_RCVD_NIC, + e_STAT_FRAMES_SENT_NIC, + e_STAT_BYTES_RCVD_NIC, + e_STAT_BYTES_SENT_NIC, #endif - e_STATISTICS_END = e_STAT_BYTE_RECV_RATE, + e_STATISTICS_END = e_STAT_BYTE_RECV_RATE, - e_STAT_MAX + e_STAT_MAX } PortStat; static QStringList PortStatName = (QStringList() - << "Link State" - << "Transmit State" - << "Capture State" + << "Link State" + << "Transmit State" + << "Capture State" - << "Frames Received" - << "Frames Sent" - << "Frame Send Rate (fps)" - << "Frame Receive Rate (fps)" - << "Bytes Received" - << "Bytes Sent" - << "Byte Send Rate (Bps)" - << "Byte Receive Rate (Bps)" + << "Frames Received" + << "Frames Sent" + << "Frame Send Rate (fps)" + << "Frame Receive Rate (fps)" + << "Bytes Received" + << "Bytes Sent" + << "Byte Send Rate (Bps)" + << "Byte Receive Rate (Bps)" #if 0 - << "Frames Received (NIC)" - << "Frames Sent (NIC)" - << "Bytes Received (NIC)" - << "Bytes Sent (NIC)" + << "Frames Received (NIC)" + << "Frames Sent (NIC)" + << "Bytes Received (NIC)" + << "Bytes Sent (NIC)" #endif ); static QStringList LinkStateName = (QStringList() - << "Unknown" - << "Down" - << "Up" + << "Unknown" + << "Down" + << "Up" ); static QStringList BoolStateName = (QStringList() - << "Off" - << "On" + << "Off" + << "On" ); class PortGroupList; class PortStatsModel : public QAbstractTableModel { - Q_OBJECT + Q_OBJECT - public: + public: - PortStatsModel(PortGroupList *p, QObject *parent = 0); + PortStatsModel(PortGroupList *p, QObject *parent = 0); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; - class PortGroupAndPortList { - public: - uint portGroupId; - QList portList; - }; - void portListFromIndex(QModelIndexList indices, - QList &portList); + class PortGroupAndPortList { + public: + uint portGroupId; + QList portList; + }; + void portListFromIndex(QModelIndexList indices, + QList &portList); - public slots: - void when_portListChanged(); - void on_portStatsUpdate(int port, void*stats); - void when_portGroup_stats_update(quint32 portGroupId); + public slots: + void when_portListChanged(); + void on_portStatsUpdate(int port, void*stats); + void when_portGroup_stats_update(quint32 portGroupId); - private slots: - void updateStats(); + private slots: + void updateStats(); - private: - PortGroupList *pgl; + private: + PortGroupList *pgl; - // numPorts stores the num of ports per portgroup - // in the same order as the portgroups are index in the pgl - // Also it stores them as cumulative totals - QList numPorts; + // numPorts stores the num of ports per portgroup + // in the same order as the portgroups are index in the pgl + // Also it stores them as cumulative totals + QList numPorts; - void getDomainIndexes(const QModelIndex &index, - uint &portGroupIdx, uint &portIdx) const; + void getDomainIndexes(const QModelIndex &index, + uint &portGroupIdx, uint &portIdx) const; }; diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index 26e2b10..c10834d 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -6,17 +6,17 @@ #include "QHeaderView" PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); - this->pgl = pgl; - model = pgl->getPortStatsModel(); - tvPortStats->setModel(model); + this->pgl = pgl; + model = pgl->getPortStatsModel(); + tvPortStats->setModel(model); - tvPortStats->verticalHeader()->setHighlightSections(false); - tvPortStats->verticalHeader()->setDefaultSectionSize( - tvPortStats->verticalHeader()->minimumSectionSize()); + tvPortStats->verticalHeader()->setHighlightSections(false); + tvPortStats->verticalHeader()->setDefaultSectionSize( + tvPortStats->verticalHeader()->minimumSectionSize()); } @@ -28,134 +28,134 @@ PortStatsWindow::~PortStatsWindow() void PortStatsWindow::on_tbStartTransmit_clicked() { - QList pgpl; + QList pgpl; - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - startTx(&pgpl[i].portList); - } + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + startTx(&pgpl[i].portList); + } } void PortStatsWindow::on_tbStopTransmit_clicked() { - QList pgpl; + QList pgpl; - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - stopTx(&pgpl[i].portList); - } + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + stopTx(&pgpl[i].portList); + } } void PortStatsWindow::on_tbStartCapture_clicked() { - // TODO(MED) - QList pgpl; + // TODO(MED) + QList pgpl; - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - startCapture(&pgpl[i].portList); - } + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + startCapture(&pgpl[i].portList); + } } void PortStatsWindow::on_tbStopCapture_clicked() { - // TODO(MED) - QList pgpl; + // TODO(MED) + QList pgpl; - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - stopCapture(&pgpl[i].portList); - } + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + stopCapture(&pgpl[i].portList); + } } void PortStatsWindow::on_tbViewCapture_clicked() { - // TODO(MED) - QList pgpl; + // TODO(MED) + QList pgpl; - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - viewCapture(&pgpl[i].portList); - } + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + viewCapture(&pgpl[i].portList); + } } void PortStatsWindow::on_tbClear_clicked() { - QList portList; + QList portList; - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - portList); + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + portList); - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < portList.size(); i++) - { - pgl->portGroupByIndex(portList.at(i).portGroupId). - clearPortStats(&portList[i].portList); - } + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < portList.size(); i++) + { + pgl->portGroupByIndex(portList.at(i).portGroupId). + clearPortStats(&portList[i].portList); + } } void PortStatsWindow::on_tbClearAll_clicked() { - for (int i = 0; i < pgl->numPortGroups(); i++) - { - pgl->portGroupByIndex(0).clearPortStats(); - } + for (int i = 0; i < pgl->numPortGroups(); i++) + { + pgl->portGroupByIndex(0).clearPortStats(); + } } void PortStatsWindow::on_tbFilter_clicked() { - bool ok; - QList currentColumns, newColumns; - PortStatsFilterDialog dialog; + bool ok; + QList currentColumns, newColumns; + PortStatsFilterDialog dialog; - for(int i = 0; i < model->columnCount(); i++) - if (!tvPortStats->isColumnHidden(i)) - currentColumns.append(i); + for(int i = 0; i < model->columnCount(); i++) + if (!tvPortStats->isColumnHidden(i)) + currentColumns.append(i); - newColumns = dialog.getItemList(&ok, model, Qt::Horizontal, currentColumns); + newColumns = dialog.getItemList(&ok, model, Qt::Horizontal, currentColumns); - if (ok) - { - // hide/show sections first ... - for(int i = 0; i < model->columnCount(); i++) - tvPortStats->setColumnHidden(i, !newColumns.contains(i)); + if (ok) + { + // hide/show sections first ... + for(int i = 0; i < model->columnCount(); i++) + tvPortStats->setColumnHidden(i, !newColumns.contains(i)); - // ... then for the 'shown' columns, set the visual index - for(int i = 0; i < newColumns.size(); i++) - { - tvPortStats->horizontalHeader()->moveSection(tvPortStats-> - horizontalHeader()->visualIndex(newColumns.at(i)), i); - } - } + // ... then for the 'shown' columns, set the visual index + for(int i = 0; i < newColumns.size(); i++) + { + tvPortStats->horizontalHeader()->moveSection(tvPortStats-> + horizontalHeader()->visualIndex(newColumns.at(i)), i); + } + } } diff --git a/client/portstatswindow.h b/client/portstatswindow.h index c1d581f..a390446 100644 --- a/client/portstatswindow.h +++ b/client/portstatswindow.h @@ -9,28 +9,28 @@ class PortStatsWindow : public QWidget, public Ui::PortStatsWindow { - Q_OBJECT + Q_OBJECT public: - PortStatsWindow(PortGroupList *pgl, QWidget *parent = 0); - ~PortStatsWindow(); + PortStatsWindow(PortGroupList *pgl, QWidget *parent = 0); + ~PortStatsWindow(); private: - PortGroupList *pgl; - PortStatsModel *model; + PortGroupList *pgl; + PortStatsModel *model; private slots: - void on_tbStartTransmit_clicked(); - void on_tbStopTransmit_clicked(); + void on_tbStartTransmit_clicked(); + void on_tbStopTransmit_clicked(); - void on_tbStartCapture_clicked(); - void on_tbStopCapture_clicked(); - void on_tbViewCapture_clicked(); + void on_tbStartCapture_clicked(); + void on_tbStopCapture_clicked(); + void on_tbViewCapture_clicked(); - void on_tbClear_clicked(); - void on_tbClearAll_clicked(); + void on_tbClear_clicked(); + void on_tbClearAll_clicked(); - void on_tbFilter_clicked(); + void on_tbFilter_clicked(); }; #endif diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 54d4b8b..23684db 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -6,67 +6,67 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) { - StreamListDelegate *delegate = new StreamListDelegate; - //slm = new StreamListModel(); - //plm = new PortGroupList(); - plm = pgl; + StreamListDelegate *delegate = new StreamListDelegate; + //slm = new StreamListModel(); + //plm = new PortGroupList(); + plm = pgl; - setupUi(this); + setupUi(this); - tvStreamList->setItemDelegate(delegate); + tvStreamList->setItemDelegate(delegate); - tvStreamList->verticalHeader()->setDefaultSectionSize( - tvStreamList->verticalHeader()->minimumSectionSize()); + tvStreamList->verticalHeader()->setDefaultSectionSize( + tvStreamList->verticalHeader()->minimumSectionSize()); - // Populate Context Menu Actions - tvPortList->addAction(actionNew_Port_Group); - tvPortList->addAction(actionDelete_Port_Group); - tvPortList->addAction(actionConnect_Port_Group); - tvPortList->addAction(actionDisconnect_Port_Group); + // Populate Context Menu Actions + tvPortList->addAction(actionNew_Port_Group); + tvPortList->addAction(actionDelete_Port_Group); + tvPortList->addAction(actionConnect_Port_Group); + tvPortList->addAction(actionDisconnect_Port_Group); - tvStreamList->addAction(actionNew_Stream); - tvStreamList->addAction(actionEdit_Stream); - tvStreamList->addAction(actionDelete_Stream); + tvStreamList->addAction(actionNew_Stream); + tvStreamList->addAction(actionEdit_Stream); + tvStreamList->addAction(actionDelete_Stream); - tvStreamList->setModel(plm->getStreamModel()); - tvPortList->setModel(plm->getPortModel()); - - connect( plm->getPortModel(), - SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(when_portModel_dataChanged(const QModelIndex&, - const QModelIndex&))); + tvStreamList->setModel(plm->getStreamModel()); + tvPortList->setModel(plm->getPortModel()); + + connect( plm->getPortModel(), + SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_portModel_dataChanged(const QModelIndex&, + const QModelIndex&))); - connect(plm->getPortModel(), SIGNAL(modelReset()), - SLOT(when_portModel_reset())); + connect(plm->getPortModel(), SIGNAL(modelReset()), + SLOT(when_portModel_reset())); - connect( tvPortList->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(when_portView_currentChanged(const QModelIndex&, - const QModelIndex&))); + connect( tvPortList->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_portView_currentChanged(const QModelIndex&, + const QModelIndex&))); - connect( tvStreamList->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(when_streamView_currentChanged(const QModelIndex&, - const QModelIndex&))); - connect( tvStreamList->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, SLOT(when_streamView_selectionChanged())); + connect( tvStreamList->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_streamView_currentChanged(const QModelIndex&, + const QModelIndex&))); + connect( tvStreamList->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, SLOT(when_streamView_selectionChanged())); #if 0 - connect( tvPortList->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&))); + connect( tvPortList->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&))); #endif - tvStreamList->resizeColumnToContents(StreamModel::StreamIcon); - tvStreamList->resizeColumnToContents(StreamModel::StreamStatus); + tvStreamList->resizeColumnToContents(StreamModel::StreamIcon); + tvStreamList->resizeColumnToContents(StreamModel::StreamStatus); - // Initially we don't have any ports/streams - so send signal triggers - when_portView_currentChanged(QModelIndex(), QModelIndex()); - when_streamView_currentChanged(QModelIndex(), QModelIndex()); + // Initially we don't have any ports/streams - so send signal triggers + when_portView_currentChanged(QModelIndex(), QModelIndex()); + when_streamView_currentChanged(QModelIndex(), QModelIndex()); - //! \todo Hide the Aggregate Box till we add support - frAggregate->setHidden(true); + //! \todo Hide the Aggregate Box till we add support + frAggregate->setHidden(true); } PortsWindow::~PortsWindow() @@ -75,342 +75,342 @@ PortsWindow::~PortsWindow() void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) { - StreamConfigDialog *scd; + StreamConfigDialog *scd; - if (!index.isValid()) - { - qDebug("%s: invalid index", __FUNCTION__); - return; - } - scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()), - index.row(), this); - qDebug("stream list activated\n"); - scd->exec(); // TODO: chk retval - delete scd; + if (!index.isValid()) + { + qDebug("%s: invalid index", __FUNCTION__); + return; + } + scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()), + index.row(), this); + qDebug("stream list activated\n"); + scd->exec(); // TODO: chk retval + delete scd; } void PortsWindow::when_portView_currentChanged(const QModelIndex& current, - const QModelIndex& previous) + const QModelIndex& previous) { - plm->getStreamModel()->setCurrentPortIndex(current); - updatePortViewActions(current); - updateStreamViewActions(); + plm->getStreamModel()->setCurrentPortIndex(current); + updatePortViewActions(current); + updateStreamViewActions(); - if (!current.isValid()) - { - qDebug("setting stacked widget to blank page"); - swDetail->setCurrentIndex(2); // blank page - } - else - { - if (plm->isPortGroup(current)) - { - swDetail->setCurrentIndex(1); // portGroup detail page - } - else if (plm->isPort(current)) - { - swDetail->setCurrentIndex(0); // port detail page - } - } + if (!current.isValid()) + { + qDebug("setting stacked widget to blank page"); + swDetail->setCurrentIndex(2); // blank page + } + else + { + if (plm->isPortGroup(current)) + { + swDetail->setCurrentIndex(1); // portGroup detail page + } + else if (plm->isPort(current)) + { + swDetail->setCurrentIndex(0); // port detail page + } + } } void PortsWindow::when_streamView_currentChanged(const QModelIndex& current, - const QModelIndex& previous) + const QModelIndex& previous) { - qDebug("stream view current changed"); - updateStreamViewActions(); + qDebug("stream view current changed"); + updateStreamViewActions(); } void PortsWindow::when_streamView_selectionChanged() { - qDebug("stream view selection changed"); - updateStreamViewActions(); + qDebug("stream view selection changed"); + updateStreamViewActions(); } void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft, - const QModelIndex& bottomRight) + const QModelIndex& bottomRight) { #if 0 // not sure why the >= <= operators are not overloaded in QModelIndex - if ((tvPortList->currentIndex() >= topLeft) && - (tvPortList->currentIndex() <= bottomRight)) + if ((tvPortList->currentIndex() >= topLeft) && + (tvPortList->currentIndex() <= bottomRight)) #endif - if ((topLeft < tvPortList->currentIndex()) || - (topLeft == tvPortList->currentIndex()) && - ((tvPortList->currentIndex() < bottomRight)) || - (tvPortList->currentIndex() == bottomRight)) - { - updatePortViewActions(tvPortList->currentIndex()); - } + if ((topLeft < tvPortList->currentIndex()) || + (topLeft == tvPortList->currentIndex()) && + ((tvPortList->currentIndex() < bottomRight)) || + (tvPortList->currentIndex() == bottomRight)) + { + updatePortViewActions(tvPortList->currentIndex()); + } } void PortsWindow::when_portModel_reset() { - when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex()); + when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex()); } #if 0 void PortsWindow::updateStreamViewActions(const QModelIndex& current) { - if (current.isValid()) - actionDelete_Stream->setEnabled(true); - else - actionDelete_Stream->setDisabled(true); + if (current.isValid()) + actionDelete_Stream->setEnabled(true); + else + actionDelete_Stream->setDisabled(true); } #endif void PortsWindow::updateStreamViewActions() { - // For some reason hasSelection() returns true even if selection size is 0 - // so additional check for size introduced - if (tvStreamList->selectionModel()->hasSelection() && - (tvStreamList->selectionModel()->selection().size() > 0)) - { - qDebug("Has selection %d", - tvStreamList->selectionModel()->selection().size()); + // For some reason hasSelection() returns true even if selection size is 0 + // so additional check for size introduced + if (tvStreamList->selectionModel()->hasSelection() && + (tvStreamList->selectionModel()->selection().size() > 0)) + { + qDebug("Has selection %d", + tvStreamList->selectionModel()->selection().size()); - // If more than one non-contiguous ranges selected, - // disable "New" and "Edit" - if (tvStreamList->selectionModel()->selection().size() > 1) - { - actionNew_Stream->setDisabled(true); - actionEdit_Stream->setDisabled(true); - } - else - { - actionNew_Stream->setEnabled(true); + // If more than one non-contiguous ranges selected, + // disable "New" and "Edit" + if (tvStreamList->selectionModel()->selection().size() > 1) + { + actionNew_Stream->setDisabled(true); + actionEdit_Stream->setDisabled(true); + } + else + { + actionNew_Stream->setEnabled(true); - // Enable "Edit" only if the single range has a single row - if (tvStreamList->selectionModel()->selection().at(0).height() > 1) - actionEdit_Stream->setDisabled(true); - else - actionEdit_Stream->setEnabled(true); - } + // Enable "Edit" only if the single range has a single row + if (tvStreamList->selectionModel()->selection().at(0).height() > 1) + actionEdit_Stream->setDisabled(true); + else + actionEdit_Stream->setEnabled(true); + } - // Delete is always enabled as long as we have a selection - actionDelete_Stream->setEnabled(true); - } - else - { - qDebug("No selection"); - actionNew_Stream->setEnabled(true); - actionEdit_Stream->setDisabled(true); - actionDelete_Stream->setDisabled(true); - } + // Delete is always enabled as long as we have a selection + actionDelete_Stream->setEnabled(true); + } + else + { + qDebug("No selection"); + actionNew_Stream->setEnabled(true); + actionEdit_Stream->setDisabled(true); + actionDelete_Stream->setDisabled(true); + } } void PortsWindow::updatePortViewActions(const QModelIndex& current) { - if (!current.isValid()) - { - qDebug("current is now invalid"); - actionDelete_Port_Group->setDisabled(true); - actionConnect_Port_Group->setDisabled(true); - actionDisconnect_Port_Group->setDisabled(true); - - goto _EXIT; - } + if (!current.isValid()) + { + qDebug("current is now invalid"); + actionDelete_Port_Group->setDisabled(true); + actionConnect_Port_Group->setDisabled(true); + actionDisconnect_Port_Group->setDisabled(true); + + goto _EXIT; + } - qDebug("currentChanged %llx", current.internalId()); + qDebug("currentChanged %llx", current.internalId()); - if (plm->isPortGroup(current)) - { - actionDelete_Port_Group->setEnabled(true); - switch(plm->portGroup(current).state()) - { - case QAbstractSocket::UnconnectedState: - case QAbstractSocket::ClosingState: - qDebug("state = unconnected|closing"); - actionConnect_Port_Group->setEnabled(true); - actionDisconnect_Port_Group->setDisabled(true); - break; + if (plm->isPortGroup(current)) + { + actionDelete_Port_Group->setEnabled(true); + switch(plm->portGroup(current).state()) + { + case QAbstractSocket::UnconnectedState: + case QAbstractSocket::ClosingState: + qDebug("state = unconnected|closing"); + actionConnect_Port_Group->setEnabled(true); + actionDisconnect_Port_Group->setDisabled(true); + break; - case QAbstractSocket::HostLookupState: - case QAbstractSocket::ConnectingState: - case QAbstractSocket::ConnectedState: - qDebug("state = lookup|connecting|connected"); - actionConnect_Port_Group->setDisabled(true); - actionDisconnect_Port_Group->setEnabled(true); - break; + case QAbstractSocket::HostLookupState: + case QAbstractSocket::ConnectingState: + case QAbstractSocket::ConnectedState: + qDebug("state = lookup|connecting|connected"); + actionConnect_Port_Group->setDisabled(true); + actionDisconnect_Port_Group->setEnabled(true); + break; - case QAbstractSocket::BoundState: - case QAbstractSocket::ListeningState: - default: - // FIXME(LOW): indicate error - qDebug("unexpected state"); - break; - } - } - else if (plm->isPort(current)) - { - actionDelete_Port_Group->setEnabled(false); - actionConnect_Port_Group->setEnabled(false); - actionDisconnect_Port_Group->setEnabled(false); - } + case QAbstractSocket::BoundState: + case QAbstractSocket::ListeningState: + default: + // FIXME(LOW): indicate error + qDebug("unexpected state"); + break; + } + } + else if (plm->isPort(current)) + { + actionDelete_Port_Group->setEnabled(false); + actionConnect_Port_Group->setEnabled(false); + actionDisconnect_Port_Group->setEnabled(false); + } _EXIT: - return; + return; } void PortsWindow::on_pbApply_clicked() { - QModelIndex curPort; - QModelIndex curPortGroup; + QModelIndex curPort; + QModelIndex curPortGroup; - curPort = tvPortList->selectionModel()->currentIndex(); - if (!curPort.isValid()) - { - qDebug("%s: curPort is invalid", __FUNCTION__); - goto _exit; - } + curPort = tvPortList->selectionModel()->currentIndex(); + if (!curPort.isValid()) + { + qDebug("%s: curPort is invalid", __FUNCTION__); + goto _exit; + } - if (!plm->isPort(curPort)) - { - qDebug("%s: curPort is not a port", __FUNCTION__); - goto _exit; - } + if (!plm->isPort(curPort)) + { + qDebug("%s: curPort is not a port", __FUNCTION__); + goto _exit; + } - curPortGroup = plm->getPortModel()->parent(curPort); - if (!curPortGroup.isValid()) - { - qDebug("%s: curPortGroup is invalid", __FUNCTION__); - goto _exit; - } - if (!plm->isPortGroup(curPortGroup)) - { - qDebug("%s: curPortGroup is not a portGroup", __FUNCTION__); - goto _exit; - } + curPortGroup = plm->getPortModel()->parent(curPort); + if (!curPortGroup.isValid()) + { + qDebug("%s: curPortGroup is invalid", __FUNCTION__); + goto _exit; + } + if (!plm->isPortGroup(curPortGroup)) + { + qDebug("%s: curPortGroup is not a portGroup", __FUNCTION__); + goto _exit; + } - // FIXME(HI): shd this be a signal? - //portGroup.when_configApply(port); - // FIXME(MED): mixing port id and index!!! - plm->portGroup(curPortGroup).when_configApply(plm->port(curPort).id()); + // FIXME(HI): shd this be a signal? + //portGroup.when_configApply(port); + // FIXME(MED): mixing port id and index!!! + plm->portGroup(curPortGroup).when_configApply(plm->port(curPort).id()); _exit: - return; + return; #if 0 - // TODO (LOW): This block is for testing only - QModelIndex current = tvPortList->selectionModel()->currentIndex(); + // TODO (LOW): This block is for testing only + QModelIndex current = tvPortList->selectionModel()->currentIndex(); - if (current.isValid()) - qDebug("current = %llx", current.internalId()); - else - qDebug("current is invalid"); + if (current.isValid()) + qDebug("current = %llx", current.internalId()); + else + qDebug("current is invalid"); #endif } void PortsWindow::on_actionNew_Port_Group_triggered() { - bool ok; - QString text = QInputDialog::getText(this, - "Add Port Group", "Port Group Address (IP[:Port])", - QLineEdit::Normal, lastNewPortGroup, &ok); - - if (ok) - { - QStringList addr = text.split(":"); - if (addr.size() == 1) // Port unspecified - addr.append(QString().setNum(DEFAULT_SERVER_PORT)); - PortGroup *pg = new PortGroup(QHostAddress(addr[0]),addr[1].toUShort()); - plm->addPortGroup(*pg); - lastNewPortGroup = text; - } + bool ok; + QString text = QInputDialog::getText(this, + "Add Port Group", "Port Group Address (IP[:Port])", + QLineEdit::Normal, lastNewPortGroup, &ok); + + if (ok) + { + QStringList addr = text.split(":"); + if (addr.size() == 1) // Port unspecified + addr.append(QString().setNum(DEFAULT_SERVER_PORT)); + PortGroup *pg = new PortGroup(QHostAddress(addr[0]),addr[1].toUShort()); + plm->addPortGroup(*pg); + lastNewPortGroup = text; + } } void PortsWindow::on_actionDelete_Port_Group_triggered() { - QModelIndex current = tvPortList->selectionModel()->currentIndex(); + QModelIndex current = tvPortList->selectionModel()->currentIndex(); - if (current.isValid()) - plm->removePortGroup(plm->portGroup(current)); + if (current.isValid()) + plm->removePortGroup(plm->portGroup(current)); } void PortsWindow::on_actionConnect_Port_Group_triggered() { - QModelIndex current = tvPortList->selectionModel()->currentIndex(); + QModelIndex current = tvPortList->selectionModel()->currentIndex(); - if (current.isValid()) - plm->portGroup(current).connectToHost(); + if (current.isValid()) + plm->portGroup(current).connectToHost(); } void PortsWindow::on_actionDisconnect_Port_Group_triggered() { - QModelIndex current = tvPortList->selectionModel()->currentIndex(); + QModelIndex current = tvPortList->selectionModel()->currentIndex(); - if (current.isValid()) - plm->portGroup(current).disconnectFromHost(); + if (current.isValid()) + plm->portGroup(current).disconnectFromHost(); } #if 0 void PortsWindow::on_actionNew_Stream_triggered() { - qDebug("New Stream Action"); + qDebug("New Stream Action"); - int row = 0; + int row = 0; - if (tvStreamList->currentIndex().isValid()) - row = tvStreamList->currentIndex().row(); - plm->getStreamModel()->insertRows(row, 1); + if (tvStreamList->currentIndex().isValid()) + row = tvStreamList->currentIndex().row(); + plm->getStreamModel()->insertRows(row, 1); } void PortsWindow::on_actionDelete_Stream_triggered() { - qDebug("Delete Stream Action"); - if (tvStreamList->currentIndex().isValid()) - plm->getStreamModel()->removeRows(tvStreamList->currentIndex().row(), 1); + qDebug("Delete Stream Action"); + if (tvStreamList->currentIndex().isValid()) + plm->getStreamModel()->removeRows(tvStreamList->currentIndex().row(), 1); } #endif void PortsWindow::on_actionNew_Stream_triggered() { - qDebug("New Stream Action"); + qDebug("New Stream Action"); - // In case nothing is selected, insert 1 row at the top - int row = 0, count = 1; + // In case nothing is selected, insert 1 row at the top + int row = 0, count = 1; - // In case we have a single range selected; insert as many rows as - // in the singe selected range before the top of the selected range - if (tvStreamList->selectionModel()->selection().size() == 1) - { - row = tvStreamList->selectionModel()->selection().at(0).top(); - count = tvStreamList->selectionModel()->selection().at(0).height(); - } + // In case we have a single range selected; insert as many rows as + // in the singe selected range before the top of the selected range + if (tvStreamList->selectionModel()->selection().size() == 1) + { + row = tvStreamList->selectionModel()->selection().at(0).top(); + count = tvStreamList->selectionModel()->selection().at(0).height(); + } - plm->getStreamModel()->insertRows(row, count); + plm->getStreamModel()->insertRows(row, count); } void PortsWindow::on_actionEdit_Stream_triggered() { - qDebug("Edit Stream Action"); + qDebug("Edit Stream Action"); - // Ensure we have only one range selected which contains only one row - if ((tvStreamList->selectionModel()->selection().size() == 1) && - (tvStreamList->selectionModel()->selection().at(0).height() == 1)) - { - on_tvStreamList_activated(tvStreamList->selectionModel()-> - selection().at(0).topLeft()); - } + // Ensure we have only one range selected which contains only one row + if ((tvStreamList->selectionModel()->selection().size() == 1) && + (tvStreamList->selectionModel()->selection().at(0).height() == 1)) + { + on_tvStreamList_activated(tvStreamList->selectionModel()-> + selection().at(0).topLeft()); + } } void PortsWindow::on_actionDelete_Stream_triggered() { - qDebug("Delete Stream Action"); + qDebug("Delete Stream Action"); - QModelIndex index; + QModelIndex index; - if (tvStreamList->selectionModel()->hasSelection()) - { - qDebug("SelectedIndexes %d", - tvStreamList->selectionModel()->selectedRows().size()); - while(tvStreamList->selectionModel()->selectedRows().size()) - { - index = tvStreamList->selectionModel()->selectedRows().at(0); - plm->getStreamModel()->removeRows(index.row(), 1); - } - } - else - qDebug("No selection"); + if (tvStreamList->selectionModel()->hasSelection()) + { + qDebug("SelectedIndexes %d", + tvStreamList->selectionModel()->selectedRows().size()); + while(tvStreamList->selectionModel()->selectedRows().size()) + { + index = tvStreamList->selectionModel()->selectedRows().at(0); + plm->getStreamModel()->removeRows(index.row(), 1); + } + } + else + qDebug("No selection"); } diff --git a/client/portswindow.h b/client/portswindow.h index b291f91..aec7216 100644 --- a/client/portswindow.h +++ b/client/portswindow.h @@ -15,43 +15,43 @@ LOW class PortsWindow : public QWidget, private Ui::PortsWindow { - Q_OBJECT + Q_OBJECT - //QAbstractItemModel *slm; // stream list model - PortGroupList *plm; + //QAbstractItemModel *slm; // stream list model + PortGroupList *plm; public: - PortsWindow(PortGroupList *pgl, QWidget *parent = 0); - ~PortsWindow(); + PortsWindow(PortGroupList *pgl, QWidget *parent = 0); + ~PortsWindow(); private: - QString lastNewPortGroup; + QString lastNewPortGroup; - void updatePortViewActions(const QModelIndex& current); - //void updateStreamViewActions(const QModelIndex& current); - void updateStreamViewActions(); + void updatePortViewActions(const QModelIndex& current); + //void updateStreamViewActions(const QModelIndex& current); + void updateStreamViewActions(); private slots: - void on_tvStreamList_activated(const QModelIndex & index); - void when_portView_currentChanged(const QModelIndex& current, - const QModelIndex& previous); - void when_streamView_currentChanged(const QModelIndex& current, - const QModelIndex& previous); - void when_streamView_selectionChanged(); - void when_portModel_dataChanged(const QModelIndex& topLeft, - const QModelIndex& bottomRight); - void when_portModel_reset(); + void on_tvStreamList_activated(const QModelIndex & index); + void when_portView_currentChanged(const QModelIndex& current, + const QModelIndex& previous); + void when_streamView_currentChanged(const QModelIndex& current, + const QModelIndex& previous); + void when_streamView_selectionChanged(); + void when_portModel_dataChanged(const QModelIndex& topLeft, + const QModelIndex& bottomRight); + void when_portModel_reset(); - void on_pbApply_clicked(); + void on_pbApply_clicked(); - void on_actionNew_Port_Group_triggered(); - void on_actionDelete_Port_Group_triggered(); - void on_actionConnect_Port_Group_triggered(); - void on_actionDisconnect_Port_Group_triggered(); + void on_actionNew_Port_Group_triggered(); + void on_actionDelete_Port_Group_triggered(); + void on_actionConnect_Port_Group_triggered(); + void on_actionDisconnect_Port_Group_triggered(); - void on_actionNew_Stream_triggered(); - void on_actionEdit_Stream_triggered(); - void on_actionDelete_Stream_triggered(); + void on_actionNew_Stream_triggered(); + void on_actionEdit_Stream_triggered(); + void on_actionDelete_Stream_triggered(); }; #endif diff --git a/client/stream.cpp b/client/stream.cpp index d2791e3..049d554 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -8,8 +8,8 @@ Stream::Stream() { - //mId = 0xFFFFFFFF; - setEnabled(true); + //mId = 0xFFFFFFFF; + setEnabled(true); } Stream::~Stream() @@ -19,42 +19,42 @@ Stream::~Stream() void Stream::loadProtocolWidgets() { #if 0 - //protocols.loadConfigWidgets(); - foreach(AbstractProtocol* proto, *currentFrameProtocols) - { - proto->loadConfigWidget(); - } + //protocols.loadConfigWidgets(); + foreach(AbstractProtocol* proto, *currentFrameProtocols) + { + proto->loadConfigWidget(); + } #else - ProtocolListIterator *iter; + ProtocolListIterator *iter; - iter = createProtocolListIterator(); - while (iter->hasNext()) - { - AbstractProtocol* p = iter->next(); - p->loadConfigWidget(); - } - delete iter; + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol* p = iter->next(); + p->loadConfigWidget(); + } + delete iter; #endif } void Stream::storeProtocolWidgets() { #if 0 - //protocols.storeConfigWidgets(); - foreach(const AbstractProtocol* proto, frameProtocol()) - { - proto->storeConfigWidget(); - _iter->toFront(); - } + //protocols.storeConfigWidgets(); + foreach(const AbstractProtocol* proto, frameProtocol()) + { + proto->storeConfigWidget(); + _iter->toFront(); + } #else - ProtocolListIterator *iter; + ProtocolListIterator *iter; - iter = createProtocolListIterator(); - while (iter->hasNext()) - { - AbstractProtocol* p = iter->next(); - p->storeConfigWidget(); - } - delete iter; + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol* p = iter->next(); + p->storeConfigWidget(); + } + delete iter; #endif } diff --git a/client/stream.h b/client/stream.h index 1539af3..1b4e756 100644 --- a/client/stream.h +++ b/client/stream.h @@ -10,14 +10,14 @@ class Stream : public StreamBase { - //quint32 mId; + //quint32 mId; public: - Stream(); - ~Stream(); + Stream(); + ~Stream(); - void loadProtocolWidgets(); - void storeProtocolWidgets(); + void loadProtocolWidgets(); + void storeProtocolWidgets(); }; #endif diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 5201099..c6a950d 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -14,538 +14,538 @@ extern ProtocolManager OstProtocolManager; int StreamConfigDialog::lastTopLevelTabIndex = 0; StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, - QWidget *parent) : QDialog (parent), mPort(port) + QWidget *parent) : QDialog (parent), mPort(port) { - OstProto::Stream s; - mCurrentStreamIndex = streamIndex; - mpStream = new Stream; - mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyInto(s); - mpStream->protoDataCopyFrom(s); - _iter = mpStream->createProtocolListIterator(); - isUpdateInProgress = false; + OstProto::Stream s; + mCurrentStreamIndex = streamIndex; + mpStream = new Stream; + mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyInto(s); + mpStream->protoDataCopyFrom(s); + _iter = mpStream->createProtocolListIterator(); + isUpdateInProgress = false; - setupUi(this); - setupUiExtra(); + setupUi(this); + setupUiExtra(); - for (int i = ProtoMin; i < ProtoMax; i++) - { - bgProto[i]->setProperty("ProtocolLevel", i); - bgProto[i]->setProperty("ProtocolId", ButtonIdNone); - connect(bgProto[i], SIGNAL(buttonClicked(int)), - this, SLOT(updateProtocol(int))); - } + for (int i = ProtoMin; i < ProtoMax; i++) + { + bgProto[i]->setProperty("ProtocolLevel", i); + bgProto[i]->setProperty("ProtocolId", ButtonIdNone); + connect(bgProto[i], SIGNAL(buttonClicked(int)), + this, SLOT(updateProtocol(int))); + } - //! \todo causes a crash! -#if 0 - connect(lePktLen, SIGNAL(textEdited(QString)), - this, SLOT(updateContents())); + //! \todo causes a crash! +#if 0 + connect(lePktLen, SIGNAL(textEdited(QString)), + this, SLOT(updateContents())); #endif - // Time to play match the signals and slots! + // Time to play match the signals and slots! - // If L1/L2(FT)/L3 = None, force subsequent protocol level(s) also to None - connect(rbL1None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); - connect(rbL3None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); + // If L1/L2(FT)/L3 = None, force subsequent protocol level(s) also to None + connect(rbL1None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); + connect(rbL3None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); - // If L1/L2(FT)/L3/L4 = Other, force subsequent protocol to Other and - // disable the subsequent protocol group as well - connect(rbL1Other, SIGNAL(toggled(bool)), rbFtOther, SLOT(setChecked(bool))); - connect(rbL1Other, SIGNAL(toggled(bool)), gbFrameType, SLOT(setDisabled(bool))); - connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool))); - connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool))); - connect(rbL3Other, SIGNAL(toggled(bool)), rbL4Other, SLOT(setChecked(bool))); - connect(rbL3Other, SIGNAL(toggled(bool)), gbL4Proto, SLOT(setDisabled(bool))); - connect(rbL4Other, SIGNAL(toggled(bool)), rbPayloadOther, SLOT(setChecked(bool))); - connect(rbL4Other, SIGNAL(toggled(bool)), gbPayloadProto, SLOT(setDisabled(bool))); + // If L1/L2(FT)/L3/L4 = Other, force subsequent protocol to Other and + // disable the subsequent protocol group as well + connect(rbL1Other, SIGNAL(toggled(bool)), rbFtOther, SLOT(setChecked(bool))); + connect(rbL1Other, SIGNAL(toggled(bool)), gbFrameType, SLOT(setDisabled(bool))); + connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool))); + connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool))); + connect(rbL3Other, SIGNAL(toggled(bool)), rbL4Other, SLOT(setChecked(bool))); + connect(rbL3Other, SIGNAL(toggled(bool)), gbL4Proto, SLOT(setDisabled(bool))); + connect(rbL4Other, SIGNAL(toggled(bool)), rbPayloadOther, SLOT(setChecked(bool))); + connect(rbL4Other, SIGNAL(toggled(bool)), gbPayloadProto, SLOT(setDisabled(bool))); - // Setup valid subsequent protocols for L2 and L3 protocols - for (int i = ProtoL2; i <= ProtoL3; i++) - { - foreach(QAbstractButton *btn1, bgProto[i]->buttons()) - { - int id1 = bgProto[i]->id(btn1); + // Setup valid subsequent protocols for L2 and L3 protocols + for (int i = ProtoL2; i <= ProtoL3; i++) + { + foreach(QAbstractButton *btn1, bgProto[i]->buttons()) + { + int id1 = bgProto[i]->id(btn1); - if (id1 != ButtonIdNone && id1 != ButtonIdOther) - { - int validProtocolCount = 0; + if (id1 != ButtonIdNone && id1 != ButtonIdOther) + { + int validProtocolCount = 0; - foreach(QAbstractButton *btn2, bgProto[i+1]->buttons()) - { - int id2 = bgProto[i+1]->id(btn2); + foreach(QAbstractButton *btn2, bgProto[i+1]->buttons()) + { + int id2 = bgProto[i+1]->id(btn2); - if (id2 != ButtonIdNone && id2 != ButtonIdOther) - { - if (OstProtocolManager.isValidNeighbour(id1, id2)) - { - connect(btn1, SIGNAL(toggled(bool)), - btn2, SLOT(setEnabled(bool))); - validProtocolCount++; - } - else - connect(btn1, SIGNAL(toggled(bool)), - btn2, SLOT(setDisabled(bool))); - } - } + if (id2 != ButtonIdNone && id2 != ButtonIdOther) + { + if (OstProtocolManager.isValidNeighbour(id1, id2)) + { + connect(btn1, SIGNAL(toggled(bool)), + btn2, SLOT(setEnabled(bool))); + validProtocolCount++; + } + else + connect(btn1, SIGNAL(toggled(bool)), + btn2, SLOT(setDisabled(bool))); + } + } - // If btn1 has no subsequent valid protocols, - // force subsequent Protocol to 'None' - if (validProtocolCount == 0) - connect(btn1, SIGNAL(clicked(bool)), - bgProto[i+1]->button(ButtonIdNone), SLOT(click())); - } - } - } + // If btn1 has no subsequent valid protocols, + // force subsequent Protocol to 'None' + if (validProtocolCount == 0) + connect(btn1, SIGNAL(clicked(bool)), + bgProto[i+1]->button(ButtonIdNone), SLOT(click())); + } + } + } - mpAvailableProtocolsModel = new QStringListModel( - OstProtocolManager.protocolDatabase(), this); - lvAllProtocols->setModel(mpAvailableProtocolsModel); - mpSelectedProtocolsModel = new QStringListModel(this); - lvSelectedProtocols->setModel(mpSelectedProtocolsModel); + mpAvailableProtocolsModel = new QStringListModel( + OstProtocolManager.protocolDatabase(), this); + lvAllProtocols->setModel(mpAvailableProtocolsModel); + mpSelectedProtocolsModel = new QStringListModel(this); + lvSelectedProtocols->setModel(mpSelectedProtocolsModel); - connect(lvAllProtocols->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, SLOT(when_lvAllProtocols_selectionChanged( - const QItemSelection&, const QItemSelection&))); - connect(lvSelectedProtocols->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(when_lvSelectedProtocols_currentChanged(const QModelIndex&, - const QModelIndex&))); + connect(lvAllProtocols->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, SLOT(when_lvAllProtocols_selectionChanged( + const QItemSelection&, const QItemSelection&))); + connect(lvSelectedProtocols->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_lvSelectedProtocols_currentChanged(const QModelIndex&, + const QModelIndex&))); - LoadCurrentStream(); - mpPacketModel = new PacketModel(this); - tvPacketTree->setModel(mpPacketModel); - mpPacketModelTester = new ModelTest(mpPacketModel); - tvPacketTree->header()->hide(); - vwPacketDump->setModel(mpPacketModel); - vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); + LoadCurrentStream(); + mpPacketModel = new PacketModel(this); + tvPacketTree->setModel(mpPacketModel); + mpPacketModelTester = new ModelTest(mpPacketModel); + tvPacketTree->header()->hide(); + vwPacketDump->setModel(mpPacketModel); + vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); - // TODO(MED): + // TODO(MED): - //! \todo Implement then enable these protocols - ARP, IPv6, ICMP, IGMP - rbL3Arp->setHidden(true); - rbL3Ipv6->setHidden(true); - rbL4Icmp->setHidden(true); - rbL4Igmp->setHidden(true); - //! \todo Enable navigation of streams - pbPrev->setDisabled(true); - pbNext->setDisabled(true); - //! \todo Support Goto Stream Id - leStreamId->setDisabled(true); - disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool))); - //! \todo Support Continuous Mode - rbModeContinuous->setDisabled(true); + //! \todo Implement then enable these protocols - ARP, IPv6, ICMP, IGMP + rbL3Arp->setHidden(true); + rbL3Ipv6->setHidden(true); + rbL4Icmp->setHidden(true); + rbL4Igmp->setHidden(true); + //! \todo Enable navigation of streams + pbPrev->setDisabled(true); + pbNext->setDisabled(true); + //! \todo Support Goto Stream Id + leStreamId->setDisabled(true); + disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool))); + //! \todo Support Continuous Mode + rbModeContinuous->setDisabled(true); - // Finally, restore the saved last selected tab for the various tab widgets - twTopLevel->setCurrentIndex(lastTopLevelTabIndex); + // Finally, restore the saved last selected tab for the various tab widgets + twTopLevel->setCurrentIndex(lastTopLevelTabIndex); } void StreamConfigDialog::setupUiExtra() { - QRegExp reHex2B("[0-9,a-f,A-F]{1,4}"); - QRegExp reHex4B("[0-9,a-f,A-F]{1,8}"); - QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); + QRegExp reHex2B("[0-9,a-f,A-F]{1,4}"); + QRegExp reHex4B("[0-9,a-f,A-F]{1,8}"); + QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); - // ---- Setup default stuff that cannot be done in designer ---- - bgProto[ProtoL1] = new QButtonGroup(); - bgProto[ProtoL1]->addButton(rbL1None, ButtonIdNone); - bgProto[ProtoL1]->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber); - bgProto[ProtoL1]->addButton(rbL1Other, ButtonIdOther); + // ---- Setup default stuff that cannot be done in designer ---- + bgProto[ProtoL1] = new QButtonGroup(); + bgProto[ProtoL1]->addButton(rbL1None, ButtonIdNone); + bgProto[ProtoL1]->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber); + bgProto[ProtoL1]->addButton(rbL1Other, ButtonIdOther); - bgProto[ProtoL2] = new QButtonGroup(); + bgProto[ProtoL2] = new QButtonGroup(); #if 0 - foreach(QRadioButton *btn, gbFrameType->findChildren()) - bgL2Proto->addButton(btn); + foreach(QRadioButton *btn, gbFrameType->findChildren()) + bgL2Proto->addButton(btn); #else - bgProto[ProtoL2]->addButton(rbFtNone, ButtonIdNone); - bgProto[ProtoL2]->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); - bgProto[ProtoL2]->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); - bgProto[ProtoL2]->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); - bgProto[ProtoL2]->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); - bgProto[ProtoL2]->addButton(rbFtOther, ButtonIdOther); + bgProto[ProtoL2]->addButton(rbFtNone, ButtonIdNone); + bgProto[ProtoL2]->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); + bgProto[ProtoL2]->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); + bgProto[ProtoL2]->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); + bgProto[ProtoL2]->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); + bgProto[ProtoL2]->addButton(rbFtOther, ButtonIdOther); #endif - bgProto[ProtoVlan] = new QButtonGroup(); - bgProto[ProtoVlan]->addButton(rbVlanNone, ButtonIdNone); - bgProto[ProtoVlan]->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); - bgProto[ProtoVlan]->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); + bgProto[ProtoVlan] = new QButtonGroup(); + bgProto[ProtoVlan]->addButton(rbVlanNone, ButtonIdNone); + bgProto[ProtoVlan]->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); + bgProto[ProtoVlan]->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); - bgProto[ProtoL3] = new QButtonGroup(); + bgProto[ProtoL3] = new QButtonGroup(); #if 0 - foreach(QRadioButton *btn, gbL3Proto->findChildren()) - bgProto[ProtoL3]->addButton(btn); + foreach(QRadioButton *btn, gbL3Proto->findChildren()) + bgProto[ProtoL3]->addButton(btn); #else - bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone); - bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); - bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF); - bgProto[ProtoL3]->addButton(rbL3Arp, 0xFFFF); - bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther); + bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone); + bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); + bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Arp, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther); #endif - bgProto[ProtoL4] = new QButtonGroup(); + bgProto[ProtoL4] = new QButtonGroup(); #if 0 - foreach(QRadioButton *btn, gbL4Proto->findChildren()) - bgProto[ProtoL4]->addButton(btn); + foreach(QRadioButton *btn, gbL4Proto->findChildren()) + bgProto[ProtoL4]->addButton(btn); #else - bgProto[ProtoL4]->addButton(rbL4None, 0); - bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); - bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); - bgProto[ProtoL4]->addButton(rbL4Icmp, 0xFFFF); - bgProto[ProtoL4]->addButton(rbL4Igmp, 0xFFFF); - bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther); + bgProto[ProtoL4]->addButton(rbL4None, 0); + bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); + bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); + bgProto[ProtoL4]->addButton(rbL4Icmp, 0xFFFF); + bgProto[ProtoL4]->addButton(rbL4Igmp, 0xFFFF); + bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther); #endif - bgProto[ProtoPayload] = new QButtonGroup(); + bgProto[ProtoPayload] = new QButtonGroup(); #if 0 - foreach(QRadioButton *btn, gbPayloadProto->findChildren()) - bgProto[ProtoPayload]->addButton(btn); + foreach(QRadioButton *btn, gbPayloadProto->findChildren()) + bgProto[ProtoPayload]->addButton(btn); #else - bgProto[ProtoPayload]->addButton(rbPayloadNone, ButtonIdNone); - bgProto[ProtoPayload]->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); - bgProto[ProtoPayload]->addButton(rbPayloadOther, ButtonIdOther); + bgProto[ProtoPayload]->addButton(rbPayloadNone, ButtonIdNone); + bgProto[ProtoPayload]->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); + bgProto[ProtoPayload]->addButton(rbPayloadOther, ButtonIdOther); #endif - /* - ** Setup Validators - */ - // Meta Data - //! \todo - doesn't seem to work - range validator needs a spinbox? - //lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); + /* + ** Setup Validators + */ + // Meta Data + //! \todo - doesn't seem to work - range validator needs a spinbox? + //lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); - /* - ** Setup Connections - */ - connect(rbSendPackets, SIGNAL(toggled(bool)), - this, SLOT(update_NumPacketsAndNumBursts())); - connect(rbSendBursts, SIGNAL(toggled(bool)), - this, SLOT(update_NumPacketsAndNumBursts())); - connect(rbModeFixed, SIGNAL(toggled(bool)), - this, SLOT(update_NumPacketsAndNumBursts())); - connect(rbModeContinuous, SIGNAL(toggled(bool)), - this, SLOT(update_NumPacketsAndNumBursts())); + /* + ** Setup Connections + */ + connect(rbSendPackets, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + connect(rbSendBursts, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + connect(rbModeFixed, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + connect(rbModeContinuous, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); } StreamConfigDialog::~StreamConfigDialog() { - delete mpPacketModelTester; - delete mpPacketModel; + delete mpPacketModelTester; + delete mpPacketModel; - for (int i = ProtoMin; i < ProtoMax; i++) - delete bgProto[i]; + for (int i = ProtoMin; i < ProtoMax; i++) + delete bgProto[i]; - delete _iter; - delete mpStream; + delete _iter; + delete mpStream; } void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode) { - if (mode == "Fixed") - { - lePktLen->setEnabled(true); - lePktLenMin->setDisabled(true); - lePktLenMax->setDisabled(true); - } - else if (mode == "Increment") - { - lePktLen->setDisabled(true); - lePktLenMin->setEnabled(true); - lePktLenMax->setEnabled(true); - } - else if (mode == "Decrement") - { - lePktLen->setDisabled(true); - lePktLenMin->setEnabled(true); - lePktLenMax->setEnabled(true); - } - else if (mode == "Random") - { - lePktLen->setDisabled(true); - lePktLenMin->setEnabled(true); - lePktLenMax->setEnabled(true); - } - else - { - qWarning("Unhandled/Unknown PktLenMode = %s", mode.toAscii().data()); - } + if (mode == "Fixed") + { + lePktLen->setEnabled(true); + lePktLenMin->setDisabled(true); + lePktLenMax->setDisabled(true); + } + else if (mode == "Increment") + { + lePktLen->setDisabled(true); + lePktLenMin->setEnabled(true); + lePktLenMax->setEnabled(true); + } + else if (mode == "Decrement") + { + lePktLen->setDisabled(true); + lePktLenMin->setEnabled(true); + lePktLenMax->setEnabled(true); + } + else if (mode == "Random") + { + lePktLen->setDisabled(true); + lePktLenMin->setEnabled(true); + lePktLenMax->setEnabled(true); + } + else + { + qWarning("Unhandled/Unknown PktLenMode = %s", mode.toAscii().data()); + } } void StreamConfigDialog::on_pbPrev_clicked() { #if 0 - StoreCurrentStream(currStreamIdx); - currStreamIdx--; - LoadCurrentStream(currStreamIdx); + StoreCurrentStream(currStreamIdx); + currStreamIdx--; + LoadCurrentStream(currStreamIdx); - pbPrev->setDisabled((currStreamIdx == 0)); - pbNext->setDisabled((currStreamIdx == 2)); + pbPrev->setDisabled((currStreamIdx == 0)); + pbNext->setDisabled((currStreamIdx == 2)); #endif } void StreamConfigDialog::on_pbNext_clicked() { #if 0 - StoreCurrentStream(currStreamIdx); - currStreamIdx++; - LoadCurrentStream(currStreamIdx); + StoreCurrentStream(currStreamIdx); + currStreamIdx++; + LoadCurrentStream(currStreamIdx); - pbPrev->setDisabled((currStreamIdx == 0)); - pbNext->setDisabled((currStreamIdx == 2)); + pbPrev->setDisabled((currStreamIdx == 0)); + pbNext->setDisabled((currStreamIdx == 2)); #endif } void StreamConfigDialog::on_tbSelectProtocols_currentChanged(int index) { - qDebug("%s, index = %d", __FUNCTION__, index); - switch (index) - { - case 0: - updateSelectProtocolsSimpleWidget(); - break; - case 1: - updateSelectProtocolsAdvancedWidget(); - break; - default: - qFatal("%s: unexpected index = %d", __FUNCTION__, index); - } + qDebug("%s, index = %d", __FUNCTION__, index); + switch (index) + { + case 0: + updateSelectProtocolsSimpleWidget(); + break; + case 1: + updateSelectProtocolsAdvancedWidget(); + break; + default: + qFatal("%s: unexpected index = %d", __FUNCTION__, index); + } } void StreamConfigDialog::when_lvAllProtocols_selectionChanged( - const QItemSelection &selected, const QItemSelection &deselected) + const QItemSelection &selected, const QItemSelection &deselected) { - int size = lvAllProtocols->selectionModel()->selectedIndexes().size(); + int size = lvAllProtocols->selectionModel()->selectedIndexes().size(); - qDebug("%s: selected.indexes().size = %d\n", __FUNCTION__, size); + qDebug("%s: selected.indexes().size = %d\n", __FUNCTION__, size); - tbAdd->setEnabled(size > 0); + tbAdd->setEnabled(size > 0); } void StreamConfigDialog::when_lvSelectedProtocols_currentChanged( - const QModelIndex ¤t, const QModelIndex &previous) + const QModelIndex ¤t, const QModelIndex &previous) { - qDebug("%s: currentRow = %d\n", __FUNCTION__, current.row()); + qDebug("%s: currentRow = %d\n", __FUNCTION__, current.row()); - tbDelete->setEnabled(current.isValid()); - tbUp->setEnabled(current.isValid() && (current.row() != 0)); - tbDown->setEnabled(current.isValid() && - (current.row() != (current.model()->rowCount() - 1))); + tbDelete->setEnabled(current.isValid()); + tbUp->setEnabled(current.isValid() && (current.row() != 0)); + tbDown->setEnabled(current.isValid() && + (current.row() != (current.model()->rowCount() - 1))); } void StreamConfigDialog::on_tbAdd_clicked() { - int n = 0; - QModelIndex idx2; - AbstractProtocol *p; - QModelIndexList selection; + int n = 0; + QModelIndex idx2; + AbstractProtocol *p; + QModelIndexList selection; - selection = lvAllProtocols->selectionModel()->selectedIndexes(); + selection = lvAllProtocols->selectionModel()->selectedIndexes(); - // Validation - if (selection.size() == 0) - return; + // Validation + if (selection.size() == 0) + return; - idx2 = lvSelectedProtocols->currentIndex(); - if (idx2.isValid()) - n = idx2.row(); + idx2 = lvSelectedProtocols->currentIndex(); + if (idx2.isValid()) + n = idx2.row(); - _iter->toFront(); - while (n--) - { - if (!_iter->hasNext()) - return; + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; - p = _iter->next(); - } + p = _iter->next(); + } - foreach(QModelIndex idx, selection) - _iter->insert(OstProtocolManager.createProtocol( - mpAvailableProtocolsModel->stringList().at(idx.row()), mpStream)); + foreach(QModelIndex idx, selection) + _iter->insert(OstProtocolManager.createProtocol( + mpAvailableProtocolsModel->stringList().at(idx.row()), mpStream)); - updateSelectProtocolsAdvancedWidget(); - lvSelectedProtocols->setCurrentIndex(idx2); + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx2); } void StreamConfigDialog::on_tbDelete_clicked() { - int n; - QModelIndex idx; - AbstractProtocol *p; + int n; + QModelIndex idx; + AbstractProtocol *p; - idx = lvSelectedProtocols->currentIndex(); + idx = lvSelectedProtocols->currentIndex(); - // Validation - if (!idx.isValid()) - return; + // Validation + if (!idx.isValid()) + return; - n = idx.row() + 1; + n = idx.row() + 1; - _iter->toFront(); - while (n--) - { - if (!_iter->hasNext()) - return; + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; - p = _iter->next(); - } + p = _iter->next(); + } - _iter->remove(); - delete p; + _iter->remove(); + delete p; - updateSelectProtocolsAdvancedWidget(); - lvSelectedProtocols->setCurrentIndex(idx); + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx); } void StreamConfigDialog::on_tbUp_clicked() { - int m, n; - QModelIndex idx; - AbstractProtocol *p; + int m, n; + QModelIndex idx; + AbstractProtocol *p; - idx = lvSelectedProtocols->currentIndex(); + idx = lvSelectedProtocols->currentIndex(); - // Validation - if (!idx.isValid() || idx.row() == 0) - return; + // Validation + if (!idx.isValid() || idx.row() == 0) + return; - m = n = idx.row() + 1; + m = n = idx.row() + 1; - _iter->toFront(); - while (n--) - { - if (!_iter->hasNext()) - return; + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; - p = _iter->next(); - } + p = _iter->next(); + } - _iter->remove(); - _iter->previous(); - _iter->insert(p); + _iter->remove(); + _iter->previous(); + _iter->insert(p); - updateSelectProtocolsAdvancedWidget(); - lvSelectedProtocols->setCurrentIndex(idx.sibling(m-2, 0)); + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx.sibling(m-2, 0)); } void StreamConfigDialog::on_tbDown_clicked() { - int m, n; - QModelIndex idx; - AbstractProtocol *p; + int m, n; + QModelIndex idx; + AbstractProtocol *p; - idx = lvSelectedProtocols->currentIndex(); + idx = lvSelectedProtocols->currentIndex(); - // Validation - if (!idx.isValid() || idx.row() == idx.model()->rowCount()) - return; + // Validation + if (!idx.isValid() || idx.row() == idx.model()->rowCount()) + return; - m = n = idx.row() + 1; + m = n = idx.row() + 1; - _iter->toFront(); - while (n--) - { - if (!_iter->hasNext()) - return; + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; - p = _iter->next(); - } + p = _iter->next(); + } - _iter->remove(); - _iter->next(); - _iter->insert(p); + _iter->remove(); + _iter->next(); + _iter->insert(p); - updateSelectProtocolsAdvancedWidget(); - lvSelectedProtocols->setCurrentIndex(idx.sibling(m,0)); + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx.sibling(m,0)); } void StreamConfigDialog::updateSelectProtocolsAdvancedWidget() { - QStringList selProtoList; + QStringList selProtoList; - qDebug("%s", __FUNCTION__); + qDebug("%s", __FUNCTION__); - _iter->toFront(); - while(_iter->hasNext()) - { - AbstractProtocol* p = _iter->next(); - qDebug("%p -- %d", p, p->protocolNumber()); - selProtoList.append(p->shortName()); - } - mpSelectedProtocolsModel->setStringList(selProtoList); + _iter->toFront(); + while(_iter->hasNext()) + { + AbstractProtocol* p = _iter->next(); + qDebug("%p -- %d", p, p->protocolNumber()); + selProtoList.append(p->shortName()); + } + mpSelectedProtocolsModel->setStringList(selProtoList); } void StreamConfigDialog::on_twTopLevel_currentChanged(int index) { - switch (index) - { - // Protocol Data - case 1: - { - QWidget *selWidget; + switch (index) + { + // Protocol Data + case 1: + { + QWidget *selWidget; - // Hide the ToolBox before modifying it - else we have a crash !!! - tbProtocolData->hide(); + // Hide the ToolBox before modifying it - else we have a crash !!! + tbProtocolData->hide(); - selWidget = tbProtocolData->currentWidget(); + selWidget = tbProtocolData->currentWidget(); - // Remove all existing protocol widgets - while (tbProtocolData->count() > 0) - { - QWidget* w = tbProtocolData->widget(0); - tbProtocolData->removeItem(0); - w->setParent(0); - } + // Remove all existing protocol widgets + while (tbProtocolData->count() > 0) + { + QWidget* w = tbProtocolData->widget(0); + tbProtocolData->removeItem(0); + w->setParent(0); + } - // Repopulate the widgets - _iter->toFront(); - while (_iter->hasNext()) - { - AbstractProtocol* p = _iter->next(); - tbProtocolData->addItem(p->configWidget(), p->name()); - } + // Repopulate the widgets + _iter->toFront(); + while (_iter->hasNext()) + { + AbstractProtocol* p = _iter->next(); + tbProtocolData->addItem(p->configWidget(), p->name()); + } - tbProtocolData->setCurrentWidget(selWidget); + tbProtocolData->setCurrentWidget(selWidget); - tbProtocolData->show(); - break; - } + tbProtocolData->show(); + break; + } - // Packet View - case 3: - { - StoreCurrentStream(); - mpPacketModel->setSelectedProtocols(*_iter); - break; - } + // Packet View + case 3: + { + StoreCurrentStream(); + mpPacketModel->setSelectedProtocols(*_iter); + break; + } - default: - break; - } + default: + break; + } } void StreamConfigDialog::update_NumPacketsAndNumBursts() { - if (rbSendPackets->isChecked() && rbModeFixed->isChecked()) - leNumPackets->setEnabled(true); - else - leNumPackets->setEnabled(false); + if (rbSendPackets->isChecked() && rbModeFixed->isChecked()) + leNumPackets->setEnabled(true); + else + leNumPackets->setEnabled(false); - if (rbSendBursts->isChecked() && rbModeFixed->isChecked()) - leNumBursts->setEnabled(true); - else - leNumBursts->setEnabled(false); + if (rbSendBursts->isChecked() && rbModeFixed->isChecked()) + leNumBursts->setEnabled(true); + else + leNumBursts->setEnabled(false); } #if 0 void StreamConfigDialog::on_lePattern_editingFinished() { - ulong num = 0; - bool isOk; - QString str; + ulong num = 0; + bool isOk; + QString str; - num = lePattern->text().remove(QChar(' ')).toULong(&isOk, 16); - qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); - lePattern->setText(uintToHexStr(num, str, 4)); - qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); + num = lePattern->text().remove(QChar(' ')).toULong(&isOk, 16); + qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); + lePattern->setText(uintToHexStr(num, str, 4)); + qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); } #endif @@ -554,23 +554,23 @@ Skip protocols upto and including the layer specified. */ bool StreamConfigDialog::skipProtocols(int layer) { - _iter->toFront(); + _iter->toFront(); - for (int i = ProtoMin; i <= layer; i++) - { - if(_iter->hasNext()) - { - int id; - QAbstractButton *btn; + for (int i = ProtoMin; i <= layer; i++) + { + if(_iter->hasNext()) + { + int id; + QAbstractButton *btn; - id = _iter->peekNext()->protocolNumber(); - btn = bgProto[i]->button(id); - if (btn) - _iter->next(); - } - } + id = _iter->peekNext()->protocolNumber(); + btn = bgProto[i]->button(id); + if (btn) + _iter->next(); + } + } - return true; + return true; } /*! @@ -578,348 +578,348 @@ Protocol choices (except "None" and "Other") for a protocol button group are dis */ void StreamConfigDialog::disableProtocols(QButtonGroup *protocolGroup, bool checked) { - qDebug("%s: btnGrp = %p, chk? = %d", __FUNCTION__, protocolGroup, checked); - foreach(QAbstractButton *btn, protocolGroup->buttons()) - { - int id = protocolGroup->id(btn); + qDebug("%s: btnGrp = %p, chk? = %d", __FUNCTION__, protocolGroup, checked); + foreach(QAbstractButton *btn, protocolGroup->buttons()) + { + int id = protocolGroup->id(btn); - if ((id != ButtonIdNone) && (id != ButtonIdOther)) - btn->setDisabled(checked); - } + if ((id != ButtonIdNone) && (id != ButtonIdOther)) + btn->setDisabled(checked); + } } void StreamConfigDialog::forceProtocolNone(bool checked) { - QObject *btn; + QObject *btn; - btn = sender(); - Q_ASSERT(btn != NULL); + btn = sender(); + Q_ASSERT(btn != NULL); - qDebug("%s: chk? = %d, btn = %p, L1 = %p, L2 = %p, L3 = %p", __FUNCTION__, - checked, btn, rbL1None, rbFtNone, rbL3None); + qDebug("%s: chk? = %d, btn = %p, L1 = %p, L2 = %p, L3 = %p", __FUNCTION__, + checked, btn, rbL1None, rbFtNone, rbL3None); - if (btn == rbL1None) - { - if (checked) - { - bgProto[ProtoVlan]->button(ButtonIdNone)->click(); - bgProto[ProtoL2]->button(ButtonIdNone)->click(); - bgProto[ProtoPayload]->button(ButtonIdNone)->click(); - } + if (btn == rbL1None) + { + if (checked) + { + bgProto[ProtoVlan]->button(ButtonIdNone)->click(); + bgProto[ProtoL2]->button(ButtonIdNone)->click(); + bgProto[ProtoPayload]->button(ButtonIdNone)->click(); + } - disableProtocols(bgProto[ProtoVlan], checked); - disableProtocols(bgProto[ProtoL2], checked); - disableProtocols(bgProto[ProtoPayload], checked); - } - else if (btn == rbFtNone) - { - if (checked) - bgProto[ProtoL3]->button(ButtonIdNone)->click(); - disableProtocols(bgProto[ProtoL3], checked); - } - else if (btn == rbL3None) - { - if (checked) - bgProto[ProtoL4]->button(ButtonIdNone)->click(); - disableProtocols(bgProto[ProtoL4], checked); - } - else - { - Q_ASSERT(1 == 0); // Unreachable code! - } + disableProtocols(bgProto[ProtoVlan], checked); + disableProtocols(bgProto[ProtoL2], checked); + disableProtocols(bgProto[ProtoPayload], checked); + } + else if (btn == rbFtNone) + { + if (checked) + bgProto[ProtoL3]->button(ButtonIdNone)->click(); + disableProtocols(bgProto[ProtoL3], checked); + } + else if (btn == rbL3None) + { + if (checked) + bgProto[ProtoL4]->button(ButtonIdNone)->click(); + disableProtocols(bgProto[ProtoL4], checked); + } + else + { + Q_ASSERT(1 == 0); // Unreachable code! + } } void StreamConfigDialog::updateProtocol(int newId) { - int level; - QButtonGroup *btnGrp; + int level; + QButtonGroup *btnGrp; - btnGrp = static_cast(sender()); - Q_ASSERT(btnGrp != NULL); + btnGrp = static_cast(sender()); + Q_ASSERT(btnGrp != NULL); - level = btnGrp->property("ProtocolLevel").toInt(); - Q_ASSERT(btnGrp == bgProto[level]); + level = btnGrp->property("ProtocolLevel").toInt(); + Q_ASSERT(btnGrp == bgProto[level]); - __updateProtocol(level, newId); + __updateProtocol(level, newId); } void StreamConfigDialog::__updateProtocol(int level, int newId) { - int oldId; - QButtonGroup *btnGrp; + int oldId; + QButtonGroup *btnGrp; - Q_ASSERT((level >= ProtoMin) && (level <= ProtoMax)); - btnGrp = bgProto[level]; - oldId = btnGrp->property("ProtocolId").toInt(); + Q_ASSERT((level >= ProtoMin) && (level <= ProtoMax)); + btnGrp = bgProto[level]; + oldId = btnGrp->property("ProtocolId").toInt(); - qDebug("%s: level = %d old id = %d new id = %d upd? = %d", __FUNCTION__, - level, oldId, newId, isUpdateInProgress); + qDebug("%s: level = %d old id = %d new id = %d upd? = %d", __FUNCTION__, + level, oldId, newId, isUpdateInProgress); - if (newId == oldId) - return; + if (newId == oldId) + return; - if (!isUpdateInProgress) - { - int ret; - AbstractProtocol *p; + if (!isUpdateInProgress) + { + int ret; + AbstractProtocol *p; - ret = skipProtocols(level-1); - Q_ASSERT(ret == true); + ret = skipProtocols(level-1); + Q_ASSERT(ret == true); - Q_ASSERT(oldId != newId); - Q_ASSERT(newId != ButtonIdOther); - - switch (oldId) - { - case ButtonIdNone: - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; + Q_ASSERT(oldId != newId); + Q_ASSERT(newId != ButtonIdOther); + + switch (oldId) + { + case ButtonIdNone: + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; - case ButtonIdOther: - default: - Q_ASSERT(_iter->hasNext()); - p =_iter->next(); + case ButtonIdOther: + default: + Q_ASSERT(_iter->hasNext()); + p =_iter->next(); - if (newId) - _iter->setValue(OstProtocolManager.createProtocol( - newId, mpStream)); - else - _iter->remove(); - delete p; - if (level == ProtoPayload) - { - while (_iter->hasNext()) - { - p = _iter->next(); - _iter->remove(); - delete p; - } - } - break; - } - } + if (newId) + _iter->setValue(OstProtocolManager.createProtocol( + newId, mpStream)); + else + _iter->remove(); + delete p; + if (level == ProtoPayload) + { + while (_iter->hasNext()) + { + p = _iter->next(); + _iter->remove(); + delete p; + } + } + break; + } + } - btnGrp->setProperty("ProtocolId", newId); - return; + btnGrp->setProperty("ProtocolId", newId); + return; } void StreamConfigDialog::updateSelectProtocolsSimpleWidget() { - int i; - quint32 id; - QAbstractButton *btn; + int i; + quint32 id; + QAbstractButton *btn; - qDebug("%s", __FUNCTION__); + qDebug("%s", __FUNCTION__); - isUpdateInProgress = true; + isUpdateInProgress = true; - // Reset to default state ... - for (i = ProtoMin; i < ProtoMax; i++) - bgProto[i]->button(ButtonIdNone)->click(); + // Reset to default state ... + for (i = ProtoMin; i < ProtoMax; i++) + bgProto[i]->button(ButtonIdNone)->click(); - // ... now iterate and update - _iter->toFront(); + // ... now iterate and update + _iter->toFront(); - for (i = ProtoMin; i < ProtoMax; i++) - { - if (!_iter->hasNext()) - goto _done; + for (i = ProtoMin; i < ProtoMax; i++) + { + if (!_iter->hasNext()) + goto _done; - id = _iter->next()->protocolNumber(); - btn = bgProto[i]->button(id); + id = _iter->next()->protocolNumber(); + btn = bgProto[i]->button(id); - if (btn) - { - if (btn->isEnabled()) - btn->click(); - else - { - btn->setChecked(true); - __updateProtocol(i, id); - } - } - else - { - switch (i) - { - case ProtoVlan: - _iter->previous(); - break; + if (btn) + { + if (btn->isEnabled()) + btn->click(); + else + { + btn->setChecked(true); + __updateProtocol(i, id); + } + } + else + { + switch (i) + { + case ProtoVlan: + _iter->previous(); + break; - case ProtoPayload: - goto _other; + case ProtoPayload: + goto _other; - default: - btn = bgProto[ProtoPayload]->button(id); - if (btn && btn->isEnabled()) - { - btn->click(); - break; - } - else - goto _other; - } - } - } + default: + btn = bgProto[ProtoPayload]->button(id); + if (btn && btn->isEnabled()) + { + btn->click(); + break; + } + else + goto _other; + } + } + } - // If more protocol(s) beyond payload ... - if (_iter->hasNext()) - { - i = ProtoPayload; - goto _other; - } + // If more protocol(s) beyond payload ... + if (_iter->hasNext()) + { + i = ProtoPayload; + goto _other; + } - goto _done; + goto _done; _other: - for (int j = i; j < ProtoMax; j++) - { - // VLAN doesn't have a "Other" button - if (j == ProtoVlan) - continue; + for (int j = i; j < ProtoMax; j++) + { + // VLAN doesn't have a "Other" button + if (j == ProtoVlan) + continue; - bgProto[j]->button(ButtonIdOther)->setChecked(true); - __updateProtocol(j, ButtonIdOther); - } + bgProto[j]->button(ButtonIdOther)->setChecked(true); + __updateProtocol(j, ButtonIdOther); + } _done: - isUpdateInProgress = false; + isUpdateInProgress = false; } void StreamConfigDialog::LoadCurrentStream() { - QString str; + QString str; - qDebug("loading mpStream %p", mpStream); + qDebug("loading mpStream %p", mpStream); - // Meta Data - { - cmbPktLenMode->setCurrentIndex(mpStream->lenMode()); - lePktLen->setText(str.setNum(mpStream->frameLen())); - lePktLenMin->setText(str.setNum(mpStream->frameLenMin())); - lePktLenMax->setText(str.setNum(mpStream->frameLenMax())); - } + // Meta Data + { + cmbPktLenMode->setCurrentIndex(mpStream->lenMode()); + lePktLen->setText(str.setNum(mpStream->frameLen())); + lePktLenMin->setText(str.setNum(mpStream->frameLenMin())); + lePktLenMax->setText(str.setNum(mpStream->frameLenMax())); + } - // Protocols - { - updateSelectProtocolsSimpleWidget(); - updateSelectProtocolsAdvancedWidget(); + // Protocols + { + updateSelectProtocolsSimpleWidget(); + updateSelectProtocolsAdvancedWidget(); - mpStream->loadProtocolWidgets(); - } + mpStream->loadProtocolWidgets(); + } - // Stream Control - { - switch (mpStream->sendUnit()) - { - case Stream::e_su_packets: - rbSendPackets->setChecked(true); - break; - case Stream::e_su_bursts: - rbSendBursts->setChecked(true); - break; - default: - qWarning("Unhandled sendUnit = %d\n", mpStream->sendUnit()); - } + // Stream Control + { + switch (mpStream->sendUnit()) + { + case Stream::e_su_packets: + rbSendPackets->setChecked(true); + break; + case Stream::e_su_bursts: + rbSendBursts->setChecked(true); + break; + default: + qWarning("Unhandled sendUnit = %d\n", mpStream->sendUnit()); + } - switch (mpStream->sendMode()) - { - case Stream::e_sm_fixed: - rbModeFixed->setChecked(true); - break; - case Stream::e_sm_continuous: - rbModeContinuous->setChecked(true); - break; - default: - qWarning("Unhandled sendMode = %d\n", mpStream->sendMode()); - } + switch (mpStream->sendMode()) + { + case Stream::e_sm_fixed: + rbModeFixed->setChecked(true); + break; + case Stream::e_sm_continuous: + rbModeContinuous->setChecked(true); + break; + default: + qWarning("Unhandled sendMode = %d\n", mpStream->sendMode()); + } - switch(mpStream->nextWhat()) - { - case Stream::e_nw_stop: - rbActionStop->setChecked(true); - break; - case Stream::e_nw_goto_next: - rbActionGotoNext->setChecked(true); - break; - case Stream::e_nw_goto_id: - rbActionGotoStream->setChecked(true); - break; - default: - qWarning("Unhandled nextAction = %d\n", mpStream->nextWhat()); - } + switch(mpStream->nextWhat()) + { + case Stream::e_nw_stop: + rbActionStop->setChecked(true); + break; + case Stream::e_nw_goto_next: + rbActionGotoNext->setChecked(true); + break; + case Stream::e_nw_goto_id: + rbActionGotoStream->setChecked(true); + break; + default: + qWarning("Unhandled nextAction = %d\n", mpStream->nextWhat()); + } - leNumPackets->setText(QString().setNum(mpStream->numPackets())); - leNumBursts->setText(QString().setNum(mpStream->numBursts())); - lePacketsPerBurst->setText(QString().setNum(mpStream->burstSize())); - lePacketsPerSec->setText(QString().setNum(mpStream->packetRate())); - leBurstsPerSec->setText(QString().setNum(mpStream->burstRate())); - // TODO(MED): Change this when we support goto to specific stream - leStreamId->setText(QString("0")); - } - qDebug("loading stream done"); + leNumPackets->setText(QString().setNum(mpStream->numPackets())); + leNumBursts->setText(QString().setNum(mpStream->numBursts())); + lePacketsPerBurst->setText(QString().setNum(mpStream->burstSize())); + lePacketsPerSec->setText(QString().setNum(mpStream->packetRate())); + leBurstsPerSec->setText(QString().setNum(mpStream->burstRate())); + // TODO(MED): Change this when we support goto to specific stream + leStreamId->setText(QString("0")); + } + qDebug("loading stream done"); } void StreamConfigDialog::StoreCurrentStream() { - QString str; - bool isOk; - Stream *pStream = mpStream; + QString str; + bool isOk; + Stream *pStream = mpStream; - qDebug("storing pStream %p", pStream); + qDebug("storing pStream %p", pStream); - // Meta Data - pStream->setLenMode((Stream::FrameLengthMode) cmbPktLenMode->currentIndex()); - pStream->setFrameLen(lePktLen->text().toULong(&isOk)); - pStream->setFrameLenMin(lePktLenMin->text().toULong(&isOk)); - pStream->setFrameLenMax(lePktLenMax->text().toULong(&isOk)); + // Meta Data + pStream->setLenMode((Stream::FrameLengthMode) cmbPktLenMode->currentIndex()); + pStream->setFrameLen(lePktLen->text().toULong(&isOk)); + pStream->setFrameLenMin(lePktLenMin->text().toULong(&isOk)); + pStream->setFrameLenMax(lePktLenMax->text().toULong(&isOk)); - // Protocols - { - pStream->storeProtocolWidgets(); - } + // Protocols + { + pStream->storeProtocolWidgets(); + } - // Stream Control - { - if (rbSendPackets->isChecked()) - pStream->setSendUnit(Stream::e_su_packets); - if (rbSendBursts->isChecked()) - pStream->setSendUnit(Stream::e_su_bursts); + // Stream Control + { + if (rbSendPackets->isChecked()) + pStream->setSendUnit(Stream::e_su_packets); + if (rbSendBursts->isChecked()) + pStream->setSendUnit(Stream::e_su_bursts); - if (rbModeFixed->isChecked()) - pStream->setSendMode(Stream::e_sm_fixed); - if (rbModeContinuous->isChecked()) - pStream->setSendMode(Stream::e_sm_continuous); + if (rbModeFixed->isChecked()) + pStream->setSendMode(Stream::e_sm_fixed); + if (rbModeContinuous->isChecked()) + pStream->setSendMode(Stream::e_sm_continuous); - if (rbActionStop->isChecked()) - pStream->setNextWhat(Stream::e_nw_stop); - if (rbActionGotoNext->isChecked()) - pStream->setNextWhat(Stream::e_nw_goto_next); - if (rbActionGotoStream->isChecked()) - pStream->setNextWhat(Stream::e_nw_goto_id); + if (rbActionStop->isChecked()) + pStream->setNextWhat(Stream::e_nw_stop); + if (rbActionGotoNext->isChecked()) + pStream->setNextWhat(Stream::e_nw_goto_next); + if (rbActionGotoStream->isChecked()) + pStream->setNextWhat(Stream::e_nw_goto_id); - pStream->setNumPackets(leNumPackets->text().toULong(&isOk)); - pStream->setNumBursts(leNumBursts->text().toULong(&isOk)); - pStream->setBurstSize(lePacketsPerBurst->text().toULong(&isOk)); - pStream->setPacketRate(lePacketsPerSec->text().toULong(&isOk)); - pStream->setBurstRate(leBurstsPerSec->text().toULong(&isOk)); - } + pStream->setNumPackets(leNumPackets->text().toULong(&isOk)); + pStream->setNumBursts(leNumBursts->text().toULong(&isOk)); + pStream->setBurstSize(lePacketsPerBurst->text().toULong(&isOk)); + pStream->setPacketRate(lePacketsPerSec->text().toULong(&isOk)); + pStream->setBurstRate(leBurstsPerSec->text().toULong(&isOk)); + } } void StreamConfigDialog::on_pbOk_clicked() { - OstProto::Stream s; + OstProto::Stream s; - // Store dialog contents into stream - StoreCurrentStream(); + // Store dialog contents into stream + StoreCurrentStream(); - // Copy the data from the "local working copy of stream" to "actual stream" - mpStream->protoDataCopyInto(s); - mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyFrom(s); + // Copy the data from the "local working copy of stream" to "actual stream" + mpStream->protoDataCopyInto(s); + mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyFrom(s); - qDebug("stream stored"); + qDebug("stream stored"); - lastTopLevelTabIndex = twTopLevel->currentIndex(); + lastTopLevelTabIndex = twTopLevel->currentIndex(); } diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 5909e8e..fcc3f40 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -8,9 +8,9 @@ #include "packetmodel.h" #include "modeltest.h" -#define MAX_MAC_ITER_COUNT 256 -#define MIN_PKT_LEN 64 -#define MAX_PKT_LEN 1522 +#define MAX_MAC_ITER_COUNT 256 +#define MIN_PKT_LEN 64 +#define MAX_PKT_LEN 1522 /* ** TODO @@ -21,92 +21,92 @@ class StreamConfigDialog : public QDialog, public Ui::StreamConfigDialog { - Q_OBJECT + Q_OBJECT public: - StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent = 0); - ~StreamConfigDialog(); + StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent = 0); + ~StreamConfigDialog(); private: - enum ButtonId - { - ButtonIdNone = 0, - ButtonIdOther = -2 - }; + enum ButtonId + { + ButtonIdNone = 0, + ButtonIdOther = -2 + }; - enum ProtoButtonGroup - { - ProtoMin, - ProtoL1 = 0, - ProtoVlan = 1, - ProtoL2 = 2, - ProtoL3 = 3, - ProtoL4 = 4, - ProtoPayload = 5, - ProtoMax - }; + enum ProtoButtonGroup + { + ProtoMin, + ProtoL1 = 0, + ProtoVlan = 1, + ProtoL2 = 2, + ProtoL3 = 3, + ProtoL4 = 4, + ProtoPayload = 5, + ProtoMax + }; - QButtonGroup *bgProto[ProtoMax]; + QButtonGroup *bgProto[ProtoMax]; - QStringListModel *mpAvailableProtocolsModel; - QStringListModel *mpSelectedProtocolsModel; + QStringListModel *mpAvailableProtocolsModel; + QStringListModel *mpSelectedProtocolsModel; - Port& mPort; - uint mCurrentStreamIndex; + Port& mPort; + uint mCurrentStreamIndex; - Stream *mpStream; - ProtocolListIterator *_iter; + Stream *mpStream; + ProtocolListIterator *_iter; - bool isUpdateInProgress; + bool isUpdateInProgress; - PacketModel *mpPacketModel; - ModelTest *mpPacketModelTester; + PacketModel *mpPacketModel; + ModelTest *mpPacketModelTester; - // The following static variables are used to track the "selected" tab + // The following static variables are used to track the "selected" tab // for the various tab widgets so that it can be restored when the dialog - // is opened the next time - static int lastTopLevelTabIndex; + // is opened the next time + static int lastTopLevelTabIndex; - void setupUiExtra(); - void updateSelectedProtocols(); - void LoadCurrentStream(); - void StoreCurrentStream(); + void setupUiExtra(); + void updateSelectedProtocols(); + void LoadCurrentStream(); + void StoreCurrentStream(); private slots: - void on_cmbPktLenMode_currentIndexChanged(QString mode); - void update_NumPacketsAndNumBursts(); + void on_cmbPktLenMode_currentIndexChanged(QString mode); + void update_NumPacketsAndNumBursts(); - void on_twTopLevel_currentChanged(int index); - void on_tbSelectProtocols_currentChanged(int index); + void on_twTopLevel_currentChanged(int index); + void on_tbSelectProtocols_currentChanged(int index); - // "Simple" Protocol Selection related - bool skipProtocols(int layer); + // "Simple" Protocol Selection related + bool skipProtocols(int layer); - void disableProtocols(QButtonGroup *protocolGroup, bool checked); - void forceProtocolNone(bool checked); + void disableProtocols(QButtonGroup *protocolGroup, bool checked); + void forceProtocolNone(bool checked); - void updateProtocol(int newId); - void __updateProtocol(int level, int newId); + void updateProtocol(int newId); + void __updateProtocol(int level, int newId); - void updateSelectProtocolsSimpleWidget(); + void updateSelectProtocolsSimpleWidget(); - // "Advanced" Protocol Selection related - void when_lvAllProtocols_selectionChanged( - const QItemSelection &selected, const QItemSelection &deselected); - void when_lvSelectedProtocols_currentChanged( - const QModelIndex ¤t, const QModelIndex &previous); + // "Advanced" Protocol Selection related + void when_lvAllProtocols_selectionChanged( + const QItemSelection &selected, const QItemSelection &deselected); + void when_lvSelectedProtocols_currentChanged( + const QModelIndex ¤t, const QModelIndex &previous); - void on_tbAdd_clicked(); - void on_tbDelete_clicked(); - void on_tbUp_clicked(); - void on_tbDown_clicked(); + void on_tbAdd_clicked(); + void on_tbDelete_clicked(); + void on_tbUp_clicked(); + void on_tbDown_clicked(); - void updateSelectProtocolsAdvancedWidget(); + void updateSelectProtocolsAdvancedWidget(); - void on_pbPrev_clicked(); - void on_pbNext_clicked(); + void on_pbPrev_clicked(); + void on_pbNext_clicked(); - void on_pbOk_clicked(); + void on_pbOk_clicked(); }; #endif diff --git a/client/streamlistdelegate.cpp b/client/streamlistdelegate.cpp index f67b99e..f701c13 100644 --- a/client/streamlistdelegate.cpp +++ b/client/streamlistdelegate.cpp @@ -13,163 +13,163 @@ StreamListDelegate::StreamListDelegate(QObject *parent) QWidget *StreamListDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem &option, - const QModelIndex &index) const + const QStyleOptionViewItem &option, + const QModelIndex &index) const { - QWidget *editor = NULL; + QWidget *editor = NULL; - switch ((StreamModel::StreamFields) index.column()) - { - case StreamModel::StreamStatus: - { - editor = new QCheckBox(parent); - goto _handled; - } - case StreamModel::StreamNextWhat: - { - editor = new QComboBox(parent); - static_cast(editor)->insertItems(0, - StreamModel::nextWhatOptionList()); - goto _handled; - } + switch ((StreamModel::StreamFields) index.column()) + { + case StreamModel::StreamStatus: + { + editor = new QCheckBox(parent); + goto _handled; + } + case StreamModel::StreamNextWhat: + { + editor = new QComboBox(parent); + static_cast(editor)->insertItems(0, + StreamModel::nextWhatOptionList()); + goto _handled; + } - case StreamModel::StreamIcon: - case StreamModel::StreamName: - default: - break; - } + case StreamModel::StreamIcon: + case StreamModel::StreamName: + default: + break; + } - editor = QItemDelegate::createEditor(parent, option, index); + editor = QItemDelegate::createEditor(parent, option, index); _handled: - return editor; + return editor; } void StreamListDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const + const QModelIndex &index) const { - switch ((StreamModel::StreamFields) index.column()) - { - case StreamModel::StreamStatus: - { - QCheckBox *cb = static_cast(editor); - cb->setChecked( - index.model()->data(index, Qt::EditRole).toBool()); - goto _handled; - } - case StreamModel::StreamNextWhat: - { - QComboBox *cb = static_cast(editor); - cb->setCurrentIndex( - index.model()->data(index, Qt::EditRole).toInt()); - goto _handled; - } + switch ((StreamModel::StreamFields) index.column()) + { + case StreamModel::StreamStatus: + { + QCheckBox *cb = static_cast(editor); + cb->setChecked( + index.model()->data(index, Qt::EditRole).toBool()); + goto _handled; + } + case StreamModel::StreamNextWhat: + { + QComboBox *cb = static_cast(editor); + cb->setCurrentIndex( + index.model()->data(index, Qt::EditRole).toInt()); + goto _handled; + } - case StreamModel::StreamIcon: - case StreamModel::StreamName: - default: - break; - } + case StreamModel::StreamIcon: + case StreamModel::StreamName: + default: + break; + } - QItemDelegate::setEditorData(editor, index); + QItemDelegate::setEditorData(editor, index); _handled: - return; + return; } void StreamListDelegate::setModelData(QWidget *editor, - QAbstractItemModel *model, const QModelIndex &index) const + QAbstractItemModel *model, const QModelIndex &index) const { - switch ((StreamModel::StreamFields) index.column()) - { - case StreamModel::StreamStatus: - { - QCheckBox *cb = static_cast(editor); - model->setData(index, cb->isChecked(), Qt::EditRole); - goto _handled; - } + switch ((StreamModel::StreamFields) index.column()) + { + case StreamModel::StreamStatus: + { + QCheckBox *cb = static_cast(editor); + model->setData(index, cb->isChecked(), Qt::EditRole); + goto _handled; + } - case StreamModel::StreamNextWhat: - { - QComboBox *cb = static_cast(editor); - model->setData(index, cb->currentIndex(), Qt::EditRole); - goto _handled; - } + case StreamModel::StreamNextWhat: + { + QComboBox *cb = static_cast(editor); + model->setData(index, cb->currentIndex(), Qt::EditRole); + goto _handled; + } - case StreamModel::StreamIcon: - case StreamModel::StreamName: - default: - break; - } + case StreamModel::StreamIcon: + case StreamModel::StreamName: + default: + break; + } - QItemDelegate::setModelData(editor, model, index); + QItemDelegate::setModelData(editor, model, index); _handled: - return; + return; } void StreamListDelegate::updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &index) const + const QStyleOptionViewItem &option, const QModelIndex &index) const { - switch ((StreamModel::StreamFields) index.column()) - { - case StreamModel::StreamStatus: - { - /* - * extra 'coz QItemDelegate does it - otherwise the editor - * placement is incorrect - */ - int extra = 2 * (qApp->style()->pixelMetric( - QStyle::PM_FocusFrameHMargin, 0) + 1); + switch ((StreamModel::StreamFields) index.column()) + { + case StreamModel::StreamStatus: + { + /* + * extra 'coz QItemDelegate does it - otherwise the editor + * placement is incorrect + */ + int extra = 2 * (qApp->style()->pixelMetric( + QStyle::PM_FocusFrameHMargin, 0) + 1); - editor->setGeometry(option.rect.translated(extra, 0)); - goto _handled; - } - case StreamModel::StreamIcon: - case StreamModel::StreamName: - case StreamModel::StreamNextWhat: - default: - break; - } + editor->setGeometry(option.rect.translated(extra, 0)); + goto _handled; + } + case StreamModel::StreamIcon: + case StreamModel::StreamName: + case StreamModel::StreamNextWhat: + default: + break; + } - QItemDelegate::updateEditorGeometry(editor, option, index); + QItemDelegate::updateEditorGeometry(editor, option, index); _handled: - return; + return; } bool StreamListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index) + const QStyleOptionViewItem &option, const QModelIndex &index) { - /* + /* * Special Handling so that user can use the "Stream status" checkbox - * without double clicking first. Copied from QItemDelegate::editorEvent() - * and modified suitably - */ - if ((StreamModel::StreamFields)index.column() == - StreamModel::StreamStatus) - { - // make sure that we have the right event type - if ((event->type() == QEvent::MouseButtonRelease) - || (event->type() == QEvent::MouseButtonDblClick)) - { - QRect checkRect = check(option, option.rect, Qt::Checked); - QRect emptyRect; - doLayout(option, &checkRect, &emptyRect, &emptyRect, false); - if (!checkRect.contains(static_cast(event)->pos())) - return false; + * without double clicking first. Copied from QItemDelegate::editorEvent() + * and modified suitably + */ + if ((StreamModel::StreamFields)index.column() == + StreamModel::StreamStatus) + { + // make sure that we have the right event type + if ((event->type() == QEvent::MouseButtonRelease) + || (event->type() == QEvent::MouseButtonDblClick)) + { + QRect checkRect = check(option, option.rect, Qt::Checked); + QRect emptyRect; + doLayout(option, &checkRect, &emptyRect, &emptyRect, false); + if (!checkRect.contains(static_cast(event)->pos())) + return false; - Qt::CheckState state = (static_cast(index.data( - Qt::CheckStateRole).toInt()) == Qt::Checked ? Qt::Unchecked : Qt::Checked); - return model->setData(index, state, Qt::CheckStateRole); - } - } + Qt::CheckState state = (static_cast(index.data( + Qt::CheckStateRole).toInt()) == Qt::Checked ? Qt::Unchecked : Qt::Checked); + return model->setData(index, state, Qt::CheckStateRole); + } + } - return QItemDelegate::editorEvent(event, model, option, index); + return QItemDelegate::editorEvent(event, model, option, index); } diff --git a/client/streamlistdelegate.h b/client/streamlistdelegate.h index a4e8d35..6a52aaa 100644 --- a/client/streamlistdelegate.h +++ b/client/streamlistdelegate.h @@ -9,20 +9,20 @@ class StreamListDelegate : public QItemDelegate Q_OBJECT public: - StreamListDelegate(QObject *parent = 0); + StreamListDelegate(QObject *parent = 0); - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; - void setEditorData(QWidget *editor, const QModelIndex &index) const; - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const; + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; - void updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const; - bool editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index); + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index); }; #endif diff --git a/client/streammodel.cpp b/client/streammodel.cpp index a3036fb..925be4b 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -4,239 +4,239 @@ #include "qicon.h" StreamModel::StreamModel(PortGroupList *p, QObject *parent) - : QAbstractTableModel(parent) + : QAbstractTableModel(parent) { - pgl = p; - mCurrentPort = NULL; + pgl = p; + mCurrentPort = NULL; } int StreamModel::rowCount(const QModelIndex &parent) const { - if (parent.isValid()) - return 0; + if (parent.isValid()) + return 0; - if (mCurrentPort) - return mCurrentPort->numStreams(); - else - return 0; + if (mCurrentPort) + return mCurrentPort->numStreams(); + else + return 0; } int StreamModel::columnCount(const QModelIndex &parent ) const { - return (int) StreamMaxFields; + return (int) StreamMaxFields; } Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const { - Qt::ItemFlags flags = QAbstractTableModel::flags(index); + Qt::ItemFlags flags = QAbstractTableModel::flags(index); - switch (index.column()) - { - case StreamIcon: - break; - case StreamName: - flags |= Qt::ItemIsEditable; - break; - case StreamStatus: - flags |= Qt::ItemIsUserCheckable; - break; - case StreamNextWhat: - flags |= Qt::ItemIsEditable; - break; - default: - //qFatal("Missed case in switch!"); - break; - } + switch (index.column()) + { + case StreamIcon: + break; + case StreamName: + flags |= Qt::ItemIsEditable; + break; + case StreamStatus: + flags |= Qt::ItemIsUserCheckable; + break; + case StreamNextWhat: + flags |= Qt::ItemIsEditable; + break; + default: + //qFatal("Missed case in switch!"); + break; + } - return flags; + return flags; } QVariant StreamModel::data(const QModelIndex &index, int role) const { - // Check for a valid index - if (!index.isValid()) - return QVariant(); + // Check for a valid index + if (!index.isValid()) + return QVariant(); - // Check for row/column limits - if (index.row() >= mCurrentPort->numStreams()) - return QVariant(); + // Check for row/column limits + if (index.row() >= mCurrentPort->numStreams()) + return QVariant(); - if (index.column() >= StreamMaxFields) - return QVariant(); + if (index.column() >= StreamMaxFields) + return QVariant(); - if (mCurrentPort == NULL) - return QVariant(); + if (mCurrentPort == NULL) + return QVariant(); - // Return data based on field and role - switch(index.column()) - { - case StreamIcon: - { - if (role == Qt::DecorationRole) - return QIcon(":/icons/stream_edit.png"); - else - return QVariant(); - break; - } - case StreamName: - { - if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) - return mCurrentPort->streamByIndex(index.row())->name(); - else - return QVariant(); - break; - } - case StreamStatus: - { - if ((role == Qt::CheckStateRole)) - { - if (mCurrentPort->streamByIndex(index.row())->isEnabled()) - return Qt::Checked; - else - return Qt::Unchecked; - } - else - return QVariant(); - break; - } - case StreamNextWhat: - { - int val = mCurrentPort->streamByIndex(index.row())->nextWhat(); + // Return data based on field and role + switch(index.column()) + { + case StreamIcon: + { + if (role == Qt::DecorationRole) + return QIcon(":/icons/stream_edit.png"); + else + return QVariant(); + break; + } + case StreamName: + { + if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) + return mCurrentPort->streamByIndex(index.row())->name(); + else + return QVariant(); + break; + } + case StreamStatus: + { + if ((role == Qt::CheckStateRole)) + { + if (mCurrentPort->streamByIndex(index.row())->isEnabled()) + return Qt::Checked; + else + return Qt::Unchecked; + } + else + return QVariant(); + break; + } + case StreamNextWhat: + { + int val = mCurrentPort->streamByIndex(index.row())->nextWhat(); - if (role == Qt::DisplayRole) - return nextWhatOptionList().at(val); - else if (role == Qt::EditRole) - return val; - else - return QVariant(); + if (role == Qt::DisplayRole) + return nextWhatOptionList().at(val); + else if (role == Qt::EditRole) + return val; + else + return QVariant(); - break; - } - default: - qFatal("-------------UNHANDLED STREAM FIELD----------------"); - } + break; + } + default: + qFatal("-------------UNHANDLED STREAM FIELD----------------"); + } - return QVariant(); + return QVariant(); } bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if (mCurrentPort == NULL) - return false; + if (mCurrentPort == NULL) + return false; - if (index.isValid()) - { - switch (index.column()) - { - // Edit Supported Fields - case StreamName: - mCurrentPort->streamByIndex(index.row())->setName(value.toString()); - emit(dataChanged(index, index)); - return true; + if (index.isValid()) + { + switch (index.column()) + { + // Edit Supported Fields + case StreamName: + mCurrentPort->streamByIndex(index.row())->setName(value.toString()); + emit(dataChanged(index, index)); + return true; - case StreamStatus: - mCurrentPort->streamByIndex(index.row())->setEnabled(value.toBool()); - emit(dataChanged(index, index)); - return true; + case StreamStatus: + mCurrentPort->streamByIndex(index.row())->setEnabled(value.toBool()); + emit(dataChanged(index, index)); + return true; - case StreamNextWhat: - if (role == Qt::EditRole) - { - mCurrentPort->streamByIndex(index.row())->setNextWhat( - (Stream::NextWhat)value.toInt()); - emit(dataChanged(index, index)); - return true; - } - else - return false; + case StreamNextWhat: + if (role == Qt::EditRole) + { + mCurrentPort->streamByIndex(index.row())->setNextWhat( + (Stream::NextWhat)value.toInt()); + emit(dataChanged(index, index)); + return true; + } + else + return false; - // Edit Not Supported Fields - case StreamIcon: - return false; + // Edit Not Supported Fields + case StreamIcon: + return false; - // Unhandled Stream Field - default: - qDebug("-------------UNHANDLED STREAM FIELD----------------"); - break; - } - } + // Unhandled Stream Field + default: + qDebug("-------------UNHANDLED STREAM FIELD----------------"); + break; + } + } - return false; + return false; } QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (role != Qt::DisplayRole) - return QVariant(); + if (role != Qt::DisplayRole) + return QVariant(); - if (orientation == Qt::Horizontal) - { - switch(section) - { - case StreamIcon: - return QString(""); - break; - case StreamName: - return QString("Name"); - break; - case StreamStatus: - return QString(""); - break; - case StreamNextWhat: - return QString("Goto"); - break; - default: - qDebug("-------------UNHANDLED STREAM FIELD----------------"); - break; - } - } - else - return QString("%1").arg(section+1); + if (orientation == Qt::Horizontal) + { + switch(section) + { + case StreamIcon: + return QString(""); + break; + case StreamName: + return QString("Name"); + break; + case StreamStatus: + return QString(""); + break; + case StreamNextWhat: + return QString("Goto"); + break; + default: + qDebug("-------------UNHANDLED STREAM FIELD----------------"); + break; + } + } + else + return QString("%1").arg(section+1); - return QVariant(); + return QVariant(); } bool StreamModel::insertRows(int row, int count, const QModelIndex &parent) { - qDebug("insertRows() row = %d", row); - qDebug("insertRows() count = %d", count); - beginInsertRows(QModelIndex(), row, row+count-1); - for (int i = 0; i < count; i++) - mCurrentPort->newStreamAt(row); - endInsertRows(); + qDebug("insertRows() row = %d", row); + qDebug("insertRows() count = %d", count); + beginInsertRows(QModelIndex(), row, row+count-1); + for (int i = 0; i < count; i++) + mCurrentPort->newStreamAt(row); + endInsertRows(); - return true; + return true; } bool StreamModel::removeRows(int row, int count, const QModelIndex &parent) { - qDebug("removeRows() row = %d", row); - qDebug("removeRows() count = %d", count); - beginRemoveRows(QModelIndex(), row, row+count-1); - for (int i = 0; i < count; i++) - { - mCurrentPort->deleteStreamAt(row); - } - endRemoveRows(); + qDebug("removeRows() row = %d", row); + qDebug("removeRows() count = %d", count); + beginRemoveRows(QModelIndex(), row, row+count-1); + for (int i = 0; i < count; i++) + { + mCurrentPort->deleteStreamAt(row); + } + endRemoveRows(); - return true; + return true; } // --------------------- SLOTS ------------------------ void StreamModel::setCurrentPortIndex(const QModelIndex ¤t) { - if (!current.isValid() || !pgl->isPort(current)) - { - qDebug("current is either invalid or not a port"); - mCurrentPort = NULL; - } - else - { - qDebug("change to valid port"); - quint16 pg = current.internalId() >> 16; - mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()]; - } - reset(); + if (!current.isValid() || !pgl->isPort(current)) + { + qDebug("current is either invalid or not a port"); + mCurrentPort = NULL; + } + else + { + qDebug("change to valid port"); + quint16 pg = current.internalId() >> 16; + mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()]; + } + reset(); } diff --git a/client/streammodel.h b/client/streammodel.h index 95af6fe..c65b4d9 100644 --- a/client/streammodel.h +++ b/client/streammodel.h @@ -9,48 +9,48 @@ class PortGroupList; class StreamModel : public QAbstractTableModel { - Q_OBJECT + Q_OBJECT - Port *mCurrentPort; - PortGroupList *pgl; + Port *mCurrentPort; + PortGroupList *pgl; - public: - StreamModel(PortGroupList *p, QObject *parent = 0); + public: + StreamModel(PortGroupList *p, QObject *parent = 0); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role) const; - bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole); - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - bool insertRows (int row, int count, - const QModelIndex & parent = QModelIndex()); - bool removeRows (int row, int count, - const QModelIndex & parent = QModelIndex()); - + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + bool insertRows (int row, int count, + const QModelIndex & parent = QModelIndex()); + bool removeRows (int row, int count, + const QModelIndex & parent = QModelIndex()); + #if 0 // CleanedUp! - // FIXME(HIGH): This *is* like a kludge - QList* currentPortStreamList() - { return &mCurrentPort->mStreams; } + // FIXME(HIGH): This *is* like a kludge + QList* currentPortStreamList() + { return &mCurrentPort->mStreams; } #endif - public: - enum StreamFields { - StreamIcon = 0, - StreamName, - StreamStatus, - StreamNextWhat, + public: + enum StreamFields { + StreamIcon = 0, + StreamName, + StreamStatus, + StreamNextWhat, - StreamMaxFields - }; + StreamMaxFields + }; - static QStringList nextWhatOptionList() - { return QStringList() << "Stop" << "Next" << "Goto first"; } + static QStringList nextWhatOptionList() + { return QStringList() << "Stop" << "Next" << "Goto first"; } - public slots: - void setCurrentPortIndex(const QModelIndex ¤t); + public slots: + void setCurrentPortIndex(const QModelIndex ¤t); }; diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 025a745..8773154 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -24,12 +24,12 @@ */ AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent) { - //qDebug("%s: &prev = %p &next = %p", __FUNCTION__, &prev, &next); - mpStream = stream; - this->parent = parent; - prev = next = NULL; - metaCount = -1; - protoSize = -1; + //qDebug("%s: &prev = %p &next = %p", __FUNCTION__, &prev, &next); + mpStream = stream; + this->parent = parent; + prev = next = NULL; + metaCount = -1; + protoSize = -1; } AbstractProtocol::~AbstractProtocol() @@ -37,15 +37,15 @@ AbstractProtocol::~AbstractProtocol() } AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return NULL; + return NULL; } quint32 AbstractProtocol::protocolNumber() const { - qFatal("Something wrong!!!"); - return 0xFFFFFFFF; + qFatal("Something wrong!!!"); + return 0xFFFFFFFF; } /*! @@ -64,7 +64,7 @@ quint32 AbstractProtocol::protocolNumber() const The default implementation returns a null string */ QString AbstractProtocol::name() const { - return QString(); + return QString(); } /*! Returns the short name or abbreviation of the protocol \n @@ -74,27 +74,27 @@ QString AbstractProtocol::name() const and subsequently returns the cached abbreviation */ QString AbstractProtocol::shortName() const { - if (protoAbbr.isNull()) - { - QString abbr; + if (protoAbbr.isNull()) + { + QString abbr; - for (int i = 0; i < name().size(); i++) - if (name().at(i).isUpper()) abbr.append(name().at(i)); + for (int i = 0; i < name().size(); i++) + if (name().at(i).isUpper()) abbr.append(name().at(i)); - if (abbr.size()) - protoAbbr = abbr; - else - protoAbbr = QString(""); - } + if (abbr.size()) + protoAbbr = abbr; + else + protoAbbr = QString(""); + } - return protoAbbr; + return protoAbbr; } /*! Returns the number of fields (both Frame and Meta fields) \n The default implementation returns zero */ -int AbstractProtocol::fieldCount() const +int AbstractProtocol::fieldCount() const { - return 0; + return 0; } /*! Returns the number of meta fields \n @@ -102,31 +102,31 @@ int AbstractProtocol::fieldCount() const the FieldIsMeta flag is set\n The default implementation caches the count on its first invocation and subsequently returns the cached count */ -int AbstractProtocol::metaFieldCount() const +int AbstractProtocol::metaFieldCount() const { - if (metaCount < 0) - { - int c = 0; - for (int i = 0; i < fieldCount() ; i++) - if (fieldFlags(i).testFlag(FieldIsMeta)) - c++; - metaCount = c; - } + if (metaCount < 0) + { + int c = 0; + for (int i = 0; i < fieldCount() ; i++) + if (fieldFlags(i).testFlag(FieldIsMeta)) + c++; + metaCount = c; + } - return metaCount; + return metaCount; } /*! Returns the number of frame fields \n Convenience method - same as fieldCount() minus metaFieldCount() */ -int AbstractProtocol::frameFieldCount() const +int AbstractProtocol::frameFieldCount() const { - //qDebug("%s:%d, %d", __FUNCTION__, fieldCount(), metaFieldCount()); - return (fieldCount() - metaFieldCount()); + //qDebug("%s:%d, %d", __FUNCTION__, fieldCount(), metaFieldCount()); + return (fieldCount() - metaFieldCount()); } AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int index) const { - return FieldIsNormal; + return FieldIsNormal; } /*! Returns the requested field attribute data \n @@ -157,116 +157,116 @@ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int index) const - protocolFramePayloadSize() */ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (attrib) - { - case FieldName: - return QString(); - case FieldBitSize: - Q_ASSERT_X(!fieldFlags(index).testFlag(FieldIsCksum), - "AbstractProtocol::fieldData()", - "FieldBitSize for checksum fields need to be handled by the subclass"); - return fieldData(index, FieldFrameValue, streamIndex). - toByteArray().size() * 8; - case FieldValue: - return 0; - case FieldFrameValue: - return QByteArray(); - case FieldTextValue: - return QString(); + switch (attrib) + { + case FieldName: + return QString(); + case FieldBitSize: + Q_ASSERT_X(!fieldFlags(index).testFlag(FieldIsCksum), + "AbstractProtocol::fieldData()", + "FieldBitSize for checksum fields need to be handled by the subclass"); + return fieldData(index, FieldFrameValue, streamIndex). + toByteArray().size() * 8; + case FieldValue: + return 0; + case FieldFrameValue: + return QByteArray(); + case FieldTextValue: + return QString(); - default: - qFatal("%s:%d: unhandled case %d\n", __FUNCTION__, __LINE__, - attrib); - } + default: + qFatal("%s:%d: unhandled case %d\n", __FUNCTION__, __LINE__, + attrib); + } - return QVariant(); + return QVariant(); } /*! Sets the value of a field corresponding to index \n Returns true if field is successfully set, false otherwise \n The default implementation always returns false */ bool AbstractProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - return false; + return false; } AbstractProtocol::ProtocolIdType AbstractProtocol::protocolIdType() const { - return ProtocolIdNone; + return ProtocolIdNone; } quint32 AbstractProtocol::protocolId(ProtocolIdType type) const { - return 0; + return 0; } quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const { - quint32 id; + quint32 id; - if (next) - id = next->protocolId(type); - else if (parent) - id = parent->payloadProtocolId(type); - else - id = 0xFFFFFFFF; + if (next) + id = next->protocolId(type); + else if (parent) + id = parent->payloadProtocolId(type); + else + id = 0xFFFFFFFF; - qDebug("%s: payloadProtocolId = 0x%x", __FUNCTION__, id); - return id; + qDebug("%s: payloadProtocolId = 0x%x", __FUNCTION__, id); + return id; } int AbstractProtocol::protocolFrameSize(int streamIndex) const { - if (protoSize < 0) - { - int bitsize = 0; + if (protoSize < 0) + { + int bitsize = 0; - for (int i = 0; i < fieldCount(); i++) - { - if (!fieldFlags(i).testFlag(FieldIsMeta)) - bitsize += fieldData(i, FieldBitSize, streamIndex).toUInt(); - } - protoSize = (bitsize+7)/8; - } + for (int i = 0; i < fieldCount(); i++) + { + if (!fieldFlags(i).testFlag(FieldIsMeta)) + bitsize += fieldData(i, FieldBitSize, streamIndex).toUInt(); + } + protoSize = (bitsize+7)/8; + } - qDebug("%s: protoSize = %d", __FUNCTION__, protoSize); - return protoSize; + qDebug("%s: protoSize = %d", __FUNCTION__, protoSize); + return protoSize; } int AbstractProtocol::protocolFrameOffset(int streamIndex) const { - int size = 0; - AbstractProtocol *p = prev; - while (p) - { - size += p->protocolFrameSize(streamIndex); - p = p->prev; - } + int size = 0; + AbstractProtocol *p = prev; + while (p) + { + size += p->protocolFrameSize(streamIndex); + p = p->prev; + } - if (parent) - size += parent->protocolFrameOffset(streamIndex); + if (parent) + size += parent->protocolFrameOffset(streamIndex); - qDebug("%s: ofs = %d", __FUNCTION__, size); - return size; + qDebug("%s: ofs = %d", __FUNCTION__, size); + return size; } int AbstractProtocol::protocolFramePayloadSize(int streamIndex) const { - int size = 0; - AbstractProtocol *p = next; - while (p) - { - size += p->protocolFrameSize(streamIndex); - p = p->next; - } - if (parent) - size += parent->protocolFramePayloadSize(streamIndex); + int size = 0; + AbstractProtocol *p = next; + while (p) + { + size += p->protocolFrameSize(streamIndex); + p = p->next; + } + if (parent) + size += parent->protocolFramePayloadSize(streamIndex); - qDebug("%s: payloadSize = %d", __FUNCTION__, size); - return size; + qDebug("%s: payloadSize = %d", __FUNCTION__, size); + return size; } @@ -277,136 +277,136 @@ int AbstractProtocol::protocolFramePayloadSize(int streamIndex) const which are not an integral number of bytes\n */ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) const { - QByteArray proto, field; - uint bits, lastbitpos = 0; - FieldFlags flags; + QByteArray proto, field; + uint bits, lastbitpos = 0; + FieldFlags flags; - for (int i=0; i < fieldCount() ; i++) - { - flags = fieldFlags(i); - if (!flags.testFlag(FieldIsMeta)) - { - bits = fieldData(i, FieldBitSize, streamIndex).toUInt(); - if (bits == 0) - continue; - Q_ASSERT(bits > 0); + for (int i=0; i < fieldCount() ; i++) + { + flags = fieldFlags(i); + if (!flags.testFlag(FieldIsMeta)) + { + bits = fieldData(i, FieldBitSize, streamIndex).toUInt(); + if (bits == 0) + continue; + Q_ASSERT(bits > 0); - if (forCksum && flags.testFlag(FieldIsCksum)) - { - field.resize((bits+7)/8); - field.fill('\0'); - } - else - field = fieldData(i, FieldFrameValue, streamIndex).toByteArray(); - qDebug("<<< %d, %d/%d >>>>", proto.size(), bits, field.size()); + if (forCksum && flags.testFlag(FieldIsCksum)) + { + field.resize((bits+7)/8); + field.fill('\0'); + } + else + field = fieldData(i, FieldFrameValue, streamIndex).toByteArray(); + qDebug("<<< %d, %d/%d >>>>", proto.size(), bits, field.size()); - if (bits == (uint) field.size() * 8) - { - if (lastbitpos == 0) - proto.append(field); - else - { - Q_ASSERT(field.size() > 0); + if (bits == (uint) field.size() * 8) + { + if (lastbitpos == 0) + proto.append(field); + else + { + Q_ASSERT(field.size() > 0); - char c = proto[proto.size() - 1]; - proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos); - for (int j = 0; j < field.size() - 1; j++) - proto.append(field.at(j) << lastbitpos | - field.at(j+1) >> lastbitpos); - } - } - else if (bits < (uint) field.size() * 8) - { - uchar c; - uint v; + char c = proto[proto.size() - 1]; + proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos); + for (int j = 0; j < field.size() - 1; j++) + proto.append(field.at(j) << lastbitpos | + field.at(j+1) >> lastbitpos); + } + } + else if (bits < (uint) field.size() * 8) + { + uchar c; + uint v; - v = (field.size()*8) - bits; + v = (field.size()*8) - bits; - Q_ASSERT(v < 8); + Q_ASSERT(v < 8); - if (lastbitpos == 0) - { - for (int j = 0; j < field.size(); j++) - { - c = field.at(j) << v; - if ((j+1) < field.size()) - c |= ((uchar)field.at(j+1) >> (8-v)); - proto.append(c); - } + if (lastbitpos == 0) + { + for (int j = 0; j < field.size(); j++) + { + c = field.at(j) << v; + if ((j+1) < field.size()) + c |= ((uchar)field.at(j+1) >> (8-v)); + proto.append(c); + } - lastbitpos = (lastbitpos + bits) % 8; - } - else - { - Q_ASSERT(proto.size() > 0); + lastbitpos = (lastbitpos + bits) % 8; + } + else + { + Q_ASSERT(proto.size() > 0); - for (int j = 0; j < field.size(); j++) - { - uchar d; + for (int j = 0; j < field.size(); j++) + { + uchar d; - c = field.at(j) << v; - if ((j+1) < field.size()) - c |= ((uchar) field.at(j+1) >> (8-v)); - d = proto[proto.size() - 1]; - proto[proto.size() - 1] = d | ((uchar) c >> lastbitpos); - if (bits > (8*j + (8 - v))) - proto.append(c << (8-lastbitpos)); - } + c = field.at(j) << v; + if ((j+1) < field.size()) + c |= ((uchar) field.at(j+1) >> (8-v)); + d = proto[proto.size() - 1]; + proto[proto.size() - 1] = d | ((uchar) c >> lastbitpos); + if (bits > (8*j + (8 - v))) + proto.append(c << (8-lastbitpos)); + } - lastbitpos = (lastbitpos + bits) % 8; - } - } - else // if (bits > field.size() * 8) - { - qFatal("bitsize more than FrameValue size. skipping..."); - continue; - } - } - } + lastbitpos = (lastbitpos + bits) % 8; + } + } + else // if (bits > field.size() * 8) + { + qFatal("bitsize more than FrameValue size. skipping..."); + continue; + } + } + } - return proto; + return proto; } bool AbstractProtocol::isProtocolFrameValueVariable() const { - return false; + return false; } bool AbstractProtocol::isProtocolFrameSizeVariable() const { - return false; + return false; } bool AbstractProtocol::isProtocolFramePayloadValueVariable() const { - AbstractProtocol *p = next; + AbstractProtocol *p = next; - while (p) - { - if (p->isProtocolFrameValueVariable()) - return true; - p = p->next; - } - if (parent && parent->isProtocolFramePayloadValueVariable()) - return true; + while (p) + { + if (p->isProtocolFrameValueVariable()) + return true; + p = p->next; + } + if (parent && parent->isProtocolFramePayloadValueVariable()) + return true; - return false; + return false; } bool AbstractProtocol::isProtocolFramePayloadSizeVariable() const { - AbstractProtocol *p = next; + AbstractProtocol *p = next; - while (p) - { - if (p->isProtocolFrameSizeVariable()) - return true; - p = p->next; - } - if (parent && parent->isProtocolFramePayloadSizeVariable()) - return true; + while (p) + { + if (p->isProtocolFrameSizeVariable()) + return true; + p = p->next; + } + if (parent && parent->isProtocolFramePayloadSizeVariable()) + return true; - return false; + return false; } @@ -418,124 +418,124 @@ bool AbstractProtocol::isProtocolFramePayloadSizeVariable() const to prevent infinite recursion */ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex, - CksumType cksumType) const + CksumType cksumType) const { - static int recursionCount = 0; - quint32 cksum = 0xFFFFFFFF; + static int recursionCount = 0; + quint32 cksum = 0xFFFFFFFF; - recursionCount++; - Q_ASSERT_X(recursionCount < 10, "protocolFrameCksum", "potential infinite recursion - does a protocol checksum field not implement FieldBitSize?"); + recursionCount++; + Q_ASSERT_X(recursionCount < 10, "protocolFrameCksum", "potential infinite recursion - does a protocol checksum field not implement FieldBitSize?"); - switch(cksumType) - { - case CksumIp: - { - QByteArray fv; - quint16 *ip; - quint32 len, sum = 0; + switch(cksumType) + { + case CksumIp: + { + QByteArray fv; + quint16 *ip; + quint32 len, sum = 0; - fv = protocolFrameValue(streamIndex, true); - ip = (quint16*) fv.constData(); - len = fv.size(); + fv = protocolFrameValue(streamIndex, true); + ip = (quint16*) fv.constData(); + len = fv.size(); - while(len > 1) - { - sum += *ip; - if(sum & 0x80000000) - sum = (sum & 0xFFFF) + (sum >> 16); - ip++; - len -= 2; - } + while(len > 1) + { + sum += *ip; + if(sum & 0x80000000) + sum = (sum & 0xFFFF) + (sum >> 16); + ip++; + len -= 2; + } - if (len) - sum += (unsigned short) *(unsigned char *)ip; + if (len) + sum += (unsigned short) *(unsigned char *)ip; - while(sum>>16) - sum = (sum & 0xFFFF) + (sum >> 16); + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); - cksum = qFromBigEndian((quint16) ~sum); - break; - } + cksum = qFromBigEndian((quint16) ~sum); + break; + } - case CksumTcpUdp: - { - quint16 cks; - quint32 sum = 0; + case CksumTcpUdp: + { + quint16 cks; + quint32 sum = 0; - cks = protocolFrameCksum(streamIndex, CksumIp); - sum += (quint16) ~cks; - cks = protocolFramePayloadCksum(streamIndex, CksumIp); - sum += (quint16) ~cks; - cks = protocolFrameHeaderCksum(streamIndex, CksumIpPseudo); - sum += (quint16) ~cks; + cks = protocolFrameCksum(streamIndex, CksumIp); + sum += (quint16) ~cks; + cks = protocolFramePayloadCksum(streamIndex, CksumIp); + sum += (quint16) ~cks; + cks = protocolFrameHeaderCksum(streamIndex, CksumIpPseudo); + sum += (quint16) ~cks; - while(sum>>16) - sum = (sum & 0xFFFF) + (sum >> 16); + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); - cksum = (~sum) & 0xFFFF; - break; - } - default: - break; - } + cksum = (~sum) & 0xFFFF; + break; + } + default: + break; + } - recursionCount--; - return cksum; + recursionCount--; + return cksum; } quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, - CksumType cksumType) const + CksumType cksumType) const { - quint32 sum = 0; - quint16 cksum; - AbstractProtocol *p = prev; + quint32 sum = 0; + quint16 cksum; + AbstractProtocol *p = prev; - Q_ASSERT(cksumType == CksumIpPseudo); + Q_ASSERT(cksumType == CksumIpPseudo); - while (p) - { - cksum = p->protocolFrameCksum(streamIndex, cksumType); - sum += (quint16) ~cksum; - p = p->prev; - qDebug("%s: sum = %u, cksum = %u", __FUNCTION__, sum, cksum); - } - if (parent) - { - cksum = parent->protocolFrameHeaderCksum(streamIndex, cksumType); - sum += (quint16) ~cksum; - } + while (p) + { + cksum = p->protocolFrameCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; + p = p->prev; + qDebug("%s: sum = %u, cksum = %u", __FUNCTION__, sum, cksum); + } + if (parent) + { + cksum = parent->protocolFrameHeaderCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; + } - while(sum>>16) - sum = (sum & 0xFFFF) + (sum >> 16); + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); - return (quint16) ~sum; + return (quint16) ~sum; } quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, - CksumType cksumType) const + CksumType cksumType) const { - quint32 sum = 0; - quint16 cksum; - AbstractProtocol *p = next; + quint32 sum = 0; + quint16 cksum; + AbstractProtocol *p = next; - Q_ASSERT(cksumType == CksumIp); + Q_ASSERT(cksumType == CksumIp); - while (p) - { - cksum = p->protocolFrameCksum(streamIndex, cksumType); - sum += (quint16) ~cksum; - p = p->next; - } + while (p) + { + cksum = p->protocolFrameCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; + p = p->next; + } - if (parent) - { - cksum = parent->protocolFramePayloadCksum(streamIndex, cksumType); - sum += (quint16) ~cksum; - } + if (parent) + { + cksum = parent->protocolFramePayloadCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; + } - while(sum>>16) - sum = (sum & 0xFFFF) + (sum >> 16); + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); - return (quint16) ~sum; + return (quint16) ~sum; } diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index c520a31..fb6a703 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -16,108 +16,108 @@ #define BASE_DEC (10) #define BASE_HEX (16) -#define uintToHexStr(num, bytes) \ - QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) +#define uintToHexStr(num, bytes) \ + QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) class StreamBase; class ProtocolListIterator; class AbstractProtocol { - template - friend class ComboProtocol; - friend class ProtocolListIterator; + template + friend class ComboProtocol; + friend class ProtocolListIterator; private: - mutable int metaCount; - mutable int protoSize; - mutable QString protoAbbr; + mutable int metaCount; + mutable int protoSize; + mutable QString protoAbbr; protected: - StreamBase *mpStream; - AbstractProtocol *parent; - AbstractProtocol *prev; - AbstractProtocol *next; + StreamBase *mpStream; + AbstractProtocol *parent; + AbstractProtocol *prev; + AbstractProtocol *next; public: - enum FieldFlag { - FieldIsNormal = 0x0, - FieldIsMeta = 0x1, - FieldIsCksum = 0x2 - }; - Q_DECLARE_FLAGS(FieldFlags, FieldFlag); + enum FieldFlag { + FieldIsNormal = 0x0, + FieldIsMeta = 0x1, + FieldIsCksum = 0x2 + }; + Q_DECLARE_FLAGS(FieldFlags, FieldFlag); - enum FieldAttrib { - FieldName, //! name - FieldValue, //! value in host byte order (user editable) - FieldTextValue, //! value as text - FieldFrameValue, //! frame encoded value in network byte order - FieldBitSize, //! size in bits - }; + enum FieldAttrib { + FieldName, //! name + FieldValue, //! value in host byte order (user editable) + FieldTextValue, //! value as text + FieldFrameValue, //! frame encoded value in network byte order + FieldBitSize, //! size in bits + }; - enum ProtocolIdType { - ProtocolIdNone, - ProtocolIdLlc, - ProtocolIdEth, - ProtocolIdIp, - }; + enum ProtocolIdType { + ProtocolIdNone, + ProtocolIdLlc, + ProtocolIdEth, + ProtocolIdIp, + }; - enum CksumType { - CksumIp, - CksumIpPseudo, - CksumTcpUdp, + enum CksumType { + CksumIp, + CksumIpPseudo, + CksumTcpUdp, - CksumMax - }; + CksumMax + }; - AbstractProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~AbstractProtocol(); + AbstractProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~AbstractProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const = 0; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) = 0; + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const = 0; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) = 0; - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; - virtual ProtocolIdType protocolIdType() const; - virtual quint32 protocolId(ProtocolIdType type) const; - quint32 payloadProtocolId(ProtocolIdType type) const; + virtual ProtocolIdType protocolIdType() const; + virtual quint32 protocolId(ProtocolIdType type) const; + quint32 payloadProtocolId(ProtocolIdType type) const; - virtual int fieldCount() const; - int metaFieldCount() const; - int frameFieldCount() const; + virtual int fieldCount() const; + int metaFieldCount() const; + int frameFieldCount() const; - virtual FieldFlags fieldFlags(int index) const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - QByteArray protocolFrameValue(int streamIndex = 0, - bool forCksum = false) const; - virtual int protocolFrameSize(int streamIndex = 0) const; - int protocolFrameOffset(int streamIndex = 0) const; - int protocolFramePayloadSize(int streamIndex = 0) const; + QByteArray protocolFrameValue(int streamIndex = 0, + bool forCksum = false) const; + virtual int protocolFrameSize(int streamIndex = 0) const; + int protocolFrameOffset(int streamIndex = 0) const; + int protocolFramePayloadSize(int streamIndex = 0) const; - virtual bool isProtocolFrameValueVariable() const; - virtual bool isProtocolFrameSizeVariable() const; - bool isProtocolFramePayloadValueVariable() const; - bool isProtocolFramePayloadSizeVariable() const; + virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameSizeVariable() const; + bool isProtocolFramePayloadValueVariable() const; + bool isProtocolFramePayloadSizeVariable() const; - virtual quint32 protocolFrameCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; - quint32 protocolFrameHeaderCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; - quint32 protocolFramePayloadCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFrameHeaderCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFramePayloadCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; - virtual QWidget* configWidget() = 0; - virtual void loadConfigWidget() = 0; - virtual void storeConfigWidget() = 0; + virtual QWidget* configWidget() = 0; + virtual void loadConfigWidget() = 0; + virtual void storeConfigWidget() = 0; }; Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractProtocol::FieldFlags); diff --git a/common/comboprotocol.h b/common/comboprotocol.h index dbfd682..9d10348 100644 --- a/common/comboprotocol.h +++ b/common/comboprotocol.h @@ -7,185 +7,185 @@ template class ComboProtocol : public AbstractProtocol { private: - ProtoA *protoA; - ProtoB *protoB; - QWidget *configForm; + ProtoA *protoA; + ProtoB *protoB; + QWidget *configForm; public: - ComboProtocol(StreamBase *stream, AbstractProtocol *parent = 0) - : AbstractProtocol(stream, parent) - { - protoA = new ProtoA(stream, this); - protoB = new ProtoB(stream, this); - protoA->next = protoB; - protoB->prev = protoA; - configForm = NULL; + ComboProtocol(StreamBase *stream, AbstractProtocol *parent = 0) + : AbstractProtocol(stream, parent) + { + protoA = new ProtoA(stream, this); + protoB = new ProtoB(stream, this); + protoA->next = protoB; + protoB->prev = protoA; + configForm = NULL; - qDebug("%s: protoNumber = %d, %p <--> %p", __FUNCTION__, - protoNumber, protoA, protoB); - } + qDebug("%s: protoNumber = %d, %p <--> %p", __FUNCTION__, + protoNumber, protoA, protoB); + } - virtual ~ComboProtocol() - { - if (configForm) - { - protoA->configWidget()->setParent(0); - protoB->configWidget()->setParent(0); - delete configForm; - } - delete protoA; - delete protoB; - } + virtual ~ComboProtocol() + { + if (configForm) + { + protoA->configWidget()->setParent(0); + protoB->configWidget()->setParent(0); + delete configForm; + } + delete protoA; + delete protoB; + } - static ComboProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent) - { - return new ComboProtocol(stream, parent); - } + static ComboProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent) + { + return new ComboProtocol(stream, parent); + } - virtual quint32 protocolNumber() const - { - return protoNumber; - } + virtual quint32 protocolNumber() const + { + return protoNumber; + } - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const - { - protoA->protoDataCopyInto(protocol); - protoB->protoDataCopyInto(protocol); - protocol.mutable_protocol_id()->set_id(protocolNumber()); - } + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const + { + protoA->protoDataCopyInto(protocol); + protoB->protoDataCopyInto(protocol); + protocol.mutable_protocol_id()->set_id(protocolNumber()); + } - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) - { - if (protocol.protocol_id().id() == protocolNumber()) - { - OstProto::Protocol proto; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) + { + if (protocol.protocol_id().id() == protocolNumber()) + { + OstProto::Protocol proto; - // NOTE: To use protoX->protoDataCopyFrom() we need to arrange - // so that it sees its own protocolNumber() - but since the - // input param 'protocol' is 'const', we make a copy first + // NOTE: To use protoX->protoDataCopyFrom() we need to arrange + // so that it sees its own protocolNumber() - but since the + // input param 'protocol' is 'const', we make a copy first - proto.CopyFrom(protocol); + proto.CopyFrom(protocol); - proto.mutable_protocol_id()->set_id(protoA->protocolNumber()); - protoA->protoDataCopyFrom(proto); + proto.mutable_protocol_id()->set_id(protoA->protocolNumber()); + protoA->protoDataCopyFrom(proto); - proto.mutable_protocol_id()->set_id(protoB->protocolNumber()); - protoB->protoDataCopyFrom(proto); - } - } + proto.mutable_protocol_id()->set_id(protoB->protocolNumber()); + protoB->protoDataCopyFrom(proto); + } + } - virtual QString name() const - { - return protoA->name() + "/" + protoB->name(); - } - virtual QString shortName() const - { - return protoA->shortName() + "/" + protoB->shortName(); - } + virtual QString name() const + { + return protoA->name() + "/" + protoB->name(); + } + virtual QString shortName() const + { + return protoA->shortName() + "/" + protoB->shortName(); + } - virtual ProtocolIdType protocolIdType() const - { - return protoB->protocolIdType(); - } + virtual ProtocolIdType protocolIdType() const + { + return protoB->protocolIdType(); + } - virtual quint32 protocolId(ProtocolIdType type) const - { - return protoA->protocolId(type); - } - //quint32 payloadProtocolId(ProtocolIdType type) const; + virtual quint32 protocolId(ProtocolIdType type) const + { + return protoA->protocolId(type); + } + //quint32 payloadProtocolId(ProtocolIdType type) const; - virtual int fieldCount() const - { - return protoA->fieldCount() + protoB->fieldCount(); - } - //virtual int metaFieldCount() const; - //int frameFieldCount() const; + virtual int fieldCount() const + { + return protoA->fieldCount() + protoB->fieldCount(); + } + //virtual int metaFieldCount() const; + //int frameFieldCount() const; - virtual FieldFlags fieldFlags(int index) const - { - int cnt = protoA->fieldCount(); + virtual FieldFlags fieldFlags(int index) const + { + int cnt = protoA->fieldCount(); - if (index < cnt) - return protoA->fieldFlags(index); - else - return protoB->fieldFlags(index - cnt); - } - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const - { - int cnt = protoA->fieldCount(); + if (index < cnt) + return protoA->fieldFlags(index); + else + return protoB->fieldFlags(index - cnt); + } + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const + { + int cnt = protoA->fieldCount(); - if (index < cnt) - return protoA->fieldData(index, attrib, streamIndex); - else - return protoB->fieldData(index - cnt, attrib, streamIndex); - } - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue) - { - int cnt = protoA->fieldCount(); + if (index < cnt) + return protoA->fieldData(index, attrib, streamIndex); + else + return protoB->fieldData(index - cnt, attrib, streamIndex); + } + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue) + { + int cnt = protoA->fieldCount(); - if (index < cnt) - return protoA->setFieldData(index, value, attrib); - else - return protoB->setFieldData(index - cnt, value, attrib); - } + if (index < cnt) + return protoA->setFieldData(index, value, attrib); + else + return protoB->setFieldData(index - cnt, value, attrib); + } #if 0 - QByteArray protocolFrameValue(int streamIndex = 0, - bool forCksum = false) const; - virtual int protocolFrameSize() const; - int protocolFrameOffset() const; - int protocolFramePayloadSize() const; + QByteArray protocolFrameValue(int streamIndex = 0, + bool forCksum = false) const; + virtual int protocolFrameSize() const; + int protocolFrameOffset() const; + int protocolFramePayloadSize() const; #endif - virtual bool isProtocolFrameValueVariable() const - { - return (protoA->isProtocolFrameValueVariable() - || protoB->isProtocolFrameValueVariable()); - } + virtual bool isProtocolFrameValueVariable() const + { + return (protoA->isProtocolFrameValueVariable() + || protoB->isProtocolFrameValueVariable()); + } - virtual bool isProtocolFrameSizeVariable() const - { - return (protoA->isProtocolFrameSizeVariable() - || protoB->isProtocolFrameSizeVariable()); - } + virtual bool isProtocolFrameSizeVariable() const + { + return (protoA->isProtocolFrameSizeVariable() + || protoB->isProtocolFrameSizeVariable()); + } #if 0 - virtual quint32 protocolFrameCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; - quint32 protocolFrameHeaderCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; - quint32 protocolFramePayloadCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFrameHeaderCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFramePayloadCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; #endif - virtual QWidget* configWidget() - { - if (configForm == NULL) - { - QVBoxLayout *layout = new QVBoxLayout; + virtual QWidget* configWidget() + { + if (configForm == NULL) + { + QVBoxLayout *layout = new QVBoxLayout; - configForm = new QWidget; - layout->addWidget(protoA->configWidget()); - layout->addWidget(protoB->configWidget()); - layout->setSpacing(0); - layout->setContentsMargins(0, 0, 0, 0); - configForm->setLayout(layout); - } - return configForm; - } - virtual void loadConfigWidget() - { - protoA->loadConfigWidget(); - protoB->loadConfigWidget(); - } - virtual void storeConfigWidget() - { - protoA->storeConfigWidget(); - protoB->storeConfigWidget(); - } + configForm = new QWidget; + layout->addWidget(protoA->configWidget()); + layout->addWidget(protoB->configWidget()); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + configForm->setLayout(layout); + } + return configForm; + } + virtual void loadConfigWidget() + { + protoA->loadConfigWidget(); + protoB->loadConfigWidget(); + } + virtual void storeConfigWidget() + { + protoA->storeConfigWidget(); + protoB->storeConfigWidget(); + } }; #endif diff --git a/common/dot2llc.h b/common/dot2llc.h index 1553549..44f6a3b 100644 --- a/common/dot2llc.h +++ b/common/dot2llc.h @@ -6,6 +6,6 @@ #include "llc.h" typedef ComboProtocol Dot2LlcProtocol; + Dot3Protocol, LlcProtocol> Dot2LlcProtocol; #endif diff --git a/common/dot2llc.proto b/common/dot2llc.proto index 3aa1ca4..51eb756 100644 --- a/common/dot2llc.proto +++ b/common/dot2llc.proto @@ -6,9 +6,9 @@ package OstProto; // 802.2 LLC message Dot2Llc { - // Empty since this is a 'combo' protocol + // Empty since this is a 'combo' protocol } extend Protocol { - optional Dot2Llc dot2Llc = 127; + optional Dot2Llc dot2Llc = 127; } diff --git a/common/dot2snap.h b/common/dot2snap.h index 3eee505..2ad3ead 100644 --- a/common/dot2snap.h +++ b/common/dot2snap.h @@ -6,6 +6,6 @@ #include "snap.h" typedef ComboProtocol Dot2SnapProtocol; + Dot2LlcProtocol, SnapProtocol> Dot2SnapProtocol; #endif diff --git a/common/dot2snap.proto b/common/dot2snap.proto index b9a03f5..ce41b8f 100644 --- a/common/dot2snap.proto +++ b/common/dot2snap.proto @@ -4,9 +4,9 @@ package OstProto; // 802.2 SNAP message Dot2Snap { - // Empty since this is a 'combo' protocol + // Empty since this is a 'combo' protocol } extend Protocol { - optional Dot2Snap dot2Snap = 128; + optional Dot2Snap dot2Snap = 128; } diff --git a/common/dot3.cpp b/common/dot3.cpp index ac2a878..ddf58a8 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -4,150 +4,150 @@ #include "dot3.h" #include "streambase.h" -#define SZ_FCS 4 +#define SZ_FCS 4 Dot3ConfigForm::Dot3ConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); } Dot3Protocol::Dot3Protocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } Dot3Protocol::~Dot3Protocol() { - delete configForm; + delete configForm; } AbstractProtocol* Dot3Protocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new Dot3Protocol(stream, parent); + return new Dot3Protocol(stream, parent); } quint32 Dot3Protocol::protocolNumber() const { - return OstProto::Protocol::kDot3FieldNumber; + return OstProto::Protocol::kDot3FieldNumber; } void Dot3Protocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::dot3)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::dot3)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void Dot3Protocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::dot3)) - data.MergeFrom(protocol.GetExtension(OstProto::dot3)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::dot3)) + data.MergeFrom(protocol.GetExtension(OstProto::dot3)); } QString Dot3Protocol::name() const { - return QString("802.3"); + return QString("802.3"); } QString Dot3Protocol::shortName() const { - return QString("802.3"); + return QString("802.3"); } -int Dot3Protocol::fieldCount() const +int Dot3Protocol::fieldCount() const { - return dot3_fieldCount; + return dot3_fieldCount; } QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case dot3_length: - switch(attrib) - { - case FieldName: - return QString("Length"); - case FieldValue: - { - quint16 len; + switch (index) + { + case dot3_length: + switch(attrib) + { + case FieldName: + return QString("Length"); + case FieldValue: + { + quint16 len; - //len = mpStream->frameLen() - SZ_FCS; - len = protocolFramePayloadSize(streamIndex); - return len; - } - case FieldTextValue: - { - quint16 len; + //len = mpStream->frameLen() - SZ_FCS; + len = protocolFramePayloadSize(streamIndex); + return len; + } + case FieldTextValue: + { + quint16 len; - //len = mpStream->frameLen() - SZ_FCS; - len = protocolFramePayloadSize(streamIndex); - return QString("%1").arg(len); - } - case FieldFrameValue: - { - quint16 len; - QByteArray fv; + //len = mpStream->frameLen() - SZ_FCS; + len = protocolFramePayloadSize(streamIndex); + return QString("%1").arg(len); + } + case FieldFrameValue: + { + quint16 len; + QByteArray fv; - //len = mpStream->frameLen() - SZ_FCS; - len = protocolFramePayloadSize(streamIndex); - fv.resize(2); - qToBigEndian(len, (uchar*) fv.data()); - return fv; - } - case FieldBitSize: - return 16; - default: - break; - } - break; + //len = mpStream->frameLen() - SZ_FCS; + len = protocolFramePayloadSize(streamIndex); + fv.resize(2); + qToBigEndian(len, (uchar*) fv.data()); + return fv; + } + case FieldBitSize: + return 16; + default: + break; + } + break; - default: - break; - } + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool Dot3Protocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - return false; + return false; } bool Dot3Protocol::isProtocolFrameValueVariable() const { - return isProtocolFramePayloadSizeVariable(); + return isProtocolFramePayloadSizeVariable(); } QWidget* Dot3Protocol::configWidget() { - if (configForm == NULL) - { - configForm = new Dot3ConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new Dot3ConfigForm; + loadConfigWidget(); + } + return configForm; } void Dot3Protocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->leLength->setText( - fieldData(dot3_length, FieldValue).toString()); + configForm->leLength->setText( + fieldData(dot3_length, FieldValue).toString()); } void Dot3Protocol::storeConfigWidget() { - bool isOk; + bool isOk; - configWidget(); + configWidget(); - data.set_length(configForm->leLength->text().toULong(&isOk)); + data.set_length(configForm->leLength->text().toULong(&isOk)); } diff --git a/common/dot3.h b/common/dot3.h index 9e0e8c1..af045db 100644 --- a/common/dot3.h +++ b/common/dot3.h @@ -8,49 +8,49 @@ class Dot3ConfigForm : public QWidget, public Ui::dot3 { - Q_OBJECT + Q_OBJECT public: - Dot3ConfigForm(QWidget *parent = 0); + Dot3ConfigForm(QWidget *parent = 0); }; class Dot3Protocol : public AbstractProtocol { private: - OstProto::Dot3 data; - Dot3ConfigForm *configForm; - enum Dot3field - { - dot3_length, + OstProto::Dot3 data; + Dot3ConfigForm *configForm; + enum Dot3field + { + dot3_length, - dot3_fieldCount - }; + dot3_fieldCount + }; public: - Dot3Protocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~Dot3Protocol(); + Dot3Protocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~Dot3Protocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameValueVariable() const; - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/dot3.proto b/common/dot3.proto index 5a84c18..154f554 100644 --- a/common/dot3.proto +++ b/common/dot3.proto @@ -4,9 +4,9 @@ package OstProto; // 802.3 message Dot3 { - optional uint32 length = 1; + optional uint32 length = 1; } extend Protocol { - optional Dot3 dot3 = 122; + optional Dot3 dot3 = 122; } diff --git a/common/eth2.cpp b/common/eth2.cpp index 0028b51..2939fed 100644 --- a/common/eth2.cpp +++ b/common/eth2.cpp @@ -4,150 +4,150 @@ #include "eth2.h" Eth2ConfigForm::Eth2ConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); } Eth2Protocol::Eth2Protocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } Eth2Protocol::~Eth2Protocol() { - delete configForm; + delete configForm; } AbstractProtocol* Eth2Protocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new Eth2Protocol(stream, parent); + return new Eth2Protocol(stream, parent); } quint32 Eth2Protocol::protocolNumber() const { - return OstProto::Protocol::kEth2FieldNumber; + return OstProto::Protocol::kEth2FieldNumber; } void Eth2Protocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::eth2)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::eth2)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void Eth2Protocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::eth2)) - data.MergeFrom(protocol.GetExtension(OstProto::eth2)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::eth2)) + data.MergeFrom(protocol.GetExtension(OstProto::eth2)); } QString Eth2Protocol::name() const { - return QString("Ethernet II"); + return QString("Ethernet II"); } QString Eth2Protocol::shortName() const { - return QString("Eth II"); + return QString("Eth II"); } AbstractProtocol::ProtocolIdType Eth2Protocol::protocolIdType() const { - return ProtocolIdEth; + return ProtocolIdEth; } -int Eth2Protocol::fieldCount() const +int Eth2Protocol::fieldCount() const { - return eth2_fieldCount; + return eth2_fieldCount; } QVariant Eth2Protocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case eth2_type: - { - quint16 type; - switch(attrib) - { - case FieldName: - return QString("Type"); - case FieldValue: - type = payloadProtocolId(ProtocolIdEth); - return type; - case FieldTextValue: - type = payloadProtocolId(ProtocolIdEth); - return QString("0x%1").arg(type, 4, BASE_HEX, QChar('0')); - case FieldFrameValue: - { - QByteArray fv; - type = payloadProtocolId(ProtocolIdEth); - fv.resize(2); - qToBigEndian((quint16) type, (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; - } - default: - break; - } + switch (index) + { + case eth2_type: + { + quint16 type; + switch(attrib) + { + case FieldName: + return QString("Type"); + case FieldValue: + type = payloadProtocolId(ProtocolIdEth); + return type; + case FieldTextValue: + type = payloadProtocolId(ProtocolIdEth); + return QString("0x%1").arg(type, 4, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + type = payloadProtocolId(ProtocolIdEth); + fv.resize(2); + qToBigEndian((quint16) type, (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool Eth2Protocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - bool isOk = false; + bool isOk = false; - if (attrib != FieldValue) - return false; + if (attrib != FieldValue) + return false; - switch (index) - { - case eth2_type: - { - uint type = value.toUInt(&isOk); - if (isOk) - data.set_type(type); - } - default: - break; - } - return isOk; + switch (index) + { + case eth2_type: + { + uint type = value.toUInt(&isOk); + if (isOk) + data.set_type(type); + } + default: + break; + } + return isOk; } QWidget* Eth2Protocol::configWidget() { - if (configForm == NULL) - { - configForm = new Eth2ConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new Eth2ConfigForm; + loadConfigWidget(); + } + return configForm; } void Eth2Protocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->leType->setText(uintToHexStr( - fieldData(eth2_type, FieldValue).toUInt(), 2)); + configForm->leType->setText(uintToHexStr( + fieldData(eth2_type, FieldValue).toUInt(), 2)); } void Eth2Protocol::storeConfigWidget() { - bool isOk; + bool isOk; - configWidget(); + configWidget(); - data.set_type(configForm->leType->text().remove(QChar(' ')).toULong(&isOk, 16)); + data.set_type(configForm->leType->text().remove(QChar(' ')).toULong(&isOk, 16)); } diff --git a/common/eth2.h b/common/eth2.h index fcf6b7d..cae1bb3 100644 --- a/common/eth2.h +++ b/common/eth2.h @@ -8,49 +8,49 @@ class Eth2ConfigForm : public QWidget, public Ui::eth2 { - Q_OBJECT + Q_OBJECT public: - Eth2ConfigForm(QWidget *parent = 0); + Eth2ConfigForm(QWidget *parent = 0); }; class Eth2Protocol : public AbstractProtocol { private: - OstProto::Eth2 data; - Eth2ConfigForm *configForm; - enum eth2field - { - eth2_type = 0, + OstProto::Eth2 data; + Eth2ConfigForm *configForm; + enum eth2field + { + eth2_type = 0, - eth2_fieldCount - }; + eth2_fieldCount + }; public: - Eth2Protocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~Eth2Protocol(); + Eth2Protocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~Eth2Protocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; - virtual ProtocolIdType protocolIdType() const; + virtual ProtocolIdType protocolIdType() const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/eth2.proto b/common/eth2.proto index 348888d..c5339a9 100644 --- a/common/eth2.proto +++ b/common/eth2.proto @@ -4,9 +4,9 @@ package OstProto; // Ethernet II message Eth2 { - optional uint32 type = 1; + optional uint32 type = 1; } extend Protocol { - optional Eth2 eth2 = 121; + optional Eth2 eth2 = 121; } diff --git a/common/ip4.cpp b/common/ip4.cpp index 4c28bfb..c2594f3 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -4,704 +4,704 @@ #include "ip4.h" Ip4ConfigForm::Ip4ConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); - leIpVersion->setValidator(new QIntValidator(0, 15, this)); + leIpVersion->setValidator(new QIntValidator(0, 15, this)); - connect(cmbIpSrcAddrMode, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_cmbIpSrcAddrMode_currentIndexChanged(int))); - connect(cmbIpDstAddrMode, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_cmbIpDstAddrMode_currentIndexChanged(int))); + connect(cmbIpSrcAddrMode, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_cmbIpSrcAddrMode_currentIndexChanged(int))); + connect(cmbIpDstAddrMode, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_cmbIpDstAddrMode_currentIndexChanged(int))); } Ip4ConfigForm::~Ip4ConfigForm() { - qDebug("IPv4 Config Form destructor called"); + qDebug("IPv4 Config Form destructor called"); } void Ip4ConfigForm::on_cmbIpSrcAddrMode_currentIndexChanged(int index) { - if (index == OstProto::Ip4::e_im_fixed) - { - leIpSrcAddrCount->setDisabled(true); - leIpSrcAddrMask->setDisabled(true); - } - else - { - leIpSrcAddrCount->setEnabled(true); - leIpSrcAddrMask->setEnabled(true); - } + if (index == OstProto::Ip4::e_im_fixed) + { + leIpSrcAddrCount->setDisabled(true); + leIpSrcAddrMask->setDisabled(true); + } + else + { + leIpSrcAddrCount->setEnabled(true); + leIpSrcAddrMask->setEnabled(true); + } } void Ip4ConfigForm::on_cmbIpDstAddrMode_currentIndexChanged(int index) { - if (index == OstProto::Ip4::e_im_fixed) - { - leIpDstAddrCount->setDisabled(true); - leIpDstAddrMask->setDisabled(true); - } - else - { - leIpDstAddrCount->setEnabled(true); - leIpDstAddrMask->setEnabled(true); - } + if (index == OstProto::Ip4::e_im_fixed) + { + leIpDstAddrCount->setDisabled(true); + leIpDstAddrMask->setDisabled(true); + } + else + { + leIpDstAddrCount->setEnabled(true); + leIpDstAddrMask->setEnabled(true); + } } Ip4Protocol::Ip4Protocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } Ip4Protocol::~Ip4Protocol() { - delete configForm; + delete configForm; } AbstractProtocol* Ip4Protocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new Ip4Protocol(stream, parent); + return new Ip4Protocol(stream, parent); } quint32 Ip4Protocol::protocolNumber() const { - return OstProto::Protocol::kIp4FieldNumber; + return OstProto::Protocol::kIp4FieldNumber; } void Ip4Protocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::ip4)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::ip4)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void Ip4Protocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::ip4)) - data.MergeFrom(protocol.GetExtension(OstProto::ip4)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::ip4)) + data.MergeFrom(protocol.GetExtension(OstProto::ip4)); } QString Ip4Protocol::name() const { - return QString("Internet Protocol ver 4"); + return QString("Internet Protocol ver 4"); } QString Ip4Protocol::shortName() const { - return QString("IPv4"); + return QString("IPv4"); } AbstractProtocol::ProtocolIdType Ip4Protocol::protocolIdType() const { - return ProtocolIdIp; + return ProtocolIdIp; } quint32 Ip4Protocol::protocolId(ProtocolIdType type) const { - switch(type) - { - case ProtocolIdLlc: return 0x060603; - case ProtocolIdEth: return 0x0800; - case ProtocolIdIp: return 0x04; - default:break; - } + switch(type) + { + case ProtocolIdLlc: return 0x060603; + case ProtocolIdEth: return 0x0800; + case ProtocolIdIp: return 0x04; + default:break; + } - return AbstractProtocol::protocolId(type); + return AbstractProtocol::protocolId(type); } -int Ip4Protocol::fieldCount() const +int Ip4Protocol::fieldCount() const { - return ip4_fieldCount; + return ip4_fieldCount; } AbstractProtocol::FieldFlags Ip4Protocol::fieldFlags(int index) const { - AbstractProtocol::FieldFlags flags; + AbstractProtocol::FieldFlags flags; - flags = AbstractProtocol::fieldFlags(index); + flags = AbstractProtocol::fieldFlags(index); - switch (index) - { - case ip4_ver: - case ip4_hdrLen: - case ip4_tos: - case ip4_totLen: - case ip4_id: - case ip4_flags: - case ip4_fragOfs: - case ip4_ttl: - case ip4_proto: - break; + switch (index) + { + case ip4_ver: + case ip4_hdrLen: + case ip4_tos: + case ip4_totLen: + case ip4_id: + case ip4_flags: + case ip4_fragOfs: + case ip4_ttl: + case ip4_proto: + break; - case ip4_cksum: - flags |= FieldIsCksum; - break; + case ip4_cksum: + flags |= FieldIsCksum; + break; - case ip4_srcAddr: - case ip4_dstAddr: - break; + case ip4_srcAddr: + case ip4_dstAddr: + break; - case ip4_isOverrideVer: - case ip4_isOverrideHdrLen: - case ip4_isOverrideTotLen: - case ip4_isOverrideCksum: - case ip4_srcAddrMode: - case ip4_srcAddrCount: - case ip4_srcAddrMask: - case ip4_dstAddrMode: - case ip4_dstAddrCount: - case ip4_dstAddrMask: - flags |= FieldIsMeta; - break; + case ip4_isOverrideVer: + case ip4_isOverrideHdrLen: + case ip4_isOverrideTotLen: + case ip4_isOverrideCksum: + case ip4_srcAddrMode: + case ip4_srcAddrCount: + case ip4_srcAddrMask: + case ip4_dstAddrMode: + case ip4_dstAddrCount: + case ip4_dstAddrMask: + flags |= FieldIsMeta; + break; - default: - break; - } + default: + break; + } - return flags; + return flags; } QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case ip4_ver: - { - int ver; + switch (index) + { + case ip4_ver: + { + int ver; - ver = data.is_override_ver() ? (data.ver_hdrlen() >> 4) & 0x0F : 4; + ver = data.is_override_ver() ? (data.ver_hdrlen() >> 4) & 0x0F : 4; - switch(attrib) - { - case FieldName: - return QString("Version"); - case FieldValue: - return ver; - case FieldTextValue: - return QString("%1").arg(ver, 1, BASE_HEX, QChar('0')); - case FieldFrameValue: - return QByteArray(1, (char) ver); - case FieldBitSize: - return 4; - default: - break; - } - break; - } - case ip4_hdrLen: - { - int hdrlen; + switch(attrib) + { + case FieldName: + return QString("Version"); + case FieldValue: + return ver; + case FieldTextValue: + return QString("%1").arg(ver, 1, BASE_HEX, QChar('0')); + case FieldFrameValue: + return QByteArray(1, (char) ver); + case FieldBitSize: + return 4; + default: + break; + } + break; + } + case ip4_hdrLen: + { + int hdrlen; - hdrlen = data.is_override_hdrlen() ? data.ver_hdrlen() & 0x0F : 5; + hdrlen = data.is_override_hdrlen() ? data.ver_hdrlen() & 0x0F : 5; - switch(attrib) - { - case FieldName: - return QString("Header Length"); - case FieldValue: - return hdrlen; - case FieldTextValue: - return QString("%1").arg(hdrlen, 1, BASE_HEX, QChar('0')); - case FieldFrameValue: - return QByteArray(1, (char) hdrlen); - case FieldBitSize: - return 4; - default: - break; - } - break; - } - case ip4_tos: - switch(attrib) - { - case FieldName: - return QString("TOS/DSCP"); - case FieldValue: - return data.tos(); - case FieldFrameValue: - return QByteArray(1, (char) data.tos()); - case FieldTextValue: - return QString("0x%1"). - arg(data.tos(), 2, BASE_HEX, QChar('0'));; - default: - break; - } - break; - case ip4_totLen: - { - switch(attrib) - { - case FieldName: - return QString("Total Length"); - case FieldValue: - { - int totlen; - totlen = data.is_override_totlen() ? data.totlen() : - (protocolFramePayloadSize(streamIndex) + 20); - return totlen; - } - case FieldFrameValue: - { - QByteArray fv; - int totlen; - totlen = data.is_override_totlen() ? data.totlen() : - (protocolFramePayloadSize(streamIndex) + 20); - fv.resize(2); - qToBigEndian((quint16) totlen, (uchar*) fv.data()); - return fv; - } - case FieldTextValue: - { - int totlen; - totlen = data.is_override_totlen() ? data.totlen() : - (protocolFramePayloadSize(streamIndex) + 20); - return QString("%1").arg(totlen); - } - case FieldBitSize: - return 16; - default: - break; - } - break; - } - case ip4_id: - switch(attrib) - { - case FieldName: - return QString("Identification"); - case FieldValue: - return data.id(); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) data.id(), (uchar*)fv.data()); - return fv; - } - case FieldTextValue: - return QString("0x%1"). - arg(data.id(), 2, BASE_HEX, QChar('0'));; - default: - break; - } - break; - case ip4_flags: - switch(attrib) - { - case FieldName: - return QString("Flags"); - case FieldValue: - return data.flags(); - case FieldFrameValue: - return QByteArray(1, (char) data.flags()); - case FieldTextValue: - { - QString s; - s.append("Unused:"); - s.append(data.flags() & IP_FLAG_UNUSED ? "1" : "0"); - s.append(" Don't Fragment:"); - s.append(data.flags() & IP_FLAG_DF ? "1" : "0"); - s.append(" More Fragments:"); - s.append(data.flags() & IP_FLAG_MF ? "1" : "0"); - return s; - } - case FieldBitSize: - return 3; - default: - break; - } - break; - case ip4_fragOfs: - switch(attrib) - { - case FieldName: - return QString("Fragment Offset"); - case FieldValue: - return data.frag_ofs(); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) (data.frag_ofs()), - (uchar*) fv.data()); - return fv; - } - case FieldTextValue: - return QString("%1").arg(data.frag_ofs()*8); - case FieldBitSize: - return 13; - default: - break; - } - break; - case ip4_ttl: - switch(attrib) - { - case FieldName: - return QString("Time to Live"); - case FieldValue: - return data.ttl(); - case FieldFrameValue: - return QByteArray(1, (char)data.ttl()); - case FieldTextValue: - return QString("%1").arg(data.ttl()); - default: - break; - } - break; - case ip4_proto: - { - switch(attrib) - { - case FieldName: - return QString("Protocol"); - case FieldValue: - { - unsigned char id = payloadProtocolId(ProtocolIdIp); - return id; - } - case FieldFrameValue: - { - unsigned char id = payloadProtocolId(ProtocolIdIp); - return QByteArray(1, (char) id); - } - case FieldTextValue: - { - unsigned char id = payloadProtocolId(ProtocolIdIp); - return QString("0x%1"). - arg(id, 2, BASE_HEX, QChar('0')); - } - default: - break; - } - break; - } - case ip4_cksum: - { - switch(attrib) - { - case FieldName: - return QString("Header Checksum"); - case FieldValue: - { - quint16 cksum; + switch(attrib) + { + case FieldName: + return QString("Header Length"); + case FieldValue: + return hdrlen; + case FieldTextValue: + return QString("%1").arg(hdrlen, 1, BASE_HEX, QChar('0')); + case FieldFrameValue: + return QByteArray(1, (char) hdrlen); + case FieldBitSize: + return 4; + default: + break; + } + break; + } + case ip4_tos: + switch(attrib) + { + case FieldName: + return QString("TOS/DSCP"); + case FieldValue: + return data.tos(); + case FieldFrameValue: + return QByteArray(1, (char) data.tos()); + case FieldTextValue: + return QString("0x%1"). + arg(data.tos(), 2, BASE_HEX, QChar('0'));; + default: + break; + } + break; + case ip4_totLen: + { + switch(attrib) + { + case FieldName: + return QString("Total Length"); + case FieldValue: + { + int totlen; + totlen = data.is_override_totlen() ? data.totlen() : + (protocolFramePayloadSize(streamIndex) + 20); + return totlen; + } + case FieldFrameValue: + { + QByteArray fv; + int totlen; + totlen = data.is_override_totlen() ? data.totlen() : + (protocolFramePayloadSize(streamIndex) + 20); + fv.resize(2); + qToBigEndian((quint16) totlen, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + { + int totlen; + totlen = data.is_override_totlen() ? data.totlen() : + (protocolFramePayloadSize(streamIndex) + 20); + return QString("%1").arg(totlen); + } + case FieldBitSize: + return 16; + default: + break; + } + break; + } + case ip4_id: + switch(attrib) + { + case FieldName: + return QString("Identification"); + case FieldValue: + return data.id(); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.id(), (uchar*)fv.data()); + return fv; + } + case FieldTextValue: + return QString("0x%1"). + arg(data.id(), 2, BASE_HEX, QChar('0'));; + default: + break; + } + break; + case ip4_flags: + switch(attrib) + { + case FieldName: + return QString("Flags"); + case FieldValue: + return data.flags(); + case FieldFrameValue: + return QByteArray(1, (char) data.flags()); + case FieldTextValue: + { + QString s; + s.append("Unused:"); + s.append(data.flags() & IP_FLAG_UNUSED ? "1" : "0"); + s.append(" Don't Fragment:"); + s.append(data.flags() & IP_FLAG_DF ? "1" : "0"); + s.append(" More Fragments:"); + s.append(data.flags() & IP_FLAG_MF ? "1" : "0"); + return s; + } + case FieldBitSize: + return 3; + default: + break; + } + break; + case ip4_fragOfs: + switch(attrib) + { + case FieldName: + return QString("Fragment Offset"); + case FieldValue: + return data.frag_ofs(); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) (data.frag_ofs()), + (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("%1").arg(data.frag_ofs()*8); + case FieldBitSize: + return 13; + default: + break; + } + break; + case ip4_ttl: + switch(attrib) + { + case FieldName: + return QString("Time to Live"); + case FieldValue: + return data.ttl(); + case FieldFrameValue: + return QByteArray(1, (char)data.ttl()); + case FieldTextValue: + return QString("%1").arg(data.ttl()); + default: + break; + } + break; + case ip4_proto: + { + switch(attrib) + { + case FieldName: + return QString("Protocol"); + case FieldValue: + { + unsigned char id = payloadProtocolId(ProtocolIdIp); + return id; + } + case FieldFrameValue: + { + unsigned char id = payloadProtocolId(ProtocolIdIp); + return QByteArray(1, (char) id); + } + case FieldTextValue: + { + unsigned char id = payloadProtocolId(ProtocolIdIp); + return QString("0x%1"). + arg(id, 2, BASE_HEX, QChar('0')); + } + default: + break; + } + break; + } + case ip4_cksum: + { + switch(attrib) + { + case FieldName: + return QString("Header Checksum"); + case FieldValue: + { + quint16 cksum; - if (data.is_override_cksum()) - cksum = data.cksum(); - else - cksum = protocolFrameCksum(streamIndex, CksumIp); - return cksum; - } - case FieldFrameValue: - { - QByteArray fv; - quint16 cksum; + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumIp); + return cksum; + } + case FieldFrameValue: + { + QByteArray fv; + quint16 cksum; - if (data.is_override_cksum()) - cksum = data.cksum(); - else - cksum = protocolFrameCksum(streamIndex, CksumIp); + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumIp); - fv.resize(2); - qToBigEndian((quint16) cksum, (uchar*) fv.data()); - return fv; - } - case FieldTextValue: - { - quint16 cksum; + fv.resize(2); + qToBigEndian((quint16) cksum, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + { + quint16 cksum; - if (data.is_override_cksum()) - cksum = data.cksum(); - else - cksum = protocolFrameCksum(streamIndex, CksumIp); - return QString("0x%1"). - arg(cksum, 4, BASE_HEX, QChar('0'));; - } - case FieldBitSize: - return 16; - default: - break; - } - break; - } - case ip4_srcAddr: - { - int u; - quint32 subnet, host, srcIp = 0; + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumIp); + return QString("0x%1"). + arg(cksum, 4, BASE_HEX, QChar('0'));; + } + case FieldBitSize: + return 16; + default: + break; + } + break; + } + case ip4_srcAddr: + { + int u; + quint32 subnet, host, srcIp = 0; - switch(data.src_ip_mode()) - { - case OstProto::Ip4::e_im_fixed: - srcIp = data.src_ip(); - break; - case OstProto::Ip4::e_im_inc_host: - u = streamIndex % data.src_ip_count(); - subnet = data.src_ip() & data.src_ip_mask(); - host = (((data.src_ip() & ~data.src_ip_mask()) + u) & - ~data.src_ip_mask()); - srcIp = subnet | host; - break; - case OstProto::Ip4::e_im_dec_host: - u = streamIndex % data.src_ip_count(); - subnet = data.src_ip() & data.src_ip_mask(); - host = (((data.src_ip() & ~data.src_ip_mask()) - u) & - ~data.src_ip_mask()); - srcIp = subnet | host; - break; - case OstProto::Ip4::e_im_random_host: - subnet = data.src_ip() & data.src_ip_mask(); - host = (qrand() & ~data.src_ip_mask()); - srcIp = subnet | host; - break; - default: - qWarning("Unhandled src_ip_mode = %d", data.src_ip_mode()); - } + switch(data.src_ip_mode()) + { + case OstProto::Ip4::e_im_fixed: + srcIp = data.src_ip(); + break; + case OstProto::Ip4::e_im_inc_host: + u = streamIndex % data.src_ip_count(); + subnet = data.src_ip() & data.src_ip_mask(); + host = (((data.src_ip() & ~data.src_ip_mask()) + u) & + ~data.src_ip_mask()); + srcIp = subnet | host; + break; + case OstProto::Ip4::e_im_dec_host: + u = streamIndex % data.src_ip_count(); + subnet = data.src_ip() & data.src_ip_mask(); + host = (((data.src_ip() & ~data.src_ip_mask()) - u) & + ~data.src_ip_mask()); + srcIp = subnet | host; + break; + case OstProto::Ip4::e_im_random_host: + subnet = data.src_ip() & data.src_ip_mask(); + host = (qrand() & ~data.src_ip_mask()); + srcIp = subnet | host; + break; + default: + qWarning("Unhandled src_ip_mode = %d", data.src_ip_mode()); + } - switch(attrib) - { - case FieldName: - return QString("Source"); - case FieldValue: - return srcIp; - case FieldFrameValue: - { - QByteArray fv; - fv.resize(4); - qToBigEndian(srcIp, (uchar*) fv.data()); - return fv; - } - case FieldTextValue: - return QHostAddress(srcIp).toString(); - default: - break; - } - break; - } - case ip4_dstAddr: - { - int u; - quint32 subnet, host, dstIp = 0; + switch(attrib) + { + case FieldName: + return QString("Source"); + case FieldValue: + return srcIp; + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian(srcIp, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QHostAddress(srcIp).toString(); + default: + break; + } + break; + } + case ip4_dstAddr: + { + int u; + quint32 subnet, host, dstIp = 0; - switch(data.dst_ip_mode()) - { - case OstProto::Ip4::e_im_fixed: - dstIp = data.dst_ip(); - break; - case OstProto::Ip4::e_im_inc_host: - u = streamIndex % data.dst_ip_count(); - subnet = data.dst_ip() & data.dst_ip_mask(); - host = (((data.dst_ip() & ~data.dst_ip_mask()) + u) & - ~data.dst_ip_mask()); - dstIp = subnet | host; - break; - case OstProto::Ip4::e_im_dec_host: - u = streamIndex % data.dst_ip_count(); - subnet = data.dst_ip() & data.dst_ip_mask(); - host = (((data.dst_ip() & ~data.dst_ip_mask()) - u) & - ~data.dst_ip_mask()); - dstIp = subnet | host; - break; - case OstProto::Ip4::e_im_random_host: - subnet = data.dst_ip() & data.dst_ip_mask(); - host = (qrand() & ~data.dst_ip_mask()); - dstIp = subnet | host; - break; - default: - qWarning("Unhandled dst_ip_mode = %d", data.dst_ip_mode()); - } + switch(data.dst_ip_mode()) + { + case OstProto::Ip4::e_im_fixed: + dstIp = data.dst_ip(); + break; + case OstProto::Ip4::e_im_inc_host: + u = streamIndex % data.dst_ip_count(); + subnet = data.dst_ip() & data.dst_ip_mask(); + host = (((data.dst_ip() & ~data.dst_ip_mask()) + u) & + ~data.dst_ip_mask()); + dstIp = subnet | host; + break; + case OstProto::Ip4::e_im_dec_host: + u = streamIndex % data.dst_ip_count(); + subnet = data.dst_ip() & data.dst_ip_mask(); + host = (((data.dst_ip() & ~data.dst_ip_mask()) - u) & + ~data.dst_ip_mask()); + dstIp = subnet | host; + break; + case OstProto::Ip4::e_im_random_host: + subnet = data.dst_ip() & data.dst_ip_mask(); + host = (qrand() & ~data.dst_ip_mask()); + dstIp = subnet | host; + break; + default: + qWarning("Unhandled dst_ip_mode = %d", data.dst_ip_mode()); + } - switch(attrib) - { - case FieldName: - return QString("Destination"); - case FieldValue: - return dstIp; - case FieldFrameValue: - { - QByteArray fv; - fv.resize(4); - qToBigEndian((quint32) dstIp, (uchar*) fv.data()); - return fv; - } - case FieldTextValue: - return QHostAddress(dstIp).toString(); - default: - break; - } - break; - } - // Meta fields + switch(attrib) + { + case FieldName: + return QString("Destination"); + case FieldValue: + return dstIp; + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) dstIp, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QHostAddress(dstIp).toString(); + default: + break; + } + break; + } + // Meta fields - case ip4_isOverrideVer: - case ip4_isOverrideHdrLen: - case ip4_isOverrideTotLen: - case ip4_isOverrideCksum: + case ip4_isOverrideVer: + case ip4_isOverrideHdrLen: + case ip4_isOverrideTotLen: + case ip4_isOverrideCksum: - case ip4_srcAddrMode: - case ip4_srcAddrCount: - case ip4_srcAddrMask: + case ip4_srcAddrMode: + case ip4_srcAddrCount: + case ip4_srcAddrMask: - case ip4_dstAddrMode: - case ip4_dstAddrCount: - case ip4_dstAddrMask: - default: - break; - } + case ip4_dstAddrMode: + case ip4_dstAddrCount: + case ip4_dstAddrMask: + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool Ip4Protocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - bool isOk = false; + bool isOk = false; - if (attrib != FieldValue) - return false; + if (attrib != FieldValue) + return false; - switch (index) - { - case ip4_proto: - { - uint proto = value.toUInt(&isOk); - if (isOk) - data.set_proto(proto); - } - default: - break; - } - return isOk; + switch (index) + { + case ip4_proto: + { + uint proto = value.toUInt(&isOk); + if (isOk) + data.set_proto(proto); + } + default: + break; + } + return isOk; } bool Ip4Protocol::isProtocolFrameValueVariable() const { - if ((data.src_ip_mode() != OstProto::Ip4::e_im_fixed) - || (data.dst_ip_mode() != OstProto::Ip4::e_im_fixed)) - return true; - else - return false; + if ((data.src_ip_mode() != OstProto::Ip4::e_im_fixed) + || (data.dst_ip_mode() != OstProto::Ip4::e_im_fixed)) + return true; + else + return false; } quint32 Ip4Protocol::protocolFrameCksum(int streamIndex, - CksumType cksumType) const + CksumType cksumType) const { - switch (cksumType) - { - case CksumIpPseudo: - { - quint32 sum; + switch (cksumType) + { + case CksumIpPseudo: + { + quint32 sum; - sum = fieldData(ip4_srcAddr, FieldValue, streamIndex).toUInt() >> 16; - sum += fieldData(ip4_srcAddr, FieldValue, streamIndex).toUInt() & 0xFFFF; - sum += fieldData(ip4_dstAddr, FieldValue, streamIndex).toUInt() >> 16; - sum += fieldData(ip4_dstAddr, FieldValue, streamIndex).toUInt() & 0xFFFF; + sum = fieldData(ip4_srcAddr, FieldValue, streamIndex).toUInt() >> 16; + sum += fieldData(ip4_srcAddr, FieldValue, streamIndex).toUInt() & 0xFFFF; + sum += fieldData(ip4_dstAddr, FieldValue, streamIndex).toUInt() >> 16; + sum += fieldData(ip4_dstAddr, FieldValue, streamIndex).toUInt() & 0xFFFF; - sum += fieldData(ip4_proto, FieldValue, streamIndex).toUInt() & 0x00FF; - sum += (fieldData(ip4_totLen, FieldValue, streamIndex).toUInt() & 0xFFFF) - 20; + sum += fieldData(ip4_proto, FieldValue, streamIndex).toUInt() & 0x00FF; + sum += (fieldData(ip4_totLen, FieldValue, streamIndex).toUInt() & 0xFFFF) - 20; - // Above calculation done assuming 'big endian' - // - so convert to host order - //return qFromBigEndian(sum); - return ~sum; - } - default: - break; - } + // Above calculation done assuming 'big endian' + // - so convert to host order + //return qFromBigEndian(sum); + return ~sum; + } + default: + break; + } - return AbstractProtocol::protocolFrameCksum(streamIndex, cksumType); + return AbstractProtocol::protocolFrameCksum(streamIndex, cksumType); } QWidget* Ip4Protocol::configWidget() { - if (configForm == NULL) - { - configForm = new Ip4ConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new Ip4ConfigForm; + loadConfigWidget(); + } + return configForm; } void Ip4Protocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->cbIpVersionOverride->setChecked(data.is_override_ver()); - configForm->leIpVersion->setText(fieldData(ip4_ver, FieldValue).toString()); + configForm->cbIpVersionOverride->setChecked(data.is_override_ver()); + configForm->leIpVersion->setText(fieldData(ip4_ver, FieldValue).toString()); - configForm->cbIpHdrLenOverride->setChecked(data.is_override_hdrlen()); - configForm->leIpHdrLen->setText(fieldData(ip4_hdrLen, FieldValue).toString()); - - configForm->leIpTos->setText(uintToHexStr(data.tos(), 1)); + configForm->cbIpHdrLenOverride->setChecked(data.is_override_hdrlen()); + configForm->leIpHdrLen->setText(fieldData(ip4_hdrLen, FieldValue).toString()); + + configForm->leIpTos->setText(uintToHexStr(data.tos(), 1)); - configForm->cbIpLengthOverride->setChecked(data.is_override_totlen()); - configForm->leIpLength->setText(fieldData(ip4_totLen, FieldValue).toString()); + configForm->cbIpLengthOverride->setChecked(data.is_override_totlen()); + configForm->leIpLength->setText(fieldData(ip4_totLen, FieldValue).toString()); - configForm->leIpId->setText(uintToHexStr(data.id(), 2)); - configForm->leIpFragOfs->setText(QString().setNum(data.frag_ofs())); - configForm->cbIpFlagsDf->setChecked((data.flags() & IP_FLAG_DF) > 0); - configForm->cbIpFlagsMf->setChecked((data.flags() & IP_FLAG_MF) > 0); + configForm->leIpId->setText(uintToHexStr(data.id(), 2)); + configForm->leIpFragOfs->setText(QString().setNum(data.frag_ofs())); + configForm->cbIpFlagsDf->setChecked((data.flags() & IP_FLAG_DF) > 0); + configForm->cbIpFlagsMf->setChecked((data.flags() & IP_FLAG_MF) > 0); - configForm->leIpTtl->setText(QString().setNum(data.ttl())); - configForm->leIpProto->setText(uintToHexStr( - fieldData(ip4_proto, FieldValue).toUInt(), 1)); + configForm->leIpTtl->setText(QString().setNum(data.ttl())); + configForm->leIpProto->setText(uintToHexStr( + fieldData(ip4_proto, FieldValue).toUInt(), 1)); - configForm->cbIpCksumOverride->setChecked(data.is_override_cksum()); - configForm->leIpCksum->setText(uintToHexStr( - fieldData(ip4_cksum, FieldValue).toUInt(), 2)); + configForm->cbIpCksumOverride->setChecked(data.is_override_cksum()); + configForm->leIpCksum->setText(uintToHexStr( + fieldData(ip4_cksum, FieldValue).toUInt(), 2)); - configForm->leIpSrcAddr->setText(QHostAddress(data.src_ip()).toString()); - configForm->cmbIpSrcAddrMode->setCurrentIndex(data.src_ip_mode()); - configForm->leIpSrcAddrCount->setText(QString().setNum(data.src_ip_count())); - configForm->leIpSrcAddrMask->setText(QHostAddress(data.src_ip_mask()).toString()); + configForm->leIpSrcAddr->setText(QHostAddress(data.src_ip()).toString()); + configForm->cmbIpSrcAddrMode->setCurrentIndex(data.src_ip_mode()); + configForm->leIpSrcAddrCount->setText(QString().setNum(data.src_ip_count())); + configForm->leIpSrcAddrMask->setText(QHostAddress(data.src_ip_mask()).toString()); - configForm->leIpDstAddr->setText(QHostAddress(data.dst_ip()).toString()); - configForm->cmbIpDstAddrMode->setCurrentIndex(data.dst_ip_mode()); - configForm->leIpDstAddrCount->setText(QString().setNum(data.dst_ip_count())); - configForm->leIpDstAddrMask->setText(QHostAddress(data.dst_ip_mask()).toString()); + configForm->leIpDstAddr->setText(QHostAddress(data.dst_ip()).toString()); + configForm->cmbIpDstAddrMode->setCurrentIndex(data.dst_ip_mode()); + configForm->leIpDstAddrCount->setText(QString().setNum(data.dst_ip_count())); + configForm->leIpDstAddrMask->setText(QHostAddress(data.dst_ip_mask()).toString()); } void Ip4Protocol::storeConfigWidget() { - uint ff = 0; - bool isOk; + uint ff = 0; + bool isOk; - configWidget(); + configWidget(); - data.set_is_override_ver(configForm->cbIpVersionOverride->isChecked()); - data.set_ver_hdrlen(((configForm->leIpVersion->text().toULong(&isOk) & 0x0F) << 4) | - (configForm->leIpHdrLen->text().toULong(&isOk) & 0x0F)); - data.set_is_override_hdrlen(configForm->cbIpHdrLenOverride->isChecked()); + data.set_is_override_ver(configForm->cbIpVersionOverride->isChecked()); + data.set_ver_hdrlen(((configForm->leIpVersion->text().toULong(&isOk) & 0x0F) << 4) | + (configForm->leIpHdrLen->text().toULong(&isOk) & 0x0F)); + data.set_is_override_hdrlen(configForm->cbIpHdrLenOverride->isChecked()); - data.set_tos(configForm->leIpTos->text().toULong(&isOk, 16)); + data.set_tos(configForm->leIpTos->text().toULong(&isOk, 16)); - data.set_totlen(configForm->leIpLength->text().toULong(&isOk)); - data.set_is_override_totlen(configForm->cbIpLengthOverride->isChecked()); + data.set_totlen(configForm->leIpLength->text().toULong(&isOk)); + data.set_is_override_totlen(configForm->cbIpLengthOverride->isChecked()); - data.set_id(configForm->leIpId->text().remove(QChar(' ')).toULong(&isOk, 16)); - data.set_frag_ofs(configForm->leIpFragOfs->text().toULong(&isOk)); + data.set_id(configForm->leIpId->text().remove(QChar(' ')).toULong(&isOk, 16)); + data.set_frag_ofs(configForm->leIpFragOfs->text().toULong(&isOk)); - if (configForm->cbIpFlagsDf->isChecked()) ff |= IP_FLAG_DF; - if (configForm->cbIpFlagsMf->isChecked()) ff |= IP_FLAG_MF; - data.set_flags(ff); + if (configForm->cbIpFlagsDf->isChecked()) ff |= IP_FLAG_DF; + if (configForm->cbIpFlagsMf->isChecked()) ff |= IP_FLAG_MF; + data.set_flags(ff); - data.set_ttl(configForm->leIpTtl->text().toULong(&isOk)); - data.set_proto(configForm->leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16)); - - data.set_is_override_cksum(configForm->cbIpCksumOverride->isChecked()); - data.set_cksum(configForm->leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); + data.set_ttl(configForm->leIpTtl->text().toULong(&isOk)); + data.set_proto(configForm->leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16)); + + data.set_is_override_cksum(configForm->cbIpCksumOverride->isChecked()); + data.set_cksum(configForm->leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); - data.set_src_ip(QHostAddress(configForm->leIpSrcAddr->text()).toIPv4Address()); - data.set_src_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpSrcAddrMode->currentIndex()); - data.set_src_ip_count(configForm->leIpSrcAddrCount->text().toULong(&isOk)); - data.set_src_ip_mask(QHostAddress(configForm->leIpSrcAddrMask->text()).toIPv4Address()); + data.set_src_ip(QHostAddress(configForm->leIpSrcAddr->text()).toIPv4Address()); + data.set_src_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpSrcAddrMode->currentIndex()); + data.set_src_ip_count(configForm->leIpSrcAddrCount->text().toULong(&isOk)); + data.set_src_ip_mask(QHostAddress(configForm->leIpSrcAddrMask->text()).toIPv4Address()); - data.set_dst_ip(QHostAddress(configForm->leIpDstAddr->text()).toIPv4Address()); - data.set_dst_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpDstAddrMode->currentIndex()); - data.set_dst_ip_count(configForm->leIpDstAddrCount->text().toULong(&isOk)); - data.set_dst_ip_mask(QHostAddress(configForm->leIpDstAddrMask->text()).toIPv4Address()); + data.set_dst_ip(QHostAddress(configForm->leIpDstAddr->text()).toIPv4Address()); + data.set_dst_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpDstAddrMode->currentIndex()); + data.set_dst_ip_count(configForm->leIpDstAddrCount->text().toULong(&isOk)); + data.set_dst_ip_mask(QHostAddress(configForm->leIpDstAddrMask->text()).toIPv4Address()); } diff --git a/common/ip4.h b/common/ip4.h index e3e1a23..a9a40b9 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -6,89 +6,89 @@ #include "ip4.pb.h" #include "ui_ip4.h" -#define IP_FLAG_MF 0x1 -#define IP_FLAG_DF 0x2 -#define IP_FLAG_UNUSED 0x4 +#define IP_FLAG_MF 0x1 +#define IP_FLAG_DF 0x2 +#define IP_FLAG_UNUSED 0x4 class Ip4ConfigForm : public QWidget, public Ui::ip4 { - Q_OBJECT + Q_OBJECT public: - Ip4ConfigForm(QWidget *parent = 0); - ~Ip4ConfigForm(); + Ip4ConfigForm(QWidget *parent = 0); + ~Ip4ConfigForm(); private slots: - void on_cmbIpSrcAddrMode_currentIndexChanged(int index); - void on_cmbIpDstAddrMode_currentIndexChanged(int index); + void on_cmbIpSrcAddrMode_currentIndexChanged(int index); + void on_cmbIpDstAddrMode_currentIndexChanged(int index); }; class Ip4Protocol : public AbstractProtocol { private: - OstProto::Ip4 data; - Ip4ConfigForm *configForm; - enum ip4field - { - ip4_ver = 0, - ip4_hdrLen, - ip4_tos, - ip4_totLen, - ip4_id, - ip4_flags, - ip4_fragOfs, - ip4_ttl, - ip4_proto, - ip4_cksum, - ip4_srcAddr, - ip4_dstAddr, + OstProto::Ip4 data; + Ip4ConfigForm *configForm; + enum ip4field + { + ip4_ver = 0, + ip4_hdrLen, + ip4_tos, + ip4_totLen, + ip4_id, + ip4_flags, + ip4_fragOfs, + ip4_ttl, + ip4_proto, + ip4_cksum, + ip4_srcAddr, + ip4_dstAddr, - ip4_isOverrideVer, - ip4_isOverrideHdrLen, - ip4_isOverrideTotLen, - ip4_isOverrideCksum, + ip4_isOverrideVer, + ip4_isOverrideHdrLen, + ip4_isOverrideTotLen, + ip4_isOverrideCksum, - ip4_srcAddrMode, - ip4_srcAddrCount, - ip4_srcAddrMask, + ip4_srcAddrMode, + ip4_srcAddrCount, + ip4_srcAddrMask, - ip4_dstAddrMode, - ip4_dstAddrCount, - ip4_dstAddrMask, + ip4_dstAddrMode, + ip4_dstAddrCount, + ip4_dstAddrMask, - ip4_fieldCount - }; + ip4_fieldCount + }; public: - Ip4Protocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~Ip4Protocol(); + Ip4Protocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~Ip4Protocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; - virtual ProtocolIdType protocolIdType() const; - virtual quint32 protocolId(ProtocolIdType type) const; - virtual int fieldCount() const; + virtual QString name() const; + virtual QString shortName() const; + virtual ProtocolIdType protocolIdType() const; + virtual quint32 protocolId(ProtocolIdType type) const; + virtual int fieldCount() const; - virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameValueVariable() const; - virtual quint32 protocolFrameCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; diff --git a/common/ip4.proto b/common/ip4.proto index 84fcbf4..ffdfcae 100644 --- a/common/ip4.proto +++ b/common/ip4.proto @@ -4,43 +4,43 @@ package OstProto; // IPv4 message Ip4 { - enum IpAddrMode { - e_im_fixed = 0; - e_im_inc_host = 1; - e_im_dec_host = 2; - e_im_random_host = 3; - } + enum IpAddrMode { + e_im_fixed = 0; + e_im_inc_host = 1; + e_im_dec_host = 2; + e_im_random_host = 3; + } - optional bool is_override_ver = 1; - optional bool is_override_hdrlen = 2; - optional bool is_override_totlen = 3; - optional bool is_override_cksum = 4; + optional bool is_override_ver = 1; + optional bool is_override_hdrlen = 2; + optional bool is_override_totlen = 3; + optional bool is_override_cksum = 4; - optional uint32 ver_hdrlen = 5 [default = 0x45]; - optional uint32 tos = 6; - optional uint32 totlen = 7; - optional uint32 id = 8 [default = 1234]; - optional uint32 flags = 9; - optional uint32 frag_ofs = 10; - optional uint32 ttl = 11 [default = 127]; - optional uint32 proto = 12; - optional uint32 cksum = 13; + optional uint32 ver_hdrlen = 5 [default = 0x45]; + optional uint32 tos = 6; + optional uint32 totlen = 7; + optional uint32 id = 8 [default = 1234]; + optional uint32 flags = 9; + optional uint32 frag_ofs = 10; + optional uint32 ttl = 11 [default = 127]; + optional uint32 proto = 12; + optional uint32 cksum = 13; - // Source IP - optional fixed32 src_ip = 14; - optional IpAddrMode src_ip_mode = 15 [default = e_im_fixed]; - optional uint32 src_ip_count = 16 [default = 16]; - optional fixed32 src_ip_mask = 17 [default = 0xFFFFFF00]; - - // Destination IP - optional fixed32 dst_ip = 18; - optional IpAddrMode dst_ip_mode = 19 [default = e_im_fixed]; - optional uint32 dst_ip_count = 20 [default = 16]; - optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFF00]; + // Source IP + optional fixed32 src_ip = 14; + optional IpAddrMode src_ip_mode = 15 [default = e_im_fixed]; + optional uint32 src_ip_count = 16 [default = 16]; + optional fixed32 src_ip_mask = 17 [default = 0xFFFFFF00]; + + // Destination IP + optional fixed32 dst_ip = 18; + optional IpAddrMode dst_ip_mode = 19 [default = e_im_fixed]; + optional uint32 dst_ip_count = 20 [default = 16]; + optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFF00]; - //! \todo (LOW) IPv4 Options + //! \todo (LOW) IPv4 Options } extend Protocol { - optional Ip4 ip4 = 130; + optional Ip4 ip4 = 130; } diff --git a/common/llc.cpp b/common/llc.cpp index 25cc307..a4943f7 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -4,173 +4,173 @@ #include "llc.h" LlcConfigForm::LlcConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); } LlcProtocol::LlcProtocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } LlcProtocol::~LlcProtocol() { - delete configForm; + delete configForm; } AbstractProtocol* LlcProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new LlcProtocol(stream, parent); + return new LlcProtocol(stream, parent); } quint32 LlcProtocol::protocolNumber() const { - return OstProto::Protocol::kLlcFieldNumber; + return OstProto::Protocol::kLlcFieldNumber; } void LlcProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::llc)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::llc)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void LlcProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::llc)) - data.MergeFrom(protocol.GetExtension(OstProto::llc)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::llc)) + data.MergeFrom(protocol.GetExtension(OstProto::llc)); } QString LlcProtocol::name() const { - return QString("802.3 Logical Link Control"); + return QString("802.3 Logical Link Control"); } QString LlcProtocol::shortName() const { - return QString("LLC"); + return QString("LLC"); } AbstractProtocol::ProtocolIdType LlcProtocol::protocolIdType() const { - return ProtocolIdLlc; + return ProtocolIdLlc; } -int LlcProtocol::fieldCount() const +int LlcProtocol::fieldCount() const { - return llc_fieldCount; + return llc_fieldCount; } QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - quint32 id; - quint8 dsap, ssap, ctl; + quint32 id; + quint8 dsap, ssap, ctl; - id = payloadProtocolId(ProtocolIdLlc); - dsap = (id >> 16) & 0xFF; - ssap = (id >> 8) & 0xFF; - ctl = (id >> 0) & 0xFF; + id = payloadProtocolId(ProtocolIdLlc); + dsap = (id >> 16) & 0xFF; + ssap = (id >> 8) & 0xFF; + ctl = (id >> 0) & 0xFF; - switch (index) - { - case llc_dsap: - switch(attrib) - { - case FieldName: - return QString("DSAP"); - case FieldValue: - return dsap; - case FieldTextValue: - return QString("%1").arg(dsap, 2, BASE_HEX, QChar('0')); - case FieldFrameValue: - return QByteArray(1, (char)(dsap)); - default: - break; - } - break; - case llc_ssap: - switch(attrib) - { - case FieldName: - return QString("SSAP"); - case FieldValue: - return ssap; - case FieldTextValue: - return QString("%1").arg(ssap, 2, BASE_HEX, QChar('0')); - case FieldFrameValue: - return QByteArray(1, (char)(ssap)); - default: - break; - } - break; - case llc_ctl: - switch(attrib) - { - case FieldName: - return QString("Control"); - case FieldValue: - return ctl; - case FieldTextValue: - return QString("%1").arg(ctl, 2, BASE_HEX, QChar('0')); - case FieldFrameValue: - return QByteArray(1, (char)(ctl)); - default: - break; - } - break; + switch (index) + { + case llc_dsap: + switch(attrib) + { + case FieldName: + return QString("DSAP"); + case FieldValue: + return dsap; + case FieldTextValue: + return QString("%1").arg(dsap, 2, BASE_HEX, QChar('0')); + case FieldFrameValue: + return QByteArray(1, (char)(dsap)); + default: + break; + } + break; + case llc_ssap: + switch(attrib) + { + case FieldName: + return QString("SSAP"); + case FieldValue: + return ssap; + case FieldTextValue: + return QString("%1").arg(ssap, 2, BASE_HEX, QChar('0')); + case FieldFrameValue: + return QByteArray(1, (char)(ssap)); + default: + break; + } + break; + case llc_ctl: + switch(attrib) + { + case FieldName: + return QString("Control"); + case FieldValue: + return ctl; + case FieldTextValue: + return QString("%1").arg(ctl, 2, BASE_HEX, QChar('0')); + case FieldFrameValue: + return QByteArray(1, (char)(ctl)); + default: + break; + } + break; - default: - break; - } + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool LlcProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - return false; + return false; } QWidget* LlcProtocol::configWidget() { - if (configForm == NULL) - { - configForm = new LlcConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new LlcConfigForm; + loadConfigWidget(); + } + return configForm; } void LlcProtocol::loadConfigWidget() { -#define uintToHexStr(num, bytes) \ - QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) +#define uintToHexStr(num, bytes) \ + QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) - configWidget(); + configWidget(); - configForm->leDsap->setText(uintToHexStr( - fieldData(llc_dsap, FieldValue).toUInt(), 1)); - configForm->leSsap->setText(uintToHexStr( - fieldData(llc_ssap, FieldValue).toUInt(), 1)); - configForm->leControl->setText(uintToHexStr( - fieldData(llc_ctl, FieldValue).toUInt(), 1)); + configForm->leDsap->setText(uintToHexStr( + fieldData(llc_dsap, FieldValue).toUInt(), 1)); + configForm->leSsap->setText(uintToHexStr( + fieldData(llc_ssap, FieldValue).toUInt(), 1)); + configForm->leControl->setText(uintToHexStr( + fieldData(llc_ctl, FieldValue).toUInt(), 1)); #undef uintToHexStr } void LlcProtocol::storeConfigWidget() { - bool isOk; + bool isOk; - configWidget(); + configWidget(); - data.set_dsap(configForm->leDsap->text().toULong(&isOk, BASE_HEX)); - data.set_ssap(configForm->leSsap->text().toULong(&isOk, BASE_HEX)); - data.set_ctl(configForm->leControl->text().toULong(&isOk, BASE_HEX)); + data.set_dsap(configForm->leDsap->text().toULong(&isOk, BASE_HEX)); + data.set_ssap(configForm->leSsap->text().toULong(&isOk, BASE_HEX)); + data.set_ctl(configForm->leControl->text().toULong(&isOk, BASE_HEX)); } diff --git a/common/llc.h b/common/llc.h index 741f493..5de0b72 100644 --- a/common/llc.h +++ b/common/llc.h @@ -11,51 +11,51 @@ class LlcConfigForm : public QWidget, public Ui::llc { - Q_OBJECT + Q_OBJECT public: - LlcConfigForm(QWidget *parent = 0); + LlcConfigForm(QWidget *parent = 0); }; class LlcProtocol : public AbstractProtocol { private: - OstProto::Llc data; - LlcConfigForm *configForm; - enum llcfield - { - llc_dsap = 0, - llc_ssap, - llc_ctl, + OstProto::Llc data; + LlcConfigForm *configForm; + enum llcfield + { + llc_dsap = 0, + llc_ssap, + llc_ctl, - llc_fieldCount - }; + llc_fieldCount + }; public: - LlcProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~LlcProtocol(); + LlcProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~LlcProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; - virtual ProtocolIdType protocolIdType() const; + virtual ProtocolIdType protocolIdType() const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/llc.proto b/common/llc.proto index 72a4393..c1966ab 100644 --- a/common/llc.proto +++ b/common/llc.proto @@ -3,11 +3,11 @@ import "protocol.proto"; package OstProto; message Llc { - optional uint32 dsap = 1; - optional uint32 ssap = 2; - optional uint32 ctl = 3; + optional uint32 dsap = 1; + optional uint32 ssap = 2; + optional uint32 ctl = 3; } extend Protocol { - optional Llc llc = 123; + optional Llc llc = 123; } diff --git a/common/mac.cpp b/common/mac.cpp index 1d7ed87..efbd518 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -4,294 +4,294 @@ #include "mac.h" MacConfigForm::MacConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); + QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); - setupUi(this); - leDstMac->setValidator(new QRegExpValidator(reMac, this)); - leSrcMac->setValidator(new QRegExpValidator(reMac, this)); - leDstMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); - leSrcMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); + setupUi(this); + leDstMac->setValidator(new QRegExpValidator(reMac, this)); + leSrcMac->setValidator(new QRegExpValidator(reMac, this)); + leDstMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); + leSrcMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this)); } MacConfigForm::~MacConfigForm() { - qDebug("In MacConfigForm destructor"); + qDebug("In MacConfigForm destructor"); } void MacConfigForm::on_cmbDstMacMode_currentIndexChanged(int index) { - if (index == OstProto::Mac::e_mm_fixed) - { - leDstMacCount->setEnabled(false); - leDstMacStep->setEnabled(false); - } - else - { - leDstMacCount->setEnabled(true); - leDstMacStep->setEnabled(true); - } + if (index == OstProto::Mac::e_mm_fixed) + { + leDstMacCount->setEnabled(false); + leDstMacStep->setEnabled(false); + } + else + { + leDstMacCount->setEnabled(true); + leDstMacStep->setEnabled(true); + } } void MacConfigForm::on_cmbSrcMacMode_currentIndexChanged(int index) { - if (index == OstProto::Mac::e_mm_fixed) - { - leSrcMacCount->setEnabled(false); - leSrcMacStep->setEnabled(false); - } - else - { - leSrcMacCount->setEnabled(true); - leSrcMacStep->setEnabled(true); - } + if (index == OstProto::Mac::e_mm_fixed) + { + leSrcMacCount->setEnabled(false); + leSrcMacStep->setEnabled(false); + } + else + { + leSrcMacCount->setEnabled(true); + leSrcMacStep->setEnabled(true); + } } MacProtocol::MacProtocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } MacProtocol::~MacProtocol() { - delete configForm; + delete configForm; } AbstractProtocol* MacProtocol::createInstance(StreamBase *stream - , AbstractProtocol *parent) + , AbstractProtocol *parent) { - return new MacProtocol(stream, parent); + return new MacProtocol(stream, parent); } quint32 MacProtocol::protocolNumber() const { - return OstProto::Protocol::kMacFieldNumber; + return OstProto::Protocol::kMacFieldNumber; } void MacProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::mac)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::mac)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void MacProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::mac)) - data.MergeFrom(protocol.GetExtension(OstProto::mac)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::mac)) + data.MergeFrom(protocol.GetExtension(OstProto::mac)); } QString MacProtocol::name() const { - return QString("Media Access Protocol"); + return QString("Media Access Protocol"); } QString MacProtocol::shortName() const { - return QString("MAC"); + return QString("MAC"); } -int MacProtocol::fieldCount() const +int MacProtocol::fieldCount() const { - return mac_fieldCount; + return mac_fieldCount; } AbstractProtocol::FieldFlags MacProtocol::fieldFlags(int index) const { - AbstractProtocol::FieldFlags flags; + AbstractProtocol::FieldFlags flags; - flags = AbstractProtocol::fieldFlags(index); + flags = AbstractProtocol::fieldFlags(index); - switch (index) - { - case mac_dstAddr: - case mac_srcAddr: - break; + switch (index) + { + case mac_dstAddr: + case mac_srcAddr: + break; - case mac_dstMacMode: - case mac_dstMacCount: - case mac_dstMacStep: - case mac_srcMacMode: - case mac_srcMacCount: - case mac_srcMacStep: - flags |= FieldIsMeta; - break; - } + case mac_dstMacMode: + case mac_dstMacCount: + case mac_dstMacStep: + case mac_srcMacMode: + case mac_srcMacCount: + case mac_srcMacStep: + flags |= FieldIsMeta; + break; + } - return flags; + return flags; } QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case mac_dstAddr: - { - int u; - quint64 dstMac = 0; + switch (index) + { + case mac_dstAddr: + { + int u; + quint64 dstMac = 0; - switch (data.dst_mac_mode()) - { - case OstProto::Mac::e_mm_fixed: - dstMac = data.dst_mac(); - break; - case OstProto::Mac::e_mm_inc: - u = (streamIndex % data.dst_mac_count()) * - data.dst_mac_step(); - dstMac = data.dst_mac() + u; - break; - case OstProto::Mac::e_mm_dec: - u = (streamIndex % data.dst_mac_count()) * - data.dst_mac_step(); - dstMac = data.dst_mac() - u; - break; - default: - qWarning("Unhandled dstMac_mode %d", data.dst_mac_mode()); - } + switch (data.dst_mac_mode()) + { + case OstProto::Mac::e_mm_fixed: + dstMac = data.dst_mac(); + break; + case OstProto::Mac::e_mm_inc: + u = (streamIndex % data.dst_mac_count()) * + data.dst_mac_step(); + dstMac = data.dst_mac() + u; + break; + case OstProto::Mac::e_mm_dec: + u = (streamIndex % data.dst_mac_count()) * + data.dst_mac_step(); + dstMac = data.dst_mac() - u; + break; + default: + qWarning("Unhandled dstMac_mode %d", data.dst_mac_mode()); + } - switch(attrib) - { - case FieldName: - return QString("Desination"); - case FieldValue: - return dstMac; - case FieldTextValue: - return uintToHexStr(dstMac, 6); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(8); - qToBigEndian(dstMac, (uchar*) fv.data()); - fv.remove(0, 2); - return fv; - } - default: - break; - } - break; - } - case mac_srcAddr: - { - int u; - quint64 srcMac = 0; + switch(attrib) + { + case FieldName: + return QString("Desination"); + case FieldValue: + return dstMac; + case FieldTextValue: + return uintToHexStr(dstMac, 6); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(8); + qToBigEndian(dstMac, (uchar*) fv.data()); + fv.remove(0, 2); + return fv; + } + default: + break; + } + break; + } + case mac_srcAddr: + { + int u; + quint64 srcMac = 0; - switch (data.src_mac_mode()) - { - case OstProto::Mac::e_mm_fixed: - srcMac = data.src_mac(); - break; - case OstProto::Mac::e_mm_inc: - u = (streamIndex % data.src_mac_count()) * - data.src_mac_step(); - srcMac = data.src_mac() + u; - break; - case OstProto::Mac::e_mm_dec: - u = (streamIndex % data.src_mac_count()) * - data.src_mac_step(); - srcMac = data.src_mac() - u; - break; - default: - qWarning("Unhandled srcMac_mode %d", data.src_mac_mode()); - } + switch (data.src_mac_mode()) + { + case OstProto::Mac::e_mm_fixed: + srcMac = data.src_mac(); + break; + case OstProto::Mac::e_mm_inc: + u = (streamIndex % data.src_mac_count()) * + data.src_mac_step(); + srcMac = data.src_mac() + u; + break; + case OstProto::Mac::e_mm_dec: + u = (streamIndex % data.src_mac_count()) * + data.src_mac_step(); + srcMac = data.src_mac() - u; + break; + default: + qWarning("Unhandled srcMac_mode %d", data.src_mac_mode()); + } - switch(attrib) - { - case FieldName: - return QString("Source"); - case FieldValue: - return srcMac; - case FieldTextValue: - return uintToHexStr(srcMac, 6); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(8); - qToBigEndian(srcMac, (uchar*) fv.data()); - fv.remove(0, 2); - return fv; - } - default: - break; - } - break; - } - // Meta fields - case mac_dstMacMode: - case mac_dstMacCount: - case mac_dstMacStep: - case mac_srcMacMode: - case mac_srcMacCount: - case mac_srcMacStep: - default: - break; - } + switch(attrib) + { + case FieldName: + return QString("Source"); + case FieldValue: + return srcMac; + case FieldTextValue: + return uintToHexStr(srcMac, 6); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(8); + qToBigEndian(srcMac, (uchar*) fv.data()); + fv.remove(0, 2); + return fv; + } + default: + break; + } + break; + } + // Meta fields + case mac_dstMacMode: + case mac_dstMacCount: + case mac_dstMacStep: + case mac_srcMacMode: + case mac_srcMacCount: + case mac_srcMacStep: + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool MacProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - return false; + return false; } bool MacProtocol::isProtocolFrameValueVariable() const { - if ((data.dst_mac_mode() != OstProto::Mac::e_mm_fixed) || - (data.src_mac_mode() != OstProto::Mac::e_mm_fixed)) - return true; - else - return false; + if ((data.dst_mac_mode() != OstProto::Mac::e_mm_fixed) || + (data.src_mac_mode() != OstProto::Mac::e_mm_fixed)) + return true; + else + return false; } QWidget* MacProtocol::configWidget() { - if (configForm == NULL) - { - configForm = new MacConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new MacConfigForm; + loadConfigWidget(); + } + return configForm; } void MacProtocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->leDstMac->setText(uintToHexStr(data.dst_mac(), 6)); - configForm->cmbDstMacMode->setCurrentIndex(data.dst_mac_mode()); - configForm->leDstMacCount->setText(QString().setNum(data.dst_mac_count())); - configForm->leDstMacStep->setText(QString().setNum(data.dst_mac_step())); + configForm->leDstMac->setText(uintToHexStr(data.dst_mac(), 6)); + configForm->cmbDstMacMode->setCurrentIndex(data.dst_mac_mode()); + configForm->leDstMacCount->setText(QString().setNum(data.dst_mac_count())); + configForm->leDstMacStep->setText(QString().setNum(data.dst_mac_step())); - configForm->leSrcMac->setText(uintToHexStr(data.src_mac(), 6)); - configForm->cmbSrcMacMode->setCurrentIndex(data.src_mac_mode()); - configForm->leSrcMacCount->setText(QString().setNum(data.src_mac_count())); - configForm->leSrcMacStep->setText(QString().setNum(data.src_mac_step())); + configForm->leSrcMac->setText(uintToHexStr(data.src_mac(), 6)); + configForm->cmbSrcMacMode->setCurrentIndex(data.src_mac_mode()); + configForm->leSrcMacCount->setText(QString().setNum(data.src_mac_count())); + configForm->leSrcMacStep->setText(QString().setNum(data.src_mac_step())); } void MacProtocol::storeConfigWidget() { - bool isOk; + bool isOk; - configWidget(); + configWidget(); - data.set_dst_mac(configForm->leDstMac->text().remove(QChar(' ')). - toULongLong(&isOk, 16)); - data.set_dst_mac_mode((OstProto::Mac::MacAddrMode) configForm-> - cmbDstMacMode->currentIndex()); - data.set_dst_mac_count(configForm->leDstMacCount->text().toULong(&isOk)); - data.set_dst_mac_step(configForm->leDstMacStep->text().toULong(&isOk)); + data.set_dst_mac(configForm->leDstMac->text().remove(QChar(' ')). + toULongLong(&isOk, 16)); + data.set_dst_mac_mode((OstProto::Mac::MacAddrMode) configForm-> + cmbDstMacMode->currentIndex()); + data.set_dst_mac_count(configForm->leDstMacCount->text().toULong(&isOk)); + data.set_dst_mac_step(configForm->leDstMacStep->text().toULong(&isOk)); - data.set_src_mac(configForm->leSrcMac->text().remove(QChar(' ')). - toULongLong(&isOk, 16)); - data.set_src_mac_mode((OstProto::Mac::MacAddrMode) configForm-> - cmbSrcMacMode->currentIndex()); - data.set_src_mac_count(configForm->leSrcMacCount->text().toULong(&isOk)); - data.set_src_mac_step(configForm->leSrcMacStep->text().toULong(&isOk)); + data.set_src_mac(configForm->leSrcMac->text().remove(QChar(' ')). + toULongLong(&isOk, 16)); + data.set_src_mac_mode((OstProto::Mac::MacAddrMode) configForm-> + cmbSrcMacMode->currentIndex()); + data.set_src_mac_count(configForm->leSrcMacCount->text().toULong(&isOk)); + data.set_src_mac_step(configForm->leSrcMacStep->text().toULong(&isOk)); } diff --git a/common/mac.h b/common/mac.h index b6165b7..242ce2a 100644 --- a/common/mac.h +++ b/common/mac.h @@ -10,62 +10,62 @@ class MacConfigForm : public QWidget, public Ui::mac { - Q_OBJECT + Q_OBJECT public: - MacConfigForm(QWidget *parent = 0); - virtual ~MacConfigForm(); + MacConfigForm(QWidget *parent = 0); + virtual ~MacConfigForm(); private slots: - void on_cmbDstMacMode_currentIndexChanged(int index); - void on_cmbSrcMacMode_currentIndexChanged(int index); + void on_cmbDstMacMode_currentIndexChanged(int index); + void on_cmbSrcMacMode_currentIndexChanged(int index); }; class MacProtocol : public AbstractProtocol { private: - OstProto::Mac data; - MacConfigForm *configForm; - enum macfield - { - mac_dstAddr = 0, - mac_srcAddr, + OstProto::Mac data; + MacConfigForm *configForm; + enum macfield + { + mac_dstAddr = 0, + mac_srcAddr, - mac_dstMacMode, - mac_dstMacCount, - mac_dstMacStep, - mac_srcMacMode, - mac_srcMacCount, - mac_srcMacStep, + mac_dstMacMode, + mac_dstMacCount, + mac_dstMacStep, + mac_srcMacMode, + mac_srcMacCount, + mac_srcMacStep, - mac_fieldCount - }; + mac_fieldCount + }; public: - MacProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~MacProtocol(); + MacProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~MacProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameValueVariable() const; - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/mac.proto b/common/mac.proto index a49c34e..642f725 100644 --- a/common/mac.proto +++ b/common/mac.proto @@ -5,25 +5,25 @@ package OstProto; // Ethernet message Mac { - enum MacAddrMode { - e_mm_fixed = 0; - e_mm_inc = 1; - e_mm_dec = 2; - } + enum MacAddrMode { + e_mm_fixed = 0; + e_mm_inc = 1; + e_mm_dec = 2; + } - // Dst Mac - optional uint64 dst_mac = 1; - optional MacAddrMode dst_mac_mode = 2 [default = e_mm_fixed]; - optional uint32 dst_mac_count = 3 [default = 16]; - optional uint32 dst_mac_step = 4 [default = 1]; + // Dst Mac + optional uint64 dst_mac = 1; + optional MacAddrMode dst_mac_mode = 2 [default = e_mm_fixed]; + optional uint32 dst_mac_count = 3 [default = 16]; + optional uint32 dst_mac_step = 4 [default = 1]; - // Src Mac - optional uint64 src_mac = 5; - optional MacAddrMode src_mac_mode = 6 [default = e_mm_fixed]; - optional uint32 src_mac_count = 7 [default = 16]; - optional uint32 src_mac_step = 8 [default = 1]; + // Src Mac + optional uint64 src_mac = 5; + optional MacAddrMode src_mac_mode = 6 [default = e_mm_fixed]; + optional uint32 src_mac_count = 7 [default = 16]; + optional uint32 src_mac_step = 8 [default = 1]; } extend Protocol { - optional Mac mac = 51; + optional Mac mac = 51; } diff --git a/common/ostproto.pro b/common/ostproto.pro index 19121ca..b3c37bb 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -2,80 +2,80 @@ TEMPLATE = lib CONFIG += qt staticlib QT += network script LIBS += \ - -lprotobuf + -lprotobuf FORMS += \ - mac.ui \ - payload.ui \ - eth2.ui \ - dot3.ui \ - llc.ui \ - snap.ui \ - vlan.ui \ - ip4.ui \ - tcp.ui \ - udp.ui \ - userscript.ui \ - sample.ui + mac.ui \ + payload.ui \ + eth2.ui \ + dot3.ui \ + llc.ui \ + snap.ui \ + vlan.ui \ + ip4.ui \ + tcp.ui \ + udp.ui \ + userscript.ui \ + sample.ui PROTOS += \ - protocol.proto \ - mac.proto \ - payload.proto \ - eth2.proto \ - dot3.proto \ - llc.proto \ - snap.proto \ - dot2llc.proto \ - dot2snap.proto \ - vlan.proto \ - svlan.proto \ - vlanstack.proto \ - ip4.proto \ - tcp.proto \ - udp.proto \ - userscript.proto \ - sample.proto + protocol.proto \ + mac.proto \ + payload.proto \ + eth2.proto \ + dot3.proto \ + llc.proto \ + snap.proto \ + dot2llc.proto \ + dot2snap.proto \ + vlan.proto \ + svlan.proto \ + vlanstack.proto \ + ip4.proto \ + tcp.proto \ + udp.proto \ + userscript.proto \ + sample.proto HEADERS += \ - abstractprotocol.h \ - comboprotocol.h \ - protocolmanager.h \ - protocollist.h \ - protocollistiterator.h \ - streambase.h \ - mac.h \ - payload.h \ - eth2.h \ - dot3.h \ - llc.h \ - snap.h \ - dot2llc.h \ - dot2snap.h \ - vlan.h \ - svlan.h \ - vlanstack.h \ - ip4.h \ - tcp.h \ - udp.h \ - userscript.h \ - sample.h + abstractprotocol.h \ + comboprotocol.h \ + protocolmanager.h \ + protocollist.h \ + protocollistiterator.h \ + streambase.h \ + mac.h \ + payload.h \ + eth2.h \ + dot3.h \ + llc.h \ + snap.h \ + dot2llc.h \ + dot2snap.h \ + vlan.h \ + svlan.h \ + vlanstack.h \ + ip4.h \ + tcp.h \ + udp.h \ + userscript.h \ + sample.h SOURCES += \ - abstractprotocol.cpp \ - protocolmanager.cpp \ - protocollist.cpp \ - protocollistiterator.cpp \ - streambase.cpp \ - mac.cpp \ - payload.cpp \ - eth2.cpp \ - dot3.cpp \ - llc.cpp \ - snap.cpp \ - vlan.cpp \ - svlan.cpp \ - ip4.cpp \ - tcp.cpp \ - udp.cpp \ - userscript.cpp \ - sample.cpp + abstractprotocol.cpp \ + protocolmanager.cpp \ + protocollist.cpp \ + protocollistiterator.cpp \ + streambase.cpp \ + mac.cpp \ + payload.cpp \ + eth2.cpp \ + dot3.cpp \ + llc.cpp \ + snap.cpp \ + vlan.cpp \ + svlan.cpp \ + ip4.cpp \ + tcp.cpp \ + udp.cpp \ + userscript.cpp \ + sample.cpp protobuf_decl.name = protobuf header protobuf_decl.input = PROTOS diff --git a/common/payload.cpp b/common/payload.cpp index 4bbca2e..276af95 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -5,232 +5,232 @@ #include "payload.h" #include "streambase.h" -#define SZ_FCS 4 +#define SZ_FCS 4 PayloadConfigForm::PayloadConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); } void PayloadConfigForm::on_cmbPatternMode_currentIndexChanged(int index) { - switch(index) - { - case OstProto::Payload::e_dp_fixed_word: - lePattern->setEnabled(true); - break; - case OstProto::Payload::e_dp_inc_byte: - case OstProto::Payload::e_dp_dec_byte: - case OstProto::Payload::e_dp_random: - lePattern->setDisabled(true); - break; - default: - qWarning("Unhandled/Unknown PatternMode = %d",index); - } + switch(index) + { + case OstProto::Payload::e_dp_fixed_word: + lePattern->setEnabled(true); + break; + case OstProto::Payload::e_dp_inc_byte: + case OstProto::Payload::e_dp_dec_byte: + case OstProto::Payload::e_dp_random: + lePattern->setDisabled(true); + break; + default: + qWarning("Unhandled/Unknown PatternMode = %d",index); + } } PayloadProtocol::PayloadProtocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } PayloadProtocol::~PayloadProtocol() { - delete configForm; + delete configForm; } AbstractProtocol* PayloadProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new PayloadProtocol(stream, parent); + return new PayloadProtocol(stream, parent); } quint32 PayloadProtocol::protocolNumber() const { - return OstProto::Protocol::kPayloadFieldNumber; + return OstProto::Protocol::kPayloadFieldNumber; } void PayloadProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::payload)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::payload)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void PayloadProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::payload)) - data.MergeFrom(protocol.GetExtension(OstProto::payload)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::payload)) + data.MergeFrom(protocol.GetExtension(OstProto::payload)); } QString PayloadProtocol::name() const { - return QString("Payload Data"); + return QString("Payload Data"); } QString PayloadProtocol::shortName() const { - return QString("DATA"); + return QString("DATA"); } -int PayloadProtocol::protocolFrameSize(int streamIndex) const +int PayloadProtocol::protocolFrameSize(int streamIndex) const { - int len; + int len; - len = mpStream->frameLen(streamIndex) - protocolFrameOffset(streamIndex) - - SZ_FCS; + len = mpStream->frameLen(streamIndex) - protocolFrameOffset(streamIndex) + - SZ_FCS; - qDebug("%s: this = %p, streamIndex = %d, len = %d", __FUNCTION__, this, - streamIndex, len); - return len; + qDebug("%s: this = %p, streamIndex = %d, len = %d", __FUNCTION__, this, + streamIndex, len); + return len; } -int PayloadProtocol::fieldCount() const +int PayloadProtocol::fieldCount() const { - return payload_fieldCount; + return payload_fieldCount; } AbstractProtocol::FieldFlags PayloadProtocol::fieldFlags(int index) const { - AbstractProtocol::FieldFlags flags; + AbstractProtocol::FieldFlags flags; - flags = AbstractProtocol::fieldFlags(index); + flags = AbstractProtocol::fieldFlags(index); - switch (index) - { - case payload_dataPattern: - break; + switch (index) + { + case payload_dataPattern: + break; - // Meta fields - case payload_dataPatternMode: - flags |= FieldIsMeta; - break; - } + // Meta fields + case payload_dataPatternMode: + flags |= FieldIsMeta; + break; + } - return flags; + return flags; } QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case payload_dataPattern: - switch(attrib) - { - case FieldName: - return QString("Data"); - case FieldValue: - return data.pattern(); - case FieldTextValue: - return QString(fieldData(index, FieldFrameValue, - streamIndex).toByteArray().toHex()); - case FieldFrameValue: - { - QByteArray fv; - int dataLen; + switch (index) + { + case payload_dataPattern: + switch(attrib) + { + case FieldName: + return QString("Data"); + case FieldValue: + return data.pattern(); + case FieldTextValue: + return QString(fieldData(index, FieldFrameValue, + streamIndex).toByteArray().toHex()); + case FieldFrameValue: + { + QByteArray fv; + int dataLen; - dataLen = protocolFrameSize(streamIndex); + dataLen = protocolFrameSize(streamIndex); - // FIXME: Hack! Bad! Bad! Very Bad!!! - if (dataLen <= 0) - dataLen = 1; + // FIXME: Hack! Bad! Bad! Very Bad!!! + if (dataLen <= 0) + dataLen = 1; - fv.resize(dataLen+4); - switch(data.pattern_mode()) - { - case OstProto::Payload::e_dp_fixed_word: - for (int i = 0; i < (dataLen/4)+1; i++) - qToBigEndian((quint32) data.pattern(), - (uchar*)(fv.data()+(i*4)) ); - break; - case OstProto::Payload::e_dp_inc_byte: - for (int i = 0; i < dataLen; i++) - fv[i] = i % (0xFF + 1); - break; - case OstProto::Payload::e_dp_dec_byte: - for (int i = 0; i < dataLen; i++) - fv[i] = 0xFF - (i % (0xFF + 1)); - break; - case OstProto::Payload::e_dp_random: - //! \todo (HIGH) cksum is incorrect for random pattern - for (int i = 0; i < dataLen; i++) - fv[i] = qrand() % (0xFF + 1); - break; - default: - qWarning("Unhandled data pattern %d", - data.pattern_mode()); - } - fv.resize(dataLen); - return fv; - } - default: - break; - } - break; + fv.resize(dataLen+4); + switch(data.pattern_mode()) + { + case OstProto::Payload::e_dp_fixed_word: + for (int i = 0; i < (dataLen/4)+1; i++) + qToBigEndian((quint32) data.pattern(), + (uchar*)(fv.data()+(i*4)) ); + break; + case OstProto::Payload::e_dp_inc_byte: + for (int i = 0; i < dataLen; i++) + fv[i] = i % (0xFF + 1); + break; + case OstProto::Payload::e_dp_dec_byte: + for (int i = 0; i < dataLen; i++) + fv[i] = 0xFF - (i % (0xFF + 1)); + break; + case OstProto::Payload::e_dp_random: + //! \todo (HIGH) cksum is incorrect for random pattern + for (int i = 0; i < dataLen; i++) + fv[i] = qrand() % (0xFF + 1); + break; + default: + qWarning("Unhandled data pattern %d", + data.pattern_mode()); + } + fv.resize(dataLen); + return fv; + } + default: + break; + } + break; - // Meta fields + // Meta fields - case payload_dataPatternMode: - default: - break; - } + case payload_dataPatternMode: + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool PayloadProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - return false; + return false; } bool PayloadProtocol::isProtocolFrameValueVariable() const { - if (isProtocolFrameSizeVariable() - || data.pattern_mode() == OstProto::Payload::e_dp_random) - return true; - else - return false; + if (isProtocolFrameSizeVariable() + || data.pattern_mode() == OstProto::Payload::e_dp_random) + return true; + else + return false; } bool PayloadProtocol::isProtocolFrameSizeVariable() const { - if (mpStream->lenMode() == StreamBase::e_fl_fixed) - return false; - else - return true; + if (mpStream->lenMode() == StreamBase::e_fl_fixed) + return false; + else + return true; } QWidget* PayloadProtocol::configWidget() { - if (configForm == NULL) - { - configForm = new PayloadConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new PayloadConfigForm; + loadConfigWidget(); + } + return configForm; } void PayloadProtocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->cmbPatternMode->setCurrentIndex(data.pattern_mode()); - configForm->lePattern->setText(uintToHexStr(data.pattern(), 4)); + configForm->cmbPatternMode->setCurrentIndex(data.pattern_mode()); + configForm->lePattern->setText(uintToHexStr(data.pattern(), 4)); } void PayloadProtocol::storeConfigWidget() { - bool isOk; + bool isOk; - configWidget(); + configWidget(); - data.set_pattern_mode((OstProto::Payload::DataPatternMode) - configForm->cmbPatternMode->currentIndex()); - data.set_pattern(configForm->lePattern->text().remove(QChar(' ')).toULong(&isOk, 16)); + data.set_pattern_mode((OstProto::Payload::DataPatternMode) + configForm->cmbPatternMode->currentIndex()); + data.set_pattern(configForm->lePattern->text().remove(QChar(' ')).toULong(&isOk, 16)); } diff --git a/common/payload.h b/common/payload.h index 9437a8c..d468a16 100644 --- a/common/payload.h +++ b/common/payload.h @@ -8,58 +8,58 @@ class PayloadConfigForm : public QWidget, public Ui::payload { - Q_OBJECT + Q_OBJECT public: - PayloadConfigForm(QWidget *parent = 0); + PayloadConfigForm(QWidget *parent = 0); private slots: - void on_cmbPatternMode_currentIndexChanged(int index); + void on_cmbPatternMode_currentIndexChanged(int index); }; class PayloadProtocol : public AbstractProtocol { private: - OstProto::Payload data; - PayloadConfigForm *configForm; - enum payloadfield - { - payload_dataPattern, + OstProto::Payload data; + PayloadConfigForm *configForm; + enum payloadfield + { + payload_dataPattern, - // Meta fields - payload_dataPatternMode, + // Meta fields + payload_dataPatternMode, - payload_fieldCount - }; + payload_fieldCount + }; public: - PayloadProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~PayloadProtocol(); + PayloadProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~PayloadProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; - virtual int protocolFrameSize(int streamIndex = 0) const; + virtual int protocolFrameSize(int streamIndex = 0) const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual bool isProtocolFrameValueVariable() const; - virtual bool isProtocolFrameSizeVariable() const; + virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameSizeVariable() const; - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/payload.proto b/common/payload.proto index b3a6946..0cbc878 100644 --- a/common/payload.proto +++ b/common/payload.proto @@ -3,20 +3,20 @@ import "protocol.proto"; package OstProto; message Payload { - enum DataPatternMode { - e_dp_fixed_word = 0; - e_dp_inc_byte = 1; - e_dp_dec_byte = 2; - e_dp_random = 3; - } + enum DataPatternMode { + e_dp_fixed_word = 0; + e_dp_inc_byte = 1; + e_dp_dec_byte = 2; + e_dp_random = 3; + } - // Data Pattern - optional DataPatternMode pattern_mode = 1; - optional uint32 pattern = 2; + // Data Pattern + optional DataPatternMode pattern_mode = 1; + optional uint32 pattern = 2; - //optional uint32 data_start_ofs = 13; + //optional uint32 data_start_ofs = 13; } extend Protocol { - optional Payload payload = 52; + optional Payload payload = 52; } diff --git a/common/protocol.proto b/common/protocol.proto index 30bec18..c8bdc05 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -3,208 +3,208 @@ package OstProto; message StreamId { - required uint32 id = 1; + required uint32 id = 1; } message StreamCore { - enum FrameLengthMode { - e_fl_fixed = 0; - e_fl_inc = 1; - e_fl_dec = 2; - e_fl_random = 3; - } - - // Basics - optional string name = 1; - optional bool is_enabled = 2; - optional uint32 ordinal = 3; + enum FrameLengthMode { + e_fl_fixed = 0; + e_fl_inc = 1; + e_fl_dec = 2; + e_fl_random = 3; + } + + // Basics + optional string name = 1; + optional bool is_enabled = 2; + optional uint32 ordinal = 3; - // Frame Length (includes CRC) - optional FrameLengthMode len_mode = 14 [default = e_fl_fixed]; - optional uint32 frame_len = 15 [default = 64]; - optional uint32 frame_len_min = 16 [default = 64]; - optional uint32 frame_len_max = 17 [default = 1518]; + // Frame Length (includes CRC) + optional FrameLengthMode len_mode = 14 [default = e_fl_fixed]; + optional uint32 frame_len = 15 [default = 64]; + optional uint32 frame_len_min = 16 [default = 64]; + optional uint32 frame_len_max = 17 [default = 1518]; - // Currently Selected Protocols - //repeated uint32 frame_proto = 20; + // Currently Selected Protocols + //repeated uint32 frame_proto = 20; } message StreamControl { - enum SendUnit { - e_su_packets = 0; - e_su_bursts = 1; - } + enum SendUnit { + e_su_packets = 0; + e_su_bursts = 1; + } - enum SendMode { - e_sm_fixed = 0; - e_sm_continuous = 1; - } + enum SendMode { + e_sm_fixed = 0; + e_sm_continuous = 1; + } - enum NextWhat { - e_nw_stop = 0; - e_nw_goto_next = 1; - e_nw_goto_id = 2; - } + enum NextWhat { + e_nw_stop = 0; + e_nw_goto_next = 1; + e_nw_goto_id = 2; + } - optional SendUnit unit = 1 [default = e_su_packets]; - optional SendMode mode = 2 [default = e_sm_fixed]; - optional uint32 num_packets = 3 [default = 1]; - optional uint32 num_bursts = 4 [default = 1]; - optional uint32 packets_per_burst = 5 [default = 10]; - optional NextWhat next = 6 [default = e_nw_goto_next]; - optional uint32 packets_per_sec = 7 [default = 1]; - optional uint32 bursts_per_sec = 8 [default = 1]; + optional SendUnit unit = 1 [default = e_su_packets]; + optional SendMode mode = 2 [default = e_sm_fixed]; + optional uint32 num_packets = 3 [default = 1]; + optional uint32 num_bursts = 4 [default = 1]; + optional uint32 packets_per_burst = 5 [default = 10]; + optional NextWhat next = 6 [default = e_nw_goto_next]; + optional uint32 packets_per_sec = 7 [default = 1]; + optional uint32 bursts_per_sec = 8 [default = 1]; } message ProtocolId { - required uint32 id = 1; + required uint32 id = 1; } message Protocol { - required ProtocolId protocol_id = 1; + required ProtocolId protocol_id = 1; - extensions 51 to 100; // Reserved for Ostinato Use - extensions 101 to 200; // Available for use by protocols + extensions 51 to 100; // Reserved for Ostinato Use + extensions 101 to 200; // Available for use by protocols - enum k { - kMacFieldNumber = 51; - kPayloadFieldNumber = 52; - kSampleFieldNumber = 53; - kUserScriptFieldNumber = 54; + enum k { + kMacFieldNumber = 51; + kPayloadFieldNumber = 52; + kSampleFieldNumber = 53; + kUserScriptFieldNumber = 54; - kEth2FieldNumber = 121; - kDot3FieldNumber = 122; - kLlcFieldNumber = 123; - kSnapFieldNumber = 124; + kEth2FieldNumber = 121; + kDot3FieldNumber = 122; + kLlcFieldNumber = 123; + kSnapFieldNumber = 124; - kSvlanFieldNumber = 125; - kVlanFieldNumber = 126; + kSvlanFieldNumber = 125; + kVlanFieldNumber = 126; - kDot2LlcFieldNumber = 127; - kDot2SnapFieldNumber = 128; - kVlanStackFieldNumber = 129; + kDot2LlcFieldNumber = 127; + kDot2SnapFieldNumber = 128; + kVlanStackFieldNumber = 129; - kIp4FieldNumber = 130; - kArpFieldNumber = 131; + kIp4FieldNumber = 130; + kArpFieldNumber = 131; - kTcpFieldNumber = 140; - kUdpFieldNumber = 141; - kIcmpFieldNumber = 142; - kIgmpFieldNumber = 143; - } + kTcpFieldNumber = 140; + kUdpFieldNumber = 141; + kIcmpFieldNumber = 142; + kIgmpFieldNumber = 143; + } } message Stream { - required StreamId stream_id = 1; - optional StreamCore core = 2; - optional StreamControl control = 3; + required StreamId stream_id = 1; + optional StreamCore core = 2; + optional StreamControl control = 3; - repeated Protocol protocol = 4; + repeated Protocol protocol = 4; } message Void { - // nothing! + // nothing! } message Ack { - //! \todo (LOW) do we need any fields in 'Ack' + //! \todo (LOW) do we need any fields in 'Ack' } message PortId { - required uint32 id = 1; + required uint32 id = 1; } message PortIdList { - repeated PortId port_id = 1; + repeated PortId port_id = 1; } message StreamIdList { - required PortId port_id = 1; - repeated StreamId stream_id = 2; + required PortId port_id = 1; + repeated StreamId stream_id = 2; } message Port { - required PortId port_id = 1; - optional string name = 2; - optional string description = 3; - optional bool is_enabled = 4; - optional bool is_exclusive_control = 6; + required PortId port_id = 1; + optional string name = 2; + optional string description = 3; + optional bool is_enabled = 4; + optional bool is_exclusive_control = 6; } message PortConfigList { - repeated Port port = 1; + repeated Port port = 1; } message StreamConfigList { - required PortId port_id = 1; - repeated Stream stream = 2; + required PortId port_id = 1; + repeated Stream stream = 2; } message CaptureBuffer { - //! \todo (HIGH) define CaptureBuffer + //! \todo (HIGH) define CaptureBuffer } message CaptureBufferList { - repeated CaptureBuffer list = 1; + repeated CaptureBuffer list = 1; } enum LinkState { - LinkStateUnknown = 0; - LinkStateDown = 1; - LinkStateUp = 2; + LinkStateUnknown = 0; + LinkStateDown = 1; + LinkStateUp = 2; } message PortState { - optional LinkState link_state = 1 [default = LinkStateUnknown]; - optional bool is_transmit_on = 2 [default = false]; - optional bool is_capture_on = 3 [default = false]; + optional LinkState link_state = 1 [default = LinkStateUnknown]; + optional bool is_transmit_on = 2 [default = false]; + optional bool is_capture_on = 3 [default = false]; } message PortStats { - required PortId port_id = 1; + required PortId port_id = 1; - optional PortState state = 2; + optional PortState state = 2; - optional uint64 rx_pkts = 11; - optional uint64 rx_bytes = 12; - optional uint64 rx_pkts_nic = 13; - optional uint64 rx_bytes_nic = 14; - optional uint64 rx_pps = 15; - optional uint64 rx_bps = 16; + optional uint64 rx_pkts = 11; + optional uint64 rx_bytes = 12; + optional uint64 rx_pkts_nic = 13; + optional uint64 rx_bytes_nic = 14; + optional uint64 rx_pps = 15; + optional uint64 rx_bps = 16; - optional uint64 tx_pkts = 21; - optional uint64 tx_bytes = 22; - optional uint64 tx_pkts_nic = 23; - optional uint64 tx_bytes_nic = 24; - optional uint64 tx_pps = 25; - optional uint64 tx_bps = 26; + optional uint64 tx_pkts = 21; + optional uint64 tx_bytes = 22; + optional uint64 tx_pkts_nic = 23; + optional uint64 tx_bytes_nic = 24; + optional uint64 tx_pps = 25; + optional uint64 tx_bps = 26; } message PortStatsList { - repeated PortStats port_stats = 1; + repeated PortStats port_stats = 1; } service OstService { - rpc getPortIdList(Void) returns (PortIdList); - rpc getPortConfig(PortIdList) returns (PortConfigList); + rpc getPortIdList(Void) returns (PortIdList); + rpc getPortConfig(PortIdList) returns (PortConfigList); - rpc getStreamIdList(PortId) returns (StreamIdList); - rpc getStreamConfig(StreamIdList) returns (StreamConfigList); - rpc addStream(StreamIdList) returns (Ack); - rpc deleteStream(StreamIdList) returns (Ack); - rpc modifyStream(StreamConfigList) returns (Ack); + rpc getStreamIdList(PortId) returns (StreamIdList); + rpc getStreamConfig(StreamIdList) returns (StreamConfigList); + rpc addStream(StreamIdList) returns (Ack); + rpc deleteStream(StreamIdList) returns (Ack); + rpc modifyStream(StreamConfigList) returns (Ack); - rpc startTx(PortIdList) returns (Ack); - rpc stopTx(PortIdList) returns (Ack); + rpc startTx(PortIdList) returns (Ack); + rpc stopTx(PortIdList) returns (Ack); - rpc startCapture(PortIdList) returns (Ack); - rpc stopCapture(PortIdList) returns (Ack); - rpc getCaptureBuffer(PortId) returns (CaptureBuffer); + rpc startCapture(PortIdList) returns (Ack); + rpc stopCapture(PortIdList) returns (Ack); + rpc getCaptureBuffer(PortId) returns (CaptureBuffer); - rpc getStats(PortIdList) returns (PortStatsList); - rpc clearStats(PortIdList) returns (Ack); + rpc getStats(PortIdList) returns (PortStatsList); + rpc clearStats(PortIdList) returns (Ack); } diff --git a/common/protocollist.cpp b/common/protocollist.cpp index 26d2aab..08ff40a 100644 --- a/common/protocollist.cpp +++ b/common/protocollist.cpp @@ -3,6 +3,6 @@ void ProtocolList::destroy() { - while (!isEmpty()) - delete takeFirst(); + while (!isEmpty()) + delete takeFirst(); } diff --git a/common/protocollist.h b/common/protocollist.h index bbf2720..d760f14 100644 --- a/common/protocollist.h +++ b/common/protocollist.h @@ -5,5 +5,5 @@ class AbstractProtocol; class ProtocolList : public QLinkedList { public: - void destroy(); + void destroy(); }; diff --git a/common/protocollistiterator.cpp b/common/protocollistiterator.cpp index 268e2d6..242d8d9 100644 --- a/common/protocollistiterator.cpp +++ b/common/protocollistiterator.cpp @@ -4,111 +4,111 @@ ProtocolListIterator::ProtocolListIterator(ProtocolList &list) { - _iter = new QMutableLinkedListIterator(list); + _iter = new QMutableLinkedListIterator(list); } ProtocolListIterator::~ProtocolListIterator() { - delete _iter; + delete _iter; } bool ProtocolListIterator::findNext(const AbstractProtocol* value) const { - return _iter->findNext((AbstractProtocol*)((uint)value)); + return _iter->findNext((AbstractProtocol*)((uint)value)); } bool ProtocolListIterator::findPrevious(const AbstractProtocol* value) { - return _iter->findPrevious((AbstractProtocol*)((uint)value)); + return _iter->findPrevious((AbstractProtocol*)((uint)value)); } bool ProtocolListIterator::hasNext() const { - return _iter->hasNext(); + return _iter->hasNext(); } bool ProtocolListIterator::hasPrevious() const { - return _iter->hasPrevious(); + return _iter->hasPrevious(); } void ProtocolListIterator::insert(AbstractProtocol* value) { - if (_iter->hasPrevious()) - { - value->prev = _iter->peekPrevious(); - value->prev->next = value; - } - else - value->prev = NULL; + if (_iter->hasPrevious()) + { + value->prev = _iter->peekPrevious(); + value->prev->next = value; + } + else + value->prev = NULL; - if (_iter->hasNext()) - { - value->next = _iter->peekNext(); - value->next->prev = value; - } - else - value->next = NULL; + if (_iter->hasNext()) + { + value->next = _iter->peekNext(); + value->next->prev = value; + } + else + value->next = NULL; - _iter->insert((AbstractProtocol*)((uint)value)); + _iter->insert((AbstractProtocol*)((uint)value)); } AbstractProtocol* ProtocolListIterator::next() { - return _iter->next(); + return _iter->next(); } AbstractProtocol* ProtocolListIterator::peekNext() const { - return _iter->peekNext(); + return _iter->peekNext(); } AbstractProtocol* ProtocolListIterator::peekPrevious() const { - return _iter->peekPrevious(); + return _iter->peekPrevious(); } AbstractProtocol* ProtocolListIterator::previous() { - return _iter->previous(); + return _iter->previous(); } void ProtocolListIterator::remove() { - if (_iter->value()->prev) - _iter->value()->prev->next = _iter->value()->next; - if (_iter->value()->next) - _iter->value()->next->prev = _iter->value()->prev; - _iter->remove(); + if (_iter->value()->prev) + _iter->value()->prev->next = _iter->value()->next; + if (_iter->value()->next) + _iter->value()->next->prev = _iter->value()->prev; + _iter->remove(); } void ProtocolListIterator::setValue(AbstractProtocol* value) const { - if (_iter->value()->prev) - _iter->value()->prev->next = value; - if (_iter->value()->next) - _iter->value()->next->prev = value; - value->prev = _iter->value()->prev; - value->next = _iter->value()->next; - _iter->setValue((AbstractProtocol*)((uint)value)); + if (_iter->value()->prev) + _iter->value()->prev->next = value; + if (_iter->value()->next) + _iter->value()->next->prev = value; + value->prev = _iter->value()->prev; + value->next = _iter->value()->next; + _iter->setValue((AbstractProtocol*)((uint)value)); } void ProtocolListIterator::toBack() { - _iter->toBack(); + _iter->toBack(); } void ProtocolListIterator::toFront() { - _iter->toFront(); + _iter->toFront(); } const AbstractProtocol* ProtocolListIterator::value() const { - return _iter->value(); + return _iter->value(); } AbstractProtocol* ProtocolListIterator::value() { - return _iter->value(); + return _iter->value(); } diff --git a/common/protocollistiterator.h b/common/protocollistiterator.h index 8ad4168..463dae9 100644 --- a/common/protocollistiterator.h +++ b/common/protocollistiterator.h @@ -6,24 +6,24 @@ class ProtocolList; class ProtocolListIterator { private: - QMutableLinkedListIterator *_iter; + QMutableLinkedListIterator *_iter; public: - ProtocolListIterator(ProtocolList &list); - ~ProtocolListIterator(); - bool findNext(const AbstractProtocol* value) const; - bool findPrevious(const AbstractProtocol* value); - bool hasNext() const; - bool hasPrevious() const; - void insert(AbstractProtocol* value); - AbstractProtocol* next(); - AbstractProtocol* peekNext() const; - AbstractProtocol* peekPrevious() const; - AbstractProtocol* previous(); - void remove(); - void setValue(AbstractProtocol* value) const; - void toBack(); - void toFront(); - const AbstractProtocol* value() const; - AbstractProtocol* value(); + ProtocolListIterator(ProtocolList &list); + ~ProtocolListIterator(); + bool findNext(const AbstractProtocol* value) const; + bool findPrevious(const AbstractProtocol* value); + bool hasNext() const; + bool hasPrevious() const; + void insert(AbstractProtocol* value); + AbstractProtocol* next(); + AbstractProtocol* peekNext() const; + AbstractProtocol* peekPrevious() const; + AbstractProtocol* previous(); + void remove(); + void setValue(AbstractProtocol* value) const; + void toBack(); + void toFront(); + const AbstractProtocol* value() const; + AbstractProtocol* value(); }; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 7c8763d..eb948ba 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -4,17 +4,17 @@ #include "protocol.pb.h" #include "mac.h" #include "payload.h" -#include "eth2.h" -#include "dot3.h" -#include "llc.h" -#include "snap.h" +#include "eth2.h" +#include "dot3.h" +#include "llc.h" +#include "snap.h" #include "dot2llc.h" #include "dot2snap.h" -#include "vlan.h" -#include "vlanstack.h" -#include "ip4.h" -#include "tcp.h" -#include "udp.h" +#include "vlan.h" +#include "vlanstack.h" +#include "ip4.h" +#include "tcp.h" +#include "udp.h" #include "userscript.h" #include "sample.h" @@ -22,111 +22,111 @@ ProtocolManager OstProtocolManager; ProtocolManager::ProtocolManager() { - /*! \todo (LOW) calls to registerProtocol() should be done by the protocols - themselves (once this is done remove the #includes for all the protocols) - */ - registerProtocol(OstProto::Protocol::kMacFieldNumber, - (void*) MacProtocol::createInstance); - registerProtocol(OstProto::Protocol::kPayloadFieldNumber, - (void*) PayloadProtocol::createInstance); - registerProtocol(OstProto::Protocol::kEth2FieldNumber, - (void*) Eth2Protocol::createInstance); - registerProtocol(OstProto::Protocol::kDot3FieldNumber, - (void*) Dot3Protocol::createInstance); - registerProtocol(OstProto::Protocol::kLlcFieldNumber, - (void*) LlcProtocol::createInstance); - registerProtocol(OstProto::Protocol::kSnapFieldNumber, - (void*) SnapProtocol::createInstance); - registerProtocol(OstProto::Protocol::kDot2LlcFieldNumber, - (void*) Dot2LlcProtocol::createInstance); - registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber, - (void*) Dot2SnapProtocol::createInstance); - registerProtocol(OstProto::Protocol::kSvlanFieldNumber, - (void*) SVlanProtocol::createInstance); - registerProtocol(OstProto::Protocol::kVlanFieldNumber, - (void*) VlanProtocol::createInstance); - registerProtocol(OstProto::Protocol::kVlanStackFieldNumber, - (void*) VlanStackProtocol::createInstance); - registerProtocol(OstProto::Protocol::kIp4FieldNumber, - (void*) Ip4Protocol::createInstance); - registerProtocol(OstProto::Protocol::kTcpFieldNumber, - (void*) TcpProtocol::createInstance); - registerProtocol(OstProto::Protocol::kUdpFieldNumber, - (void*) UdpProtocol::createInstance); + /*! \todo (LOW) calls to registerProtocol() should be done by the protocols + themselves (once this is done remove the #includes for all the protocols) + */ + registerProtocol(OstProto::Protocol::kMacFieldNumber, + (void*) MacProtocol::createInstance); + registerProtocol(OstProto::Protocol::kPayloadFieldNumber, + (void*) PayloadProtocol::createInstance); + registerProtocol(OstProto::Protocol::kEth2FieldNumber, + (void*) Eth2Protocol::createInstance); + registerProtocol(OstProto::Protocol::kDot3FieldNumber, + (void*) Dot3Protocol::createInstance); + registerProtocol(OstProto::Protocol::kLlcFieldNumber, + (void*) LlcProtocol::createInstance); + registerProtocol(OstProto::Protocol::kSnapFieldNumber, + (void*) SnapProtocol::createInstance); + registerProtocol(OstProto::Protocol::kDot2LlcFieldNumber, + (void*) Dot2LlcProtocol::createInstance); + registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber, + (void*) Dot2SnapProtocol::createInstance); + registerProtocol(OstProto::Protocol::kSvlanFieldNumber, + (void*) SVlanProtocol::createInstance); + registerProtocol(OstProto::Protocol::kVlanFieldNumber, + (void*) VlanProtocol::createInstance); + registerProtocol(OstProto::Protocol::kVlanStackFieldNumber, + (void*) VlanStackProtocol::createInstance); + registerProtocol(OstProto::Protocol::kIp4FieldNumber, + (void*) Ip4Protocol::createInstance); + registerProtocol(OstProto::Protocol::kTcpFieldNumber, + (void*) TcpProtocol::createInstance); + registerProtocol(OstProto::Protocol::kUdpFieldNumber, + (void*) UdpProtocol::createInstance); - registerProtocol(OstProto::Protocol::kUserScriptFieldNumber, - (void*) UserScriptProtocol::createInstance); - registerProtocol(OstProto::Protocol::kSampleFieldNumber, - (void*) SampleProtocol::createInstance); + registerProtocol(OstProto::Protocol::kUserScriptFieldNumber, + (void*) UserScriptProtocol::createInstance); + registerProtocol(OstProto::Protocol::kSampleFieldNumber, + (void*) SampleProtocol::createInstance); - populateNeighbourProtocols(); + populateNeighbourProtocols(); } void ProtocolManager::registerProtocol(int protoNumber, - void *protoInstanceCreator) + void *protoInstanceCreator) { - AbstractProtocol *p; + AbstractProtocol *p; - Q_ASSERT(!factory.contains(protoNumber)); + Q_ASSERT(!factory.contains(protoNumber)); - factory.insert(protoNumber, protoInstanceCreator); + factory.insert(protoNumber, protoInstanceCreator); - p = createProtocol(protoNumber, NULL); - protocolList.append(p); + p = createProtocol(protoNumber, NULL); + protocolList.append(p); - numberToNameMap.insert(protoNumber, p->shortName()); - nameToNumberMap.insert(p->shortName(), protoNumber); + numberToNameMap.insert(protoNumber, p->shortName()); + nameToNumberMap.insert(p->shortName(), protoNumber); } void ProtocolManager::populateNeighbourProtocols() { - neighbourProtocols.clear(); + neighbourProtocols.clear(); - foreach(AbstractProtocol *p, protocolList) - { - if (p->protocolIdType() != AbstractProtocol::ProtocolIdNone) - { - foreach(AbstractProtocol *q, protocolList) - { - if (q->protocolId(p->protocolIdType())) - neighbourProtocols.insert( - p->protocolNumber(), q->protocolNumber()); - } - } - } + foreach(AbstractProtocol *p, protocolList) + { + if (p->protocolIdType() != AbstractProtocol::ProtocolIdNone) + { + foreach(AbstractProtocol *q, protocolList) + { + if (q->protocolId(p->protocolIdType())) + neighbourProtocols.insert( + p->protocolNumber(), q->protocolNumber()); + } + } + } } AbstractProtocol* ProtocolManager::createProtocol(int protoNumber, - StreamBase *stream, AbstractProtocol *parent) + StreamBase *stream, AbstractProtocol *parent) { - AbstractProtocol* (*pc)(StreamBase*, AbstractProtocol*); - AbstractProtocol* p; + AbstractProtocol* (*pc)(StreamBase*, AbstractProtocol*); + AbstractProtocol* p; - pc = (AbstractProtocol* (*)(StreamBase*, AbstractProtocol*)) - factory.value(protoNumber); - - Q_ASSERT(pc != NULL); + pc = (AbstractProtocol* (*)(StreamBase*, AbstractProtocol*)) + factory.value(protoNumber); + + Q_ASSERT(pc != NULL); - p = (*pc)(stream, parent); + p = (*pc)(stream, parent); - return p; + return p; } AbstractProtocol* ProtocolManager::createProtocol(QString protoName, - StreamBase *stream, AbstractProtocol *parent) + StreamBase *stream, AbstractProtocol *parent) { - return createProtocol(nameToNumberMap.value(protoName), stream, parent); + return createProtocol(nameToNumberMap.value(protoName), stream, parent); } bool ProtocolManager::isValidNeighbour(int protoPrefix, int protoSuffix) { - if (neighbourProtocols.contains(protoPrefix, protoSuffix)) - return true; - else - return false; + if (neighbourProtocols.contains(protoPrefix, protoSuffix)) + return true; + else + return false; } QStringList ProtocolManager::protocolDatabase() { - return numberToNameMap.values(); + return numberToNameMap.values(); } diff --git a/common/protocolmanager.h b/common/protocolmanager.h index c619099..86ccf5d 100644 --- a/common/protocolmanager.h +++ b/common/protocolmanager.h @@ -9,27 +9,27 @@ class StreamBase; class ProtocolManager { - QMap numberToNameMap; - QMap nameToNumberMap; - QMultiMap neighbourProtocols; - QMap factory; - QList protocolList; + QMap numberToNameMap; + QMap nameToNumberMap; + QMultiMap neighbourProtocols; + QMap factory; + QList protocolList; - void populateNeighbourProtocols(); + void populateNeighbourProtocols(); public: - ProtocolManager(); + ProtocolManager(); - void registerProtocol(int protoNumber, void *protoInstanceCreator); + void registerProtocol(int protoNumber, void *protoInstanceCreator); - AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream, - AbstractProtocol *parent = 0); - AbstractProtocol* createProtocol(QString protoName, StreamBase *stream, - AbstractProtocol *parent = 0); + AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream, + AbstractProtocol *parent = 0); + AbstractProtocol* createProtocol(QString protoName, StreamBase *stream, + AbstractProtocol *parent = 0); - bool isValidNeighbour(int protoPrefix, int protoSuffix); + bool isValidNeighbour(int protoPrefix, int protoSuffix); - QStringList protocolDatabase(); + QStringList protocolDatabase(); }; #endif diff --git a/common/sample.cpp b/common/sample.cpp index 2477908..00a65e6 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -3,54 +3,54 @@ #include "sample.h" SampleConfigForm::SampleConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); } SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } SampleProtocol::~SampleProtocol() { - delete configForm; + delete configForm; } AbstractProtocol* SampleProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new SampleProtocol(stream, parent); + return new SampleProtocol(stream, parent); } quint32 SampleProtocol::protocolNumber() const { - return OstProto::Protocol::kSampleFieldNumber; + return OstProto::Protocol::kSampleFieldNumber; } void SampleProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::sample)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::sample)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void SampleProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::sample)) - data.MergeFrom(protocol.GetExtension(OstProto::sample)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::sample)) + data.MergeFrom(protocol.GetExtension(OstProto::sample)); } QString SampleProtocol::name() const { - return QString("Sample Protocol"); + return QString("Sample Protocol"); } QString SampleProtocol::shortName() const { - return QString("SAMPLE"); + return QString("SAMPLE"); } /*! @@ -62,7 +62,7 @@ QString SampleProtocol::shortName() const */ AbstractProtocol::ProtocolIdType SampleProtocol::protocolIdType() const { - return ProtocolIdIp; + return ProtocolIdIp; } /*! @@ -75,314 +75,314 @@ AbstractProtocol::ProtocolIdType SampleProtocol::protocolIdType() const */ quint32 SampleProtocol::protocolId(ProtocolIdType type) const { - switch(type) - { - case ProtocolIdIp: return 1234; - default:break; - } + switch(type) + { + case ProtocolIdIp: return 1234; + default:break; + } - return AbstractProtocol::protocolId(type); + return AbstractProtocol::protocolId(type); } -int SampleProtocol::fieldCount() const +int SampleProtocol::fieldCount() const { - return sample_fieldCount; + return sample_fieldCount; } AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const { - AbstractProtocol::FieldFlags flags; + AbstractProtocol::FieldFlags flags; - flags = AbstractProtocol::fieldFlags(index); + flags = AbstractProtocol::fieldFlags(index); - switch (index) - { - case sample_a: - case sample_b: - case sample_payloadLength: - break; + switch (index) + { + case sample_a: + case sample_b: + case sample_payloadLength: + break; - case sample_checksum: - flags |= FieldIsCksum; - break; + case sample_checksum: + flags |= FieldIsCksum; + break; - case sample_x: - case sample_y: - break; + case sample_x: + case sample_y: + break; - case sample_is_override_checksum: - flags |= FieldIsMeta; - break; + case sample_is_override_checksum: + flags |= FieldIsMeta; + break; - default: - qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, - index); - break; - } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } - return flags; + return flags; } QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case sample_a: - { - int a = data.ab() >> 13; + switch (index) + { + case sample_a: + { + int a = data.ab() >> 13; - switch(attrib) - { - case FieldName: - return QString("A"); - case FieldValue: - return a; - case FieldTextValue: - return QString("%1").arg(a); - case FieldFrameValue: - return QByteArray(1, (char) a); - case FieldBitSize: - return 3; - default: - break; - } - break; + switch(attrib) + { + case FieldName: + return QString("A"); + case FieldValue: + return a; + case FieldTextValue: + return QString("%1").arg(a); + case FieldFrameValue: + return QByteArray(1, (char) a); + case FieldBitSize: + return 3; + default: + break; + } + break; - } - case sample_b: - { - int b = data.ab() & 0x1FFF; + } + case sample_b: + { + int b = data.ab() & 0x1FFF; - switch(attrib) - { - case FieldName: - return QString("B"); - case FieldValue: - return b; - case FieldTextValue: - return QString("%1").arg(b, 4, BASE_HEX, QChar('0')); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) b, (uchar*) fv.data()); - return fv; - } - case FieldBitSize: - return 13; - default: - break; - } - break; - } + switch(attrib) + { + case FieldName: + return QString("B"); + case FieldValue: + return b; + case FieldTextValue: + return QString("%1").arg(b, 4, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) b, (uchar*) fv.data()); + return fv; + } + case FieldBitSize: + return 13; + default: + break; + } + break; + } - case sample_payloadLength: - { - switch(attrib) - { - case FieldName: - return QString("Payload Length"); - case FieldValue: - return protocolFramePayloadSize(streamIndex); - case FieldFrameValue: - { - QByteArray fv; - int totlen; - totlen = protocolFramePayloadSize(streamIndex); - fv.resize(2); - qToBigEndian((quint16) totlen, (uchar*) fv.data()); - return fv; - } - case FieldTextValue: - return QString("%1").arg( - protocolFramePayloadSize(streamIndex)); - case FieldBitSize: - return 16; - default: - break; - } - break; - } - case sample_checksum: - { - quint16 cksum; + case sample_payloadLength: + { + switch(attrib) + { + case FieldName: + return QString("Payload Length"); + case FieldValue: + return protocolFramePayloadSize(streamIndex); + case FieldFrameValue: + { + QByteArray fv; + int totlen; + totlen = protocolFramePayloadSize(streamIndex); + fv.resize(2); + qToBigEndian((quint16) totlen, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("%1").arg( + protocolFramePayloadSize(streamIndex)); + case FieldBitSize: + return 16; + default: + break; + } + break; + } + case sample_checksum: + { + quint16 cksum; - switch(attrib) - { - case FieldValue: - case FieldFrameValue: - case FieldTextValue: - { - if (data.is_override_checksum()) - cksum = data.checksum(); - else - cksum = protocolFrameCksum(streamIndex, CksumIp); - } - default: - break; - } + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + { + if (data.is_override_checksum()) + cksum = data.checksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumIp); + } + default: + break; + } - switch(attrib) - { - case FieldName: - return QString("Checksum"); - case FieldValue: - return cksum; - case FieldFrameValue: - { - QByteArray fv; + switch(attrib) + { + case FieldName: + return QString("Checksum"); + case FieldValue: + return cksum; + case FieldFrameValue: + { + QByteArray fv; - fv.resize(2); - qToBigEndian(cksum, (uchar*) fv.data()); - return fv; - } - case FieldTextValue: - return QString("0x%1").arg( - cksum, 4, BASE_HEX, QChar('0'));; - case FieldBitSize: - return 16; - default: - break; - } - break; - } - case sample_x: - { - switch(attrib) - { - case FieldName: - return QString("X"); - case FieldValue: - return data.x(); - case FieldTextValue: - return QString("%1").arg(data.x()); - //return QString("%1").arg(data.x(), 8, BASE_HEX, QChar('0')); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(4); - qToBigEndian((quint32) data.x(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; - } - case sample_y: - { - switch(attrib) - { - case FieldName: - return QString("Y"); - case FieldValue: - return data.y(); - case FieldTextValue: - //return QString("%1").arg(data.y()); - return QString("%1").arg(data.y(), 8, BASE_HEX, QChar('0')); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(4); - qToBigEndian((quint32) data.y(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; - } + fv.resize(2); + qToBigEndian(cksum, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("0x%1").arg( + cksum, 4, BASE_HEX, QChar('0'));; + case FieldBitSize: + return 16; + default: + break; + } + break; + } + case sample_x: + { + switch(attrib) + { + case FieldName: + return QString("X"); + case FieldValue: + return data.x(); + case FieldTextValue: + return QString("%1").arg(data.x()); + //return QString("%1").arg(data.x(), 8, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.x(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + case sample_y: + { + switch(attrib) + { + case FieldName: + return QString("Y"); + case FieldValue: + return data.y(); + case FieldTextValue: + //return QString("%1").arg(data.y()); + return QString("%1").arg(data.y(), 8, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.y(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } - // Meta fields - case sample_is_override_checksum: - { - switch(attrib) - { - case FieldValue: - return data.is_override_checksum(); - default: - break; - } - break; - } - default: - qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, - index); - break; - } + // Meta fields + case sample_is_override_checksum: + { + switch(attrib) + { + case FieldValue: + return data.is_override_checksum(); + default: + break; + } + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool SampleProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - bool isOk = false; + bool isOk = false; - if (attrib != FieldValue) - goto _exit; + if (attrib != FieldValue) + goto _exit; - switch (index) - { - case sample_a: - { - uint a = value.toUInt(&isOk); - if (isOk) - data.set_ab((data.ab() & 0xe000) | (a << 13)); - break; - } - case sample_b: - { - uint b = value.toUInt(&isOk); - if (isOk) - data.set_ab((data.ab() & 0x1FFF) | b); - break; - } - case sample_payloadLength: - { - uint len = value.toUInt(&isOk); - if (isOk) - data.set_payload_length(len); - break; - } - case sample_checksum: - { - uint csum = value.toUInt(&isOk); - if (isOk) - data.set_checksum(csum); - break; - } - case sample_x: - { - uint x = value.toUInt(&isOk); - if (isOk) - data.set_x(x); - break; - } - case sample_y: - { - uint y = value.toUInt(&isOk); - if (isOk) - data.set_y(y); - break; - } - case sample_is_override_checksum: - { - bool ovr = value.toBool(); - data.set_is_override_checksum(ovr); - isOk = true; - break; - } - default: - qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, - index); - break; - } + switch (index) + { + case sample_a: + { + uint a = value.toUInt(&isOk); + if (isOk) + data.set_ab((data.ab() & 0xe000) | (a << 13)); + break; + } + case sample_b: + { + uint b = value.toUInt(&isOk); + if (isOk) + data.set_ab((data.ab() & 0x1FFF) | b); + break; + } + case sample_payloadLength: + { + uint len = value.toUInt(&isOk); + if (isOk) + data.set_payload_length(len); + break; + } + case sample_checksum: + { + uint csum = value.toUInt(&isOk); + if (isOk) + data.set_checksum(csum); + break; + } + case sample_x: + { + uint x = value.toUInt(&isOk); + if (isOk) + data.set_x(x); + break; + } + case sample_y: + { + uint y = value.toUInt(&isOk); + if (isOk) + data.set_y(y); + break; + } + case sample_is_override_checksum: + { + bool ovr = value.toBool(); + data.set_is_override_checksum(ovr); + isOk = true; + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } _exit: - return isOk; + return isOk; } /*! @@ -393,7 +393,7 @@ _exit: */ int SampleProtocol::protocolFrameSize(int streamIndex) const { - return AbstractProtocol::protocolFrameSize(streamIndex); + return AbstractProtocol::protocolFrameSize(streamIndex); } /*! @@ -404,7 +404,7 @@ int SampleProtocol::protocolFrameSize(int streamIndex) const */ bool SampleProtocol::isProtocolFrameValueVariable() const { - return false; + return false; } /*! @@ -416,54 +416,54 @@ bool SampleProtocol::isProtocolFrameValueVariable() const */ bool SampleProtocol::isProtocolFrameSizeVariable() const { - return false; + return false; } QWidget* SampleProtocol::configWidget() { - if (configForm == NULL) - { - configForm = new SampleConfigForm; - loadConfigWidget(); - } + if (configForm == NULL) + { + configForm = new SampleConfigForm; + loadConfigWidget(); + } - return configForm; + return configForm; } void SampleProtocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->sampleA->setText(fieldData(sample_a, FieldValue).toString()); - configForm->sampleB->setText(fieldData(sample_b, FieldValue).toString()); + configForm->sampleA->setText(fieldData(sample_a, FieldValue).toString()); + configForm->sampleB->setText(fieldData(sample_b, FieldValue).toString()); - configForm->samplePayloadLength->setText( - fieldData(sample_payloadLength, FieldValue).toString()); + configForm->samplePayloadLength->setText( + fieldData(sample_payloadLength, FieldValue).toString()); - configForm->isChecksumOverride->setChecked( - fieldData(sample_is_override_checksum, FieldValue).toBool()); - configForm->sampleChecksum->setText(uintToHexStr( - fieldData(sample_checksum, FieldValue).toUInt(), 2)); + configForm->isChecksumOverride->setChecked( + fieldData(sample_is_override_checksum, FieldValue).toBool()); + configForm->sampleChecksum->setText(uintToHexStr( + fieldData(sample_checksum, FieldValue).toUInt(), 2)); - configForm->sampleX->setText(fieldData(sample_x, FieldValue).toString()); - configForm->sampleY->setText(fieldData(sample_y, FieldValue).toString()); + configForm->sampleX->setText(fieldData(sample_x, FieldValue).toString()); + configForm->sampleY->setText(fieldData(sample_y, FieldValue).toString()); } void SampleProtocol::storeConfigWidget() { - bool isOk; + bool isOk; - configWidget(); - setFieldData(sample_a, configForm->sampleA->text()); - setFieldData(sample_b, configForm->sampleB->text()); + configWidget(); + setFieldData(sample_a, configForm->sampleA->text()); + setFieldData(sample_b, configForm->sampleB->text()); - setFieldData(sample_payloadLength, configForm->samplePayloadLength->text()); - setFieldData(sample_is_override_checksum, - configForm->isChecksumOverride->isChecked()); - setFieldData(sample_checksum, configForm->sampleChecksum->text().toUInt(&isOk, BASE_HEX)); + setFieldData(sample_payloadLength, configForm->samplePayloadLength->text()); + setFieldData(sample_is_override_checksum, + configForm->isChecksumOverride->isChecked()); + setFieldData(sample_checksum, configForm->sampleChecksum->text().toUInt(&isOk, BASE_HEX)); - setFieldData(sample_x, configForm->sampleX->text()); - setFieldData(sample_y, configForm->sampleY->text()); + setFieldData(sample_x, configForm->sampleX->text()); + setFieldData(sample_y, configForm->sampleY->text()); } diff --git a/common/sample.h b/common/sample.h index a0e0ad3..55f549e 100644 --- a/common/sample.h +++ b/common/sample.h @@ -9,74 +9,74 @@ /* Sample Protocol Frame Format - +-----+------+------+------+------+------+ - | A | B | LEN | CSUM | X | Y | - | (3) | (13) | (16) | (16) | (32) | (32) | + | A | B | LEN | CSUM | X | Y | + | (3) | (13) | (16) | (16) | (32) | (32) | +-----+------+------+------+------+------+ Figures in brackets represent field width in bits */ class SampleConfigForm : public QWidget, public Ui::Sample { - Q_OBJECT + Q_OBJECT public: - SampleConfigForm(QWidget *parent = 0); + SampleConfigForm(QWidget *parent = 0); private slots: }; class SampleProtocol : public AbstractProtocol { private: - OstProto::Sample data; - SampleConfigForm *configForm; - enum samplefield - { - // Frame Fields - sample_a = 0, - sample_b, - sample_payloadLength, - sample_checksum, - sample_x, - sample_y, + OstProto::Sample data; + SampleConfigForm *configForm; + enum samplefield + { + // Frame Fields + sample_a = 0, + sample_b, + sample_payloadLength, + sample_checksum, + sample_x, + sample_y, - // Meta Fields - sample_is_override_checksum, + // Meta Fields + sample_is_override_checksum, - sample_fieldCount - }; + sample_fieldCount + }; public: - SampleProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~SampleProtocol(); + SampleProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~SampleProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual ProtocolIdType protocolIdType() const; - virtual quint32 protocolId(ProtocolIdType type) const; + virtual ProtocolIdType protocolIdType() const; + virtual quint32 protocolId(ProtocolIdType type) const; - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual int protocolFrameSize(int streamIndex = 0) const; + virtual int protocolFrameSize(int streamIndex = 0) const; - virtual bool isProtocolFrameValueVariable() const; - virtual bool isProtocolFrameSizeVariable() const; + virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameSizeVariable() const; - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/sample.proto b/common/sample.proto index 76213d4..16d4daf 100644 --- a/common/sample.proto +++ b/common/sample.proto @@ -5,15 +5,15 @@ package OstProto; // Sample Protocol message Sample { - optional bool is_override_checksum = 1; + optional bool is_override_checksum = 1; - optional uint32 ab = 2; - optional uint32 payload_length = 3; - optional uint32 checksum = 4; - optional uint32 x = 5 [default = 1234]; - optional uint32 y = 6; + optional uint32 ab = 2; + optional uint32 payload_length = 3; + optional uint32 checksum = 4; + optional uint32 x = 5 [default = 1234]; + optional uint32 y = 6; } extend Protocol { - optional Sample sample = 53; + optional Sample sample = 53; } diff --git a/common/snap.cpp b/common/snap.cpp index 0f7d477..3eaab91 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -4,171 +4,171 @@ #include "snap.h" SnapConfigForm::SnapConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); } SnapProtocol::SnapProtocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } SnapProtocol::~SnapProtocol() { - delete configForm; + delete configForm; } AbstractProtocol* SnapProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new SnapProtocol(stream, parent); + return new SnapProtocol(stream, parent); } quint32 SnapProtocol::protocolNumber() const { - return OstProto::Protocol::kSnapFieldNumber; + return OstProto::Protocol::kSnapFieldNumber; } void SnapProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::snap)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::snap)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void SnapProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::snap)) - data.MergeFrom(protocol.GetExtension(OstProto::snap)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::snap)) + data.MergeFrom(protocol.GetExtension(OstProto::snap)); } QString SnapProtocol::name() const { - return QString("SubNetwork Access Protocol"); + return QString("SubNetwork Access Protocol"); } QString SnapProtocol::shortName() const { - return QString("SNAP"); + return QString("SNAP"); } AbstractProtocol::ProtocolIdType SnapProtocol::protocolIdType() const { - return ProtocolIdEth; + return ProtocolIdEth; } quint32 SnapProtocol::protocolId(ProtocolIdType type) const { - switch(type) - { - case ProtocolIdLlc: return 0xAAAA03; - default: break; - } + switch(type) + { + case ProtocolIdLlc: return 0xAAAA03; + default: break; + } - return AbstractProtocol::protocolId(type); + return AbstractProtocol::protocolId(type); } -int SnapProtocol::fieldCount() const +int SnapProtocol::fieldCount() const { - return snap_fieldCount; + return snap_fieldCount; } QVariant SnapProtocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case snap_oui: - switch(attrib) - { - case FieldName: - return QString("OUI"); - case FieldValue: - return data.oui(); - case FieldTextValue: - return QString("%1").arg(data.oui(), 6, BASE_HEX, QChar('0')); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(4); - qToBigEndian((quint32) data.oui(), (uchar*) fv.data()); - fv.remove(0, 1); - return fv; - } - default: - break; - } - break; - case snap_type: - { - quint16 type; + switch (index) + { + case snap_oui: + switch(attrib) + { + case FieldName: + return QString("OUI"); + case FieldValue: + return data.oui(); + case FieldTextValue: + return QString("%1").arg(data.oui(), 6, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.oui(), (uchar*) fv.data()); + fv.remove(0, 1); + return fv; + } + default: + break; + } + break; + case snap_type: + { + quint16 type; - switch(attrib) - { - case FieldName: - return QString("Type"); - case FieldValue: - type = payloadProtocolId(ProtocolIdEth); - return type; - case FieldTextValue: - type = payloadProtocolId(ProtocolIdEth); - return QString("%1").arg(type, 4, BASE_HEX, QChar('0')); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - type = payloadProtocolId(ProtocolIdEth); - qToBigEndian(type, (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; - } - default: - break; - } + switch(attrib) + { + case FieldName: + return QString("Type"); + case FieldValue: + type = payloadProtocolId(ProtocolIdEth); + return type; + case FieldTextValue: + type = payloadProtocolId(ProtocolIdEth); + return QString("%1").arg(type, 4, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + type = payloadProtocolId(ProtocolIdEth); + qToBigEndian(type, (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool SnapProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - return false; + return false; } QWidget* SnapProtocol::configWidget() { - if (configForm == NULL) - { - configForm = new SnapConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new SnapConfigForm; + loadConfigWidget(); + } + return configForm; } void SnapProtocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->leOui->setText(uintToHexStr( - fieldData(snap_oui, FieldValue).toUInt(), 3)); - configForm->leType->setText(uintToHexStr( - fieldData(snap_type, FieldValue).toUInt(), 2)); + configForm->leOui->setText(uintToHexStr( + fieldData(snap_oui, FieldValue).toUInt(), 3)); + configForm->leType->setText(uintToHexStr( + fieldData(snap_type, FieldValue).toUInt(), 2)); } void SnapProtocol::storeConfigWidget() { - bool isOk; + bool isOk; - configWidget(); + configWidget(); - data.set_oui(configForm->leOui->text().toULong(&isOk, BASE_HEX)); - data.set_type(configForm->leType->text().toULong(&isOk, BASE_HEX)); + data.set_oui(configForm->leOui->text().toULong(&isOk, BASE_HEX)); + data.set_type(configForm->leType->text().toULong(&isOk, BASE_HEX)); } diff --git a/common/snap.h b/common/snap.h index c4018ad..42eae0c 100644 --- a/common/snap.h +++ b/common/snap.h @@ -8,51 +8,51 @@ class SnapConfigForm : public QWidget, public Ui::snap { - Q_OBJECT + Q_OBJECT public: - SnapConfigForm(QWidget *parent = 0); + SnapConfigForm(QWidget *parent = 0); }; class SnapProtocol : public AbstractProtocol { private: - OstProto::Snap data; - SnapConfigForm *configForm; - enum snapfield - { - snap_oui = 0, - snap_type, + OstProto::Snap data; + SnapConfigForm *configForm; + enum snapfield + { + snap_oui = 0, + snap_type, - snap_fieldCount - }; + snap_fieldCount + }; public: - SnapProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~SnapProtocol(); + SnapProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~SnapProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; - virtual ProtocolIdType protocolIdType() const; - virtual quint32 protocolId(ProtocolIdType type) const; + virtual ProtocolIdType protocolIdType() const; + virtual quint32 protocolId(ProtocolIdType type) const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/snap.proto b/common/snap.proto index 957c213..7ac3254 100644 --- a/common/snap.proto +++ b/common/snap.proto @@ -3,10 +3,10 @@ import "protocol.proto"; package OstProto; message Snap { - optional uint32 oui = 1; - optional uint32 type = 2; + optional uint32 oui = 1; + optional uint32 type = 2; } extend Protocol { - optional Snap snap = 124; + optional Snap snap = 124; } diff --git a/common/streambase.cpp b/common/streambase.cpp index 5bd2dcb..e40f009 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -7,373 +7,373 @@ extern ProtocolManager OstProtocolManager; StreamBase::StreamBase() : - mStreamId(new OstProto::StreamId), - mCore(new OstProto::StreamCore), - mControl(new OstProto::StreamControl) + mStreamId(new OstProto::StreamId), + mCore(new OstProto::StreamCore), + mControl(new OstProto::StreamControl) { - AbstractProtocol *proto; - ProtocolListIterator *iter; + AbstractProtocol *proto; + ProtocolListIterator *iter; - mStreamId->set_id(0xFFFFFFFF); + mStreamId->set_id(0xFFFFFFFF); - currentFrameProtocols = new ProtocolList; + currentFrameProtocols = new ProtocolList; - iter = createProtocolListIterator(); - // By default newly created streams have the mac and payload protocols - proto = OstProtocolManager.createProtocol( - OstProto::Protocol::kMacFieldNumber, this); - iter->insert(proto); - qDebug("stream: mac = %p", proto); + iter = createProtocolListIterator(); + // By default newly created streams have the mac and payload protocols + proto = OstProtocolManager.createProtocol( + OstProto::Protocol::kMacFieldNumber, this); + iter->insert(proto); + qDebug("stream: mac = %p", proto); - proto = OstProtocolManager.createProtocol( - OstProto::Protocol::kPayloadFieldNumber, this); - iter->insert(proto); - qDebug("stream: payload = %p", proto); + proto = OstProtocolManager.createProtocol( + OstProto::Protocol::kPayloadFieldNumber, this); + iter->insert(proto); + qDebug("stream: payload = %p", proto); - { - iter->toFront(); - while (iter->hasNext()) - { - qDebug("{{%p}}", iter->next()); - // qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber()); - } - iter->toFront(); - while (iter->hasNext()) - { - qDebug("{[%d]}", iter->next()->protocolNumber()); - // qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber()); - } - } + { + iter->toFront(); + while (iter->hasNext()) + { + qDebug("{{%p}}", iter->next()); + // qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber()); + } + iter->toFront(); + while (iter->hasNext()) + { + qDebug("{[%d]}", iter->next()->protocolNumber()); + // qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber()); + } + } - delete iter; + delete iter; } StreamBase::~StreamBase() { - delete mStreamId; - delete mCore; - delete mControl; + delete mStreamId; + delete mCore; + delete mControl; } void StreamBase::protoDataCopyFrom(const OstProto::Stream &stream) { - AbstractProtocol *proto; - ProtocolListIterator *iter; + AbstractProtocol *proto; + ProtocolListIterator *iter; - mStreamId->CopyFrom(stream.stream_id()); - mCore->CopyFrom(stream.core()); - mControl->CopyFrom(stream.control()); + mStreamId->CopyFrom(stream.stream_id()); + mCore->CopyFrom(stream.core()); + mControl->CopyFrom(stream.control()); - currentFrameProtocols->destroy(); - iter = createProtocolListIterator(); - for (int i=0; i < stream.protocol_size(); i++) - { - proto = OstProtocolManager.createProtocol( - stream.protocol(i).protocol_id().id(), this); - proto->protoDataCopyFrom(stream.protocol(i)); - iter->insert(proto); - } + currentFrameProtocols->destroy(); + iter = createProtocolListIterator(); + for (int i=0; i < stream.protocol_size(); i++) + { + proto = OstProtocolManager.createProtocol( + stream.protocol(i).protocol_id().id(), this); + proto->protoDataCopyFrom(stream.protocol(i)); + iter->insert(proto); + } - delete iter; + delete iter; } void StreamBase::protoDataCopyInto(OstProto::Stream &stream) const { - stream.mutable_stream_id()->CopyFrom(*mStreamId); - stream.mutable_core()->CopyFrom(*mCore); - stream.mutable_control()->CopyFrom(*mControl); + stream.mutable_stream_id()->CopyFrom(*mStreamId); + stream.mutable_core()->CopyFrom(*mCore); + stream.mutable_control()->CopyFrom(*mControl); - stream.clear_protocol(); - foreach (const AbstractProtocol* proto, *currentFrameProtocols) - { - OstProto::Protocol *p; + stream.clear_protocol(); + foreach (const AbstractProtocol* proto, *currentFrameProtocols) + { + OstProto::Protocol *p; - p = stream.add_protocol(); - proto->protoDataCopyInto(*p); - } + p = stream.add_protocol(); + proto->protoDataCopyInto(*p); + } } #if 0 ProtocolList StreamBase::frameProtocol() { - return currentFrameProtocols; + return currentFrameProtocols; } void StreamBase::setFrameProtocol(ProtocolList protocolList) { - //currentFrameProtocols.destroy(); - currentFrameProtocols = protocolList; + //currentFrameProtocols.destroy(); + currentFrameProtocols = protocolList; } #endif ProtocolListIterator* StreamBase::createProtocolListIterator() const { - return new ProtocolListIterator(*currentFrameProtocols); + return new ProtocolListIterator(*currentFrameProtocols); } bool StreamBase::operator < (const StreamBase &s) const { - return(mCore->ordinal() < s.mCore->ordinal()); + return(mCore->ordinal() < s.mCore->ordinal()); } -quint32 StreamBase::id() +quint32 StreamBase::id() { - return mStreamId->id(); + return mStreamId->id(); } bool StreamBase::setId(quint32 id) { - mStreamId->set_id(id); - return true; + mStreamId->set_id(id); + return true; } -quint32 StreamBase::ordinal() +quint32 StreamBase::ordinal() { - return mCore->ordinal(); + return mCore->ordinal(); } -bool StreamBase::setOrdinal(quint32 ordinal) +bool StreamBase::setOrdinal(quint32 ordinal) { - mCore->set_ordinal(ordinal); - return true; + mCore->set_ordinal(ordinal); + return true; } bool StreamBase::isEnabled() const { - return mCore->is_enabled(); + return mCore->is_enabled(); } bool StreamBase::setEnabled(bool flag) { - mCore->set_is_enabled(flag); - return true; + mCore->set_is_enabled(flag); + return true; } const QString StreamBase::name() const { - return QString().fromStdString(mCore->name()); + return QString().fromStdString(mCore->name()); } bool StreamBase::setName(QString name) { - mCore->set_name(name.toStdString()); - return true; + mCore->set_name(name.toStdString()); + return true; } -StreamBase::FrameLengthMode StreamBase::lenMode() const +StreamBase::FrameLengthMode StreamBase::lenMode() const { - return (StreamBase::FrameLengthMode) mCore->len_mode(); + return (StreamBase::FrameLengthMode) mCore->len_mode(); } -bool StreamBase::setLenMode(FrameLengthMode lenMode) +bool StreamBase::setLenMode(FrameLengthMode lenMode) { - mCore->set_len_mode((OstProto::StreamCore::FrameLengthMode) lenMode); - return true; + mCore->set_len_mode((OstProto::StreamCore::FrameLengthMode) lenMode); + return true; } -quint16 StreamBase::frameLen(int streamIndex) const +quint16 StreamBase::frameLen(int streamIndex) const { - int pktLen; + int pktLen; - // Decide a frame length based on length mode - switch(lenMode()) - { - case OstProto::StreamCore::e_fl_fixed: - pktLen = mCore->frame_len(); - break; - case OstProto::StreamCore::e_fl_inc: - pktLen = frameLenMin() + (streamIndex % - (frameLenMax() - frameLenMin() + 1)); - break; - case OstProto::StreamCore::e_fl_dec: - pktLen = frameLenMax() - (streamIndex % - (frameLenMax() - frameLenMin() + 1)); - break; - case OstProto::StreamCore::e_fl_random: - //! \todo (MED) This 'random' sequence is same across iterations - qsrand(((uint) this)); - for (int i = 0; i <= streamIndex; i++) - pktLen = qrand(); - pktLen = frameLenMin() + (pktLen % - (frameLenMax() - frameLenMin() + 1)); - break; - default: - qWarning("Unhandled len mode %d. Using default 64", - lenMode()); - pktLen = 64; - break; - } + // Decide a frame length based on length mode + switch(lenMode()) + { + case OstProto::StreamCore::e_fl_fixed: + pktLen = mCore->frame_len(); + break; + case OstProto::StreamCore::e_fl_inc: + pktLen = frameLenMin() + (streamIndex % + (frameLenMax() - frameLenMin() + 1)); + break; + case OstProto::StreamCore::e_fl_dec: + pktLen = frameLenMax() - (streamIndex % + (frameLenMax() - frameLenMin() + 1)); + break; + case OstProto::StreamCore::e_fl_random: + //! \todo (MED) This 'random' sequence is same across iterations + qsrand(((uint) this)); + for (int i = 0; i <= streamIndex; i++) + pktLen = qrand(); + pktLen = frameLenMin() + (pktLen % + (frameLenMax() - frameLenMin() + 1)); + break; + default: + qWarning("Unhandled len mode %d. Using default 64", + lenMode()); + pktLen = 64; + break; + } - return pktLen; + return pktLen; } bool StreamBase::setFrameLen(quint16 frameLen) { - mCore->set_frame_len(frameLen); - return true; + mCore->set_frame_len(frameLen); + return true; } -quint16 StreamBase::frameLenMin() const +quint16 StreamBase::frameLenMin() const { - return mCore->frame_len_min(); + return mCore->frame_len_min(); } bool StreamBase::setFrameLenMin(quint16 frameLenMin) { - mCore->set_frame_len_min(frameLenMin); - return true; + mCore->set_frame_len_min(frameLenMin); + return true; } -quint16 StreamBase::frameLenMax() const +quint16 StreamBase::frameLenMax() const { - return mCore->frame_len_max(); + return mCore->frame_len_max(); } bool StreamBase::setFrameLenMax(quint16 frameLenMax) { - mCore->set_frame_len_max(frameLenMax); - return true; + mCore->set_frame_len_max(frameLenMax); + return true; } StreamBase::SendUnit StreamBase::sendUnit() const { - return (StreamBase::SendUnit) mControl->unit(); + return (StreamBase::SendUnit) mControl->unit(); } bool StreamBase::setSendUnit(SendUnit sendUnit) { - mControl->set_unit((OstProto::StreamControl::SendUnit) sendUnit); - return true; + mControl->set_unit((OstProto::StreamControl::SendUnit) sendUnit); + return true; } StreamBase::SendMode StreamBase::sendMode() const { - return (StreamBase::SendMode) mControl->mode(); + return (StreamBase::SendMode) mControl->mode(); } bool StreamBase::setSendMode(SendMode sendMode) { - mControl->set_mode( - (OstProto::StreamControl::SendMode) sendMode); - return true; + mControl->set_mode( + (OstProto::StreamControl::SendMode) sendMode); + return true; } StreamBase::NextWhat StreamBase::nextWhat() const { - return (StreamBase::NextWhat) mControl->next(); + return (StreamBase::NextWhat) mControl->next(); } bool StreamBase::setNextWhat(NextWhat nextWhat) { - mControl->set_next((OstProto::StreamControl::NextWhat) nextWhat); - return true; + mControl->set_next((OstProto::StreamControl::NextWhat) nextWhat); + return true; } quint32 StreamBase::numPackets() const { - return (quint32) mControl->num_packets(); + return (quint32) mControl->num_packets(); } bool StreamBase::setNumPackets(quint32 numPackets) { - mControl->set_num_packets(numPackets); - return true; + mControl->set_num_packets(numPackets); + return true; } quint32 StreamBase::numBursts() const { - return (quint32) mControl->num_bursts(); + return (quint32) mControl->num_bursts(); } bool StreamBase::setNumBursts(quint32 numBursts) { - mControl->set_num_bursts(numBursts); - return true; + mControl->set_num_bursts(numBursts); + return true; } quint32 StreamBase::burstSize() const { - return (quint32) mControl->packets_per_burst(); + return (quint32) mControl->packets_per_burst(); } bool StreamBase::setBurstSize(quint32 packetsPerBurst) { - mControl->set_packets_per_burst(packetsPerBurst); - return true; + mControl->set_packets_per_burst(packetsPerBurst); + return true; } quint32 StreamBase::packetRate() const { - return (quint32) mControl->packets_per_sec(); + return (quint32) mControl->packets_per_sec(); } bool StreamBase::setPacketRate(quint32 packetsPerSec) { - mControl->set_packets_per_sec(packetsPerSec); - return true; + mControl->set_packets_per_sec(packetsPerSec); + return true; } quint32 StreamBase::burstRate() const { - return (quint32) mControl->bursts_per_sec(); + return (quint32) mControl->bursts_per_sec(); } bool StreamBase::setBurstRate(quint32 burstsPerSec) { - mControl->set_bursts_per_sec(burstsPerSec); - return true; + mControl->set_bursts_per_sec(burstsPerSec); + return true; } bool StreamBase::isFrameVariable() const { - ProtocolListIterator *iter; + ProtocolListIterator *iter; - iter = createProtocolListIterator(); - while (iter->hasNext()) - { - AbstractProtocol *proto; + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol *proto; - proto = iter->next(); - if (proto->isProtocolFrameValueVariable()) - goto _exit; - } - delete iter; - return false; + proto = iter->next(); + if (proto->isProtocolFrameValueVariable()) + goto _exit; + } + delete iter; + return false; _exit: - delete iter; - return true; + delete iter; + return true; } int StreamBase::frameValue(uchar *buf, int bufMaxSize, int n) const { - int pktLen, len = 0; + int pktLen, len = 0; - pktLen = frameLen(n); + pktLen = frameLen(n); - // pktLen is adjusted for CRC/FCS which will be added by the NIC - pktLen -= 4; + // pktLen is adjusted for CRC/FCS which will be added by the NIC + pktLen -= 4; - if ((pktLen < 0) || (pktLen > bufMaxSize)) - return 0; + if ((pktLen < 0) || (pktLen > bufMaxSize)) + return 0; - ProtocolListIterator *iter; + ProtocolListIterator *iter; - iter = createProtocolListIterator(); - while (iter->hasNext()) - { - AbstractProtocol *proto; - QByteArray ba; + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol *proto; + QByteArray ba; - proto = iter->next(); - ba = proto->protocolFrameValue(n); + proto = iter->next(); + ba = proto->protocolFrameValue(n); - if (len + ba.size() < bufMaxSize) - memcpy(buf+len, ba.constData(), ba.size()); - len += ba.size(); - } - delete iter; + if (len + ba.size() < bufMaxSize) + memcpy(buf+len, ba.constData(), ba.size()); + len += ba.size(); + } + delete iter; - return pktLen; + return pktLen; } diff --git a/common/streambase.h b/common/streambase.h index 45f0cbb..dd30232 100644 --- a/common/streambase.h +++ b/common/streambase.h @@ -13,107 +13,107 @@ class ProtocolListIterator; class StreamBase { private: - OstProto::StreamId *mStreamId; - OstProto::StreamCore *mCore; - OstProto::StreamControl *mControl; + OstProto::StreamId *mStreamId; + OstProto::StreamCore *mCore; + OstProto::StreamControl *mControl; - ProtocolList *currentFrameProtocols; + ProtocolList *currentFrameProtocols; public: - StreamBase(); - ~StreamBase(); + StreamBase(); + ~StreamBase(); - void protoDataCopyFrom(const OstProto::Stream &stream); - void protoDataCopyInto(OstProto::Stream &stream) const; + void protoDataCopyFrom(const OstProto::Stream &stream); + void protoDataCopyInto(OstProto::Stream &stream) const; - ProtocolListIterator* createProtocolListIterator() const; + ProtocolListIterator* createProtocolListIterator() const; - //! \todo (LOW) should we have a copy constructor?? + //! \todo (LOW) should we have a copy constructor?? public: - enum FrameLengthMode { - e_fl_fixed, - e_fl_inc, - e_fl_dec, - e_fl_random - }; + enum FrameLengthMode { + e_fl_fixed, + e_fl_inc, + e_fl_dec, + e_fl_random + }; - enum SendUnit { - e_su_packets, - e_su_bursts - }; + enum SendUnit { + e_su_packets, + e_su_bursts + }; - enum SendMode { - e_sm_fixed, - e_sm_continuous - }; + enum SendMode { + e_sm_fixed, + e_sm_continuous + }; - enum NextWhat { - e_nw_stop, - e_nw_goto_next, - e_nw_goto_id - }; + enum NextWhat { + e_nw_stop, + e_nw_goto_next, + e_nw_goto_id + }; - bool operator < (const StreamBase &s) const; + bool operator < (const StreamBase &s) const; - quint32 id(); - bool setId(quint32 id); + quint32 id(); + bool setId(quint32 id); #if 0 // FIXME(HI): needed? - quint32 portId() - { return mCore->port_id();} - bool setPortId(quint32 id) - { mCore->set_port_id(id); return true;} + quint32 portId() + { return mCore->port_id();} + bool setPortId(quint32 id) + { mCore->set_port_id(id); return true;} #endif - quint32 ordinal(); - bool setOrdinal(quint32 ordinal); + quint32 ordinal(); + bool setOrdinal(quint32 ordinal); - bool isEnabled() const; - bool setEnabled(bool flag); + bool isEnabled() const; + bool setEnabled(bool flag); - const QString name() const ; - bool setName(QString name) ; + const QString name() const ; + bool setName(QString name) ; - // Frame Length (includes FCS); - FrameLengthMode lenMode() const; - bool setLenMode(FrameLengthMode lenMode); + // Frame Length (includes FCS); + FrameLengthMode lenMode() const; + bool setLenMode(FrameLengthMode lenMode); - quint16 frameLen(int streamIndex = 0) const; - bool setFrameLen(quint16 frameLen); + quint16 frameLen(int streamIndex = 0) const; + bool setFrameLen(quint16 frameLen); - quint16 frameLenMin() const; - bool setFrameLenMin(quint16 frameLenMin); + quint16 frameLenMin() const; + bool setFrameLenMin(quint16 frameLenMin); - quint16 frameLenMax() const; - bool setFrameLenMax(quint16 frameLenMax); + quint16 frameLenMax() const; + bool setFrameLenMax(quint16 frameLenMax); - SendUnit sendUnit() const; - bool setSendUnit(SendUnit sendUnit); + SendUnit sendUnit() const; + bool setSendUnit(SendUnit sendUnit); - SendMode sendMode() const; - bool setSendMode(SendMode sendMode); + SendMode sendMode() const; + bool setSendMode(SendMode sendMode); - NextWhat nextWhat() const; - bool setNextWhat(NextWhat nextWhat); + NextWhat nextWhat() const; + bool setNextWhat(NextWhat nextWhat); - quint32 numPackets() const; - bool setNumPackets(quint32 numPackets); + quint32 numPackets() const; + bool setNumPackets(quint32 numPackets); - quint32 numBursts() const; - bool setNumBursts(quint32 numBursts); + quint32 numBursts() const; + bool setNumBursts(quint32 numBursts); - quint32 burstSize() const; - bool setBurstSize(quint32 packetsPerBurst); + quint32 burstSize() const; + bool setBurstSize(quint32 packetsPerBurst); - quint32 packetRate() const; - bool setPacketRate(quint32 packetsPerSec); + quint32 packetRate() const; + bool setPacketRate(quint32 packetsPerSec); - quint32 burstRate() const; - bool setBurstRate(quint32 burstsPerSec); + quint32 burstRate() const; + bool setBurstRate(quint32 burstsPerSec); - bool isFrameVariable() const; - int frameValue(uchar *buf, int bufMaxSize, int n) const; + bool isFrameVariable() const; + int frameValue(uchar *buf, int bufMaxSize, int n) const; }; #endif diff --git a/common/svlan.cpp b/common/svlan.cpp index 55ef836..6d30cfc 100644 --- a/common/svlan.cpp +++ b/common/svlan.cpp @@ -4,10 +4,10 @@ #include "svlan.pb.h" SVlanProtocol::SVlanProtocol(StreamBase *stream, AbstractProtocol *parent) - : VlanProtocol(stream, parent) + : VlanProtocol(stream, parent) { - data.set_tpid(0x88a8); - data.set_is_override_tpid(true); + data.set_tpid(0x88a8); + data.set_is_override_tpid(true); } SVlanProtocol::~SVlanProtocol() @@ -15,35 +15,35 @@ SVlanProtocol::~SVlanProtocol() } AbstractProtocol* SVlanProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new SVlanProtocol(stream, parent); + return new SVlanProtocol(stream, parent); } quint32 SVlanProtocol::protocolNumber() const { - return OstProto::Protocol::kSvlanFieldNumber; + return OstProto::Protocol::kSvlanFieldNumber; } void SVlanProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::svlan)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::svlan)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void SVlanProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::svlan)) - data.MergeFrom(protocol.GetExtension(OstProto::svlan)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::svlan)) + data.MergeFrom(protocol.GetExtension(OstProto::svlan)); } QString SVlanProtocol::name() const { - return QString("SVlan"); + return QString("SVlan"); } QString SVlanProtocol::shortName() const { - return QString("SVlan"); + return QString("SVlan"); } diff --git a/common/svlan.h b/common/svlan.h index 0fb4b97..3c7d673 100644 --- a/common/svlan.h +++ b/common/svlan.h @@ -6,18 +6,18 @@ class SVlanProtocol : public VlanProtocol { public: - SVlanProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~SVlanProtocol(); + SVlanProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~SVlanProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; }; #endif diff --git a/common/svlan.proto b/common/svlan.proto index 72e4557..42f45bc 100644 --- a/common/svlan.proto +++ b/common/svlan.proto @@ -4,5 +4,5 @@ import "vlan.proto"; package OstProto; extend Protocol { - optional Vlan svlan = 125; + optional Vlan svlan = 125; } diff --git a/common/tcp.cpp b/common/tcp.cpp index 6bbc271..b6990f5 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -4,458 +4,458 @@ #include "tcp.h" TcpConfigForm::TcpConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); } TcpProtocol::TcpProtocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } TcpProtocol::~TcpProtocol() { - delete configForm; + delete configForm; } AbstractProtocol* TcpProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new TcpProtocol(stream, parent); + return new TcpProtocol(stream, parent); } quint32 TcpProtocol::protocolNumber() const { - return OstProto::Protocol::kTcpFieldNumber; + return OstProto::Protocol::kTcpFieldNumber; } void TcpProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::tcp)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::tcp)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void TcpProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::tcp)) - data.MergeFrom(protocol.GetExtension(OstProto::tcp)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::tcp)) + data.MergeFrom(protocol.GetExtension(OstProto::tcp)); } QString TcpProtocol::name() const { - return QString("Transmission Control Protocol"); + return QString("Transmission Control Protocol"); } QString TcpProtocol::shortName() const { - return QString("TCP"); + return QString("TCP"); } quint32 TcpProtocol::protocolId(ProtocolIdType type) const { - switch(type) - { - case ProtocolIdIp: return 0x06; - default: break; - } + switch(type) + { + case ProtocolIdIp: return 0x06; + default: break; + } - return AbstractProtocol::protocolId(type); + return AbstractProtocol::protocolId(type); } -int TcpProtocol::fieldCount() const +int TcpProtocol::fieldCount() const { - return tcp_fieldCount; + return tcp_fieldCount; } AbstractProtocol::FieldFlags TcpProtocol::fieldFlags(int index) const { - AbstractProtocol::FieldFlags flags; + AbstractProtocol::FieldFlags flags; - flags = AbstractProtocol::fieldFlags(index); + flags = AbstractProtocol::fieldFlags(index); - switch (index) - { - case tcp_src_port: - case tcp_dst_port: - case tcp_seq_num: - case tcp_ack_num: - case tcp_hdrlen: - case tcp_rsvd: - case tcp_flags: - case tcp_window: - break; + switch (index) + { + case tcp_src_port: + case tcp_dst_port: + case tcp_seq_num: + case tcp_ack_num: + case tcp_hdrlen: + case tcp_rsvd: + case tcp_flags: + case tcp_window: + break; - case tcp_cksum: - flags |= FieldIsCksum; - break; + case tcp_cksum: + flags |= FieldIsCksum; + break; - case tcp_urg_ptr: - break; + case tcp_urg_ptr: + break; - case tcp_is_override_hdrlen: - case tcp_is_override_cksum: - flags |= FieldIsMeta; - break; + case tcp_is_override_hdrlen: + case tcp_is_override_cksum: + flags |= FieldIsMeta; + break; - default: - break; - } + default: + break; + } - return flags; + return flags; } QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case tcp_src_port: - switch(attrib) - { - case FieldName: - return QString("Source Port"); - case FieldValue: - return data.src_port(); - case FieldTextValue: - return QString("%1").arg(data.src_port()); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) data.src_port(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; + switch (index) + { + case tcp_src_port: + switch(attrib) + { + case FieldName: + return QString("Source Port"); + case FieldValue: + return data.src_port(); + case FieldTextValue: + return QString("%1").arg(data.src_port()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.src_port(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; - case tcp_dst_port: - switch(attrib) - { - case FieldName: - return QString("Destination Port"); - case FieldValue: - return data.dst_port(); - case FieldTextValue: - return QString("%1").arg(data.dst_port()); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; + case tcp_dst_port: + switch(attrib) + { + case FieldName: + return QString("Destination Port"); + case FieldValue: + return data.dst_port(); + case FieldTextValue: + return QString("%1").arg(data.dst_port()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; - case tcp_seq_num: - switch(attrib) - { - case FieldName: - return QString("Sequence Number"); - case FieldValue: - return data.seq_num(); - case FieldTextValue: - return QString("%1").arg(data.seq_num()); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(4); - qToBigEndian((quint32) data.seq_num(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; + case tcp_seq_num: + switch(attrib) + { + case FieldName: + return QString("Sequence Number"); + case FieldValue: + return data.seq_num(); + case FieldTextValue: + return QString("%1").arg(data.seq_num()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.seq_num(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; - case tcp_ack_num: - switch(attrib) - { - case FieldName: - return QString("Acknowledgement Number"); - case FieldValue: - return data.ack_num(); - case FieldTextValue: - return QString("%1").arg(data.ack_num()); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(4); - qToBigEndian((quint32) data.ack_num(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; + case tcp_ack_num: + switch(attrib) + { + case FieldName: + return QString("Acknowledgement Number"); + case FieldValue: + return data.ack_num(); + case FieldTextValue: + return QString("%1").arg(data.ack_num()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.ack_num(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; - case tcp_hdrlen: - switch(attrib) - { - case FieldName: - return QString("Header Length"); - case FieldValue: - if (data.is_override_hdrlen()) - return ((data.hdrlen_rsvd() >> 4) & 0x0F); - else - return 5; - case FieldTextValue: - if (data.is_override_hdrlen()) - return QString("%1 bytes").arg( - 4 * ((data.hdrlen_rsvd() >> 4) & 0x0F)); - else - return QString("20 bytes"); - case FieldFrameValue: - if (data.is_override_hdrlen()) - return QByteArray(1, - (char)((data.hdrlen_rsvd() >> 4) & 0x0F)); - else - return QByteArray(1, (char) 0x05); - case FieldBitSize: - return 4; - default: - break; - } - break; + case tcp_hdrlen: + switch(attrib) + { + case FieldName: + return QString("Header Length"); + case FieldValue: + if (data.is_override_hdrlen()) + return ((data.hdrlen_rsvd() >> 4) & 0x0F); + else + return 5; + case FieldTextValue: + if (data.is_override_hdrlen()) + return QString("%1 bytes").arg( + 4 * ((data.hdrlen_rsvd() >> 4) & 0x0F)); + else + return QString("20 bytes"); + case FieldFrameValue: + if (data.is_override_hdrlen()) + return QByteArray(1, + (char)((data.hdrlen_rsvd() >> 4) & 0x0F)); + else + return QByteArray(1, (char) 0x05); + case FieldBitSize: + return 4; + default: + break; + } + break; - case tcp_rsvd: - switch(attrib) - { - case FieldName: - return QString("Reserved"); - case FieldValue: - return (data.hdrlen_rsvd() & 0x0F); - case FieldTextValue: - return QString("%1").arg(data.hdrlen_rsvd() & 0x0F); - case FieldFrameValue: - return QByteArray(1, (char)(data.hdrlen_rsvd() & 0x0F)); - case FieldBitSize: - return 4; - default: - break; - } - break; + case tcp_rsvd: + switch(attrib) + { + case FieldName: + return QString("Reserved"); + case FieldValue: + return (data.hdrlen_rsvd() & 0x0F); + case FieldTextValue: + return QString("%1").arg(data.hdrlen_rsvd() & 0x0F); + case FieldFrameValue: + return QByteArray(1, (char)(data.hdrlen_rsvd() & 0x0F)); + case FieldBitSize: + return 4; + default: + break; + } + break; - case tcp_flags: - switch(attrib) - { - case FieldName: - return QString("Flags"); - case FieldValue: - return (data.flags()); - case FieldTextValue: - { - QString s; - s.append("URG: "); - s.append(data.flags() & TCP_FLAG_URG ? "1" : "0"); - s.append(" ACK: "); - s.append(data.flags() & TCP_FLAG_ACK ? "1" : "0"); - s.append(" PSH: "); - s.append(data.flags() & TCP_FLAG_PSH ? "1" : "0"); - s.append(" RST: "); - s.append(data.flags() & TCP_FLAG_RST ? "1" : "0"); - s.append(" SYN: "); - s.append(data.flags() & TCP_FLAG_SYN ? "1" : "0"); - s.append(" FIN: "); - s.append(data.flags() & TCP_FLAG_FIN ? "1" : "0"); - return s; - } - case FieldFrameValue: - return QByteArray(1, (char)(data.flags() & 0x3F)); - default: - break; - } - break; + case tcp_flags: + switch(attrib) + { + case FieldName: + return QString("Flags"); + case FieldValue: + return (data.flags()); + case FieldTextValue: + { + QString s; + s.append("URG: "); + s.append(data.flags() & TCP_FLAG_URG ? "1" : "0"); + s.append(" ACK: "); + s.append(data.flags() & TCP_FLAG_ACK ? "1" : "0"); + s.append(" PSH: "); + s.append(data.flags() & TCP_FLAG_PSH ? "1" : "0"); + s.append(" RST: "); + s.append(data.flags() & TCP_FLAG_RST ? "1" : "0"); + s.append(" SYN: "); + s.append(data.flags() & TCP_FLAG_SYN ? "1" : "0"); + s.append(" FIN: "); + s.append(data.flags() & TCP_FLAG_FIN ? "1" : "0"); + return s; + } + case FieldFrameValue: + return QByteArray(1, (char)(data.flags() & 0x3F)); + default: + break; + } + break; - case tcp_window: - switch(attrib) - { - case FieldName: - return QString("Window Size"); - case FieldValue: - return data.window(); - case FieldTextValue: - return QString("%1").arg(data.window()); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) data.window(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; + case tcp_window: + switch(attrib) + { + case FieldName: + return QString("Window Size"); + case FieldValue: + return data.window(); + case FieldTextValue: + return QString("%1").arg(data.window()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.window(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; - case tcp_cksum: - switch(attrib) - { - case FieldName: - return QString("Checksum"); - case FieldValue: - { - quint16 cksum; + case tcp_cksum: + switch(attrib) + { + case FieldName: + return QString("Checksum"); + case FieldValue: + { + quint16 cksum; - if (data.is_override_cksum()) - cksum = data.cksum(); - else - cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); - return cksum; - } - case FieldTextValue: - { - quint16 cksum; + return cksum; + } + case FieldTextValue: + { + quint16 cksum; - if (data.is_override_cksum()) - cksum = data.cksum(); - else - cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); - return QString("0x%1").arg(cksum, 4, BASE_HEX, QChar('0')); - } - case FieldFrameValue: - { - quint16 cksum; + return QString("0x%1").arg(cksum, 4, BASE_HEX, QChar('0')); + } + case FieldFrameValue: + { + quint16 cksum; - if (data.is_override_cksum()) - cksum = data.cksum(); - else - cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); - QByteArray fv; - fv.resize(2); - qToBigEndian(cksum, (uchar*) fv.data()); - return fv; - } - case FieldBitSize: - return 16; - default: - break; - } - break; + QByteArray fv; + fv.resize(2); + qToBigEndian(cksum, (uchar*) fv.data()); + return fv; + } + case FieldBitSize: + return 16; + default: + break; + } + break; - case tcp_urg_ptr: - switch(attrib) - { - case FieldName: - return QString("Urgent Pointer"); - case FieldValue: - return data.urg_ptr(); - case FieldTextValue: - return QString("%1").arg(data.urg_ptr()); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) data.urg_ptr(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; + case tcp_urg_ptr: + switch(attrib) + { + case FieldName: + return QString("Urgent Pointer"); + case FieldValue: + return data.urg_ptr(); + case FieldTextValue: + return QString("%1").arg(data.urg_ptr()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.urg_ptr(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; - // Meta fields - case tcp_is_override_hdrlen: - case tcp_is_override_cksum: - default: - break; - } + // Meta fields + case tcp_is_override_hdrlen: + case tcp_is_override_cksum: + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool TcpProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - return false; + return false; } bool TcpProtocol::isProtocolFrameValueVariable() const { - if (data.is_override_cksum()) - return false; - else - return isProtocolFramePayloadValueVariable(); + if (data.is_override_cksum()) + return false; + else + return isProtocolFramePayloadValueVariable(); } QWidget* TcpProtocol::configWidget() { - if (configForm == NULL) - { - configForm = new TcpConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new TcpConfigForm; + loadConfigWidget(); + } + return configForm; } void TcpProtocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->leTcpSrcPort->setText(QString().setNum(data.src_port())); - configForm->leTcpDstPort->setText(QString().setNum(data.dst_port())); + configForm->leTcpSrcPort->setText(QString().setNum(data.src_port())); + configForm->leTcpDstPort->setText(QString().setNum(data.dst_port())); - configForm->leTcpSeqNum->setText(QString().setNum(data.seq_num())); - configForm->leTcpAckNum->setText(QString().setNum(data.ack_num())); + configForm->leTcpSeqNum->setText(QString().setNum(data.seq_num())); + configForm->leTcpAckNum->setText(QString().setNum(data.ack_num())); - configForm->leTcpHdrLen->setText(fieldData(tcp_hdrlen, FieldValue).toString()); - configForm->cbTcpHdrLenOverride->setChecked(data.is_override_hdrlen()); + configForm->leTcpHdrLen->setText(fieldData(tcp_hdrlen, FieldValue).toString()); + configForm->cbTcpHdrLenOverride->setChecked(data.is_override_hdrlen()); - configForm->leTcpWindow->setText(QString().setNum(data.window())); + configForm->leTcpWindow->setText(QString().setNum(data.window())); - configForm->leTcpCksum->setText(QString("%1").arg( - fieldData(tcp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); - configForm->cbTcpCksumOverride->setChecked(data.is_override_cksum()); + configForm->leTcpCksum->setText(QString("%1").arg( + fieldData(tcp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); + configForm->cbTcpCksumOverride->setChecked(data.is_override_cksum()); - configForm->leTcpUrgentPointer->setText(QString().setNum(data.urg_ptr())); + configForm->leTcpUrgentPointer->setText(QString().setNum(data.urg_ptr())); - configForm->cbTcpFlagsUrg->setChecked((data.flags() & TCP_FLAG_URG) > 0); - configForm->cbTcpFlagsAck->setChecked((data.flags() & TCP_FLAG_ACK) > 0); - configForm->cbTcpFlagsPsh->setChecked((data.flags() & TCP_FLAG_PSH) > 0); - configForm->cbTcpFlagsRst->setChecked((data.flags() & TCP_FLAG_RST) > 0); - configForm->cbTcpFlagsSyn->setChecked((data.flags() & TCP_FLAG_SYN) > 0); - configForm->cbTcpFlagsFin->setChecked((data.flags() & TCP_FLAG_FIN) > 0); + configForm->cbTcpFlagsUrg->setChecked((data.flags() & TCP_FLAG_URG) > 0); + configForm->cbTcpFlagsAck->setChecked((data.flags() & TCP_FLAG_ACK) > 0); + configForm->cbTcpFlagsPsh->setChecked((data.flags() & TCP_FLAG_PSH) > 0); + configForm->cbTcpFlagsRst->setChecked((data.flags() & TCP_FLAG_RST) > 0); + configForm->cbTcpFlagsSyn->setChecked((data.flags() & TCP_FLAG_SYN) > 0); + configForm->cbTcpFlagsFin->setChecked((data.flags() & TCP_FLAG_FIN) > 0); } void TcpProtocol::storeConfigWidget() { - bool isOk; - int ff = 0; + bool isOk; + int ff = 0; - configWidget(); + configWidget(); - data.set_src_port(configForm->leTcpSrcPort->text().toULong(&isOk)); - data.set_dst_port(configForm->leTcpDstPort->text().toULong(&isOk)); + data.set_src_port(configForm->leTcpSrcPort->text().toULong(&isOk)); + data.set_dst_port(configForm->leTcpDstPort->text().toULong(&isOk)); - data.set_seq_num(configForm->leTcpSeqNum->text().toULong(&isOk)); - data.set_ack_num(configForm->leTcpAckNum->text().toULong(&isOk)); + data.set_seq_num(configForm->leTcpSeqNum->text().toULong(&isOk)); + data.set_ack_num(configForm->leTcpAckNum->text().toULong(&isOk)); - data.set_hdrlen_rsvd((configForm->leTcpHdrLen->text().toULong(&isOk) << 4) & 0xF0); - data.set_is_override_hdrlen(configForm->cbTcpHdrLenOverride->isChecked()); + data.set_hdrlen_rsvd((configForm->leTcpHdrLen->text().toULong(&isOk) << 4) & 0xF0); + data.set_is_override_hdrlen(configForm->cbTcpHdrLenOverride->isChecked()); - data.set_window(configForm->leTcpWindow->text().toULong(&isOk)); + data.set_window(configForm->leTcpWindow->text().toULong(&isOk)); - data.set_cksum(configForm->leTcpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); - data.set_is_override_cksum(configForm->cbTcpCksumOverride->isChecked()); + data.set_cksum(configForm->leTcpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); + data.set_is_override_cksum(configForm->cbTcpCksumOverride->isChecked()); - data.set_urg_ptr(configForm->leTcpUrgentPointer->text().toULong(&isOk)); + data.set_urg_ptr(configForm->leTcpUrgentPointer->text().toULong(&isOk)); - if (configForm->cbTcpFlagsUrg->isChecked()) ff |= TCP_FLAG_URG; - if (configForm->cbTcpFlagsAck->isChecked()) ff |= TCP_FLAG_ACK; - if (configForm->cbTcpFlagsPsh->isChecked()) ff |= TCP_FLAG_PSH; - if (configForm->cbTcpFlagsRst->isChecked()) ff |= TCP_FLAG_RST; - if (configForm->cbTcpFlagsSyn->isChecked()) ff |= TCP_FLAG_SYN; - if (configForm->cbTcpFlagsFin->isChecked()) ff |= TCP_FLAG_FIN; - data.set_flags(ff); + if (configForm->cbTcpFlagsUrg->isChecked()) ff |= TCP_FLAG_URG; + if (configForm->cbTcpFlagsAck->isChecked()) ff |= TCP_FLAG_ACK; + if (configForm->cbTcpFlagsPsh->isChecked()) ff |= TCP_FLAG_PSH; + if (configForm->cbTcpFlagsRst->isChecked()) ff |= TCP_FLAG_RST; + if (configForm->cbTcpFlagsSyn->isChecked()) ff |= TCP_FLAG_SYN; + if (configForm->cbTcpFlagsFin->isChecked()) ff |= TCP_FLAG_FIN; + data.set_flags(ff); } diff --git a/common/tcp.h b/common/tcp.h index 72cfbf8..8ef7ebf 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -6,72 +6,72 @@ #include "tcp.pb.h" #include "ui_tcp.h" -#define TCP_FLAG_URG 0x20 -#define TCP_FLAG_ACK 0x10 -#define TCP_FLAG_PSH 0x08 -#define TCP_FLAG_RST 0x04 -#define TCP_FLAG_SYN 0x02 -#define TCP_FLAG_FIN 0x01 +#define TCP_FLAG_URG 0x20 +#define TCP_FLAG_ACK 0x10 +#define TCP_FLAG_PSH 0x08 +#define TCP_FLAG_RST 0x04 +#define TCP_FLAG_SYN 0x02 +#define TCP_FLAG_FIN 0x01 class TcpConfigForm : public QWidget, public Ui::tcp { - Q_OBJECT + Q_OBJECT public: - TcpConfigForm(QWidget *parent = 0); + TcpConfigForm(QWidget *parent = 0); }; class TcpProtocol : public AbstractProtocol { private: - OstProto::Tcp data; - TcpConfigForm *configForm; - enum tcpfield - { - tcp_src_port = 0, - tcp_dst_port, - tcp_seq_num, - tcp_ack_num, - tcp_hdrlen, - tcp_rsvd, - tcp_flags, - tcp_window, - tcp_cksum, - tcp_urg_ptr, + OstProto::Tcp data; + TcpConfigForm *configForm; + enum tcpfield + { + tcp_src_port = 0, + tcp_dst_port, + tcp_seq_num, + tcp_ack_num, + tcp_hdrlen, + tcp_rsvd, + tcp_flags, + tcp_window, + tcp_cksum, + tcp_urg_ptr, - tcp_is_override_hdrlen, - tcp_is_override_cksum, + tcp_is_override_hdrlen, + tcp_is_override_cksum, - tcp_fieldCount - }; + tcp_fieldCount + }; public: - TcpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~TcpProtocol(); + TcpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~TcpProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; - virtual quint32 protocolId(ProtocolIdType type) const; + virtual QString name() const; + virtual QString shortName() const; + virtual quint32 protocolId(ProtocolIdType type) const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameValueVariable() const; - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/tcp.proto b/common/tcp.proto index 3cc6135..05dd181 100644 --- a/common/tcp.proto +++ b/common/tcp.proto @@ -4,24 +4,24 @@ package OstProto; // Tcp message Tcp { - optional bool is_override_hdrlen = 1; - optional bool is_override_cksum = 2; + optional bool is_override_hdrlen = 1; + optional bool is_override_cksum = 2; - optional uint32 src_port = 3 [default = 8902]; - optional uint32 dst_port = 4 [default = 80]; + optional uint32 src_port = 3 [default = 8902]; + optional uint32 dst_port = 4 [default = 80]; - optional uint32 seq_num = 5 [default = 129018]; - optional uint32 ack_num = 6; + optional uint32 seq_num = 5 [default = 129018]; + optional uint32 ack_num = 6; - optional uint32 hdrlen_rsvd = 7 [default = 0x50]; - optional uint32 flags = 8; + optional uint32 hdrlen_rsvd = 7 [default = 0x50]; + optional uint32 flags = 8; - optional uint32 window = 9 [default = 1024]; - optional uint32 cksum = 10; - optional uint32 urg_ptr = 11; + optional uint32 window = 9 [default = 1024]; + optional uint32 cksum = 10; + optional uint32 urg_ptr = 11; } extend Protocol { - optional Tcp tcp = 140; + optional Tcp tcp = 140; } diff --git a/common/udp.cpp b/common/udp.cpp index 9cb74ec..e65e0af 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -4,306 +4,306 @@ #include "udp.h" UdpConfigForm::UdpConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); } UdpProtocol::UdpProtocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } UdpProtocol::~UdpProtocol() { - delete configForm; + delete configForm; } AbstractProtocol* UdpProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new UdpProtocol(stream, parent); + return new UdpProtocol(stream, parent); } quint32 UdpProtocol::protocolNumber() const { - return OstProto::Protocol::kUdpFieldNumber; + return OstProto::Protocol::kUdpFieldNumber; } void UdpProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::udp)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::udp)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void UdpProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::udp)) - data.MergeFrom(protocol.GetExtension(OstProto::udp)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::udp)) + data.MergeFrom(protocol.GetExtension(OstProto::udp)); } QString UdpProtocol::name() const { - return QString("User Datagram Protocol"); + return QString("User Datagram Protocol"); } QString UdpProtocol::shortName() const { - return QString("UDP"); + return QString("UDP"); } quint32 UdpProtocol::protocolId(ProtocolIdType type) const { - switch(type) - { - case ProtocolIdIp: return 0x11; - default: break; - } + switch(type) + { + case ProtocolIdIp: return 0x11; + default: break; + } - return AbstractProtocol::protocolId(type); + return AbstractProtocol::protocolId(type); } -int UdpProtocol::fieldCount() const +int UdpProtocol::fieldCount() const { - return udp_fieldCount; + return udp_fieldCount; } AbstractProtocol::FieldFlags UdpProtocol::fieldFlags(int index) const { - AbstractProtocol::FieldFlags flags; + AbstractProtocol::FieldFlags flags; - flags = AbstractProtocol::fieldFlags(index); + flags = AbstractProtocol::fieldFlags(index); - switch (index) - { - case udp_srcPort: - case udp_dstPort: - case udp_totLen: - break; + switch (index) + { + case udp_srcPort: + case udp_dstPort: + case udp_totLen: + break; - case udp_cksum: - flags |= FieldIsCksum; - break; + case udp_cksum: + flags |= FieldIsCksum; + break; - case udp_isOverrideTotLen: - case udp_isOverrideCksum: - flags |= FieldIsMeta; - break; + case udp_isOverrideTotLen: + case udp_isOverrideCksum: + flags |= FieldIsMeta; + break; - default: - break; - } + default: + break; + } - return flags; + return flags; } QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case udp_srcPort: - switch(attrib) - { - case FieldName: - return QString("Source Port"); - case FieldValue: - return data.src_port(); - case FieldTextValue: - return QString("%1").arg(data.src_port()); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) data.src_port(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; + switch (index) + { + case udp_srcPort: + switch(attrib) + { + case FieldName: + return QString("Source Port"); + case FieldValue: + return data.src_port(); + case FieldTextValue: + return QString("%1").arg(data.src_port()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.src_port(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; - case udp_dstPort: - switch(attrib) - { - case FieldName: - return QString("Destination Port"); - case FieldValue: - return data.dst_port(); - case FieldTextValue: - return QString("%1").arg(data.dst_port()); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; + case udp_dstPort: + switch(attrib) + { + case FieldName: + return QString("Destination Port"); + case FieldValue: + return data.dst_port(); + case FieldTextValue: + return QString("%1").arg(data.dst_port()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; - case udp_totLen: - { + case udp_totLen: + { - switch(attrib) - { - case FieldName: - return QString("Datagram Length"); - case FieldValue: - { - int totlen; + switch(attrib) + { + case FieldName: + return QString("Datagram Length"); + case FieldValue: + { + int totlen; - totlen = data.is_override_totlen() ? - data.totlen() : - (protocolFramePayloadSize(streamIndex) + 8); - return totlen; - } - case FieldFrameValue: - { - QByteArray fv; - int totlen; - totlen = data.is_override_totlen() ? - data.totlen() : - (protocolFramePayloadSize(streamIndex) + 8); - fv.resize(2); - qToBigEndian((quint16) totlen, (uchar*) fv.data()); - return fv; - } - case FieldTextValue: - { - int totlen; - totlen = data.is_override_totlen() ? - data.totlen() : - (protocolFramePayloadSize(streamIndex) + 8); - return QString("%1").arg(totlen); - } - case FieldBitSize: - return 16; - default: - break; - } - break; - } - case udp_cksum: - { - quint16 cksum; + totlen = data.is_override_totlen() ? + data.totlen() : + (protocolFramePayloadSize(streamIndex) + 8); + return totlen; + } + case FieldFrameValue: + { + QByteArray fv; + int totlen; + totlen = data.is_override_totlen() ? + data.totlen() : + (protocolFramePayloadSize(streamIndex) + 8); + fv.resize(2); + qToBigEndian((quint16) totlen, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + { + int totlen; + totlen = data.is_override_totlen() ? + data.totlen() : + (protocolFramePayloadSize(streamIndex) + 8); + return QString("%1").arg(totlen); + } + case FieldBitSize: + return 16; + default: + break; + } + break; + } + case udp_cksum: + { + quint16 cksum; - switch(attrib) - { - case FieldValue: - case FieldFrameValue: - case FieldTextValue: - { - if (data.is_override_cksum()) - cksum = data.cksum(); - else - cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); - qDebug("UDP cksum = %hu", cksum); - } - default: - break; - } + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + { + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + qDebug("UDP cksum = %hu", cksum); + } + default: + break; + } - switch(attrib) - { - case FieldName: - return QString("Checksum"); - case FieldValue: - return cksum; - case FieldFrameValue: - { - QByteArray fv; + switch(attrib) + { + case FieldName: + return QString("Checksum"); + case FieldValue: + return cksum; + case FieldFrameValue: + { + QByteArray fv; - fv.resize(2); - qToBigEndian(cksum, (uchar*) fv.data()); - return fv; - } - case FieldTextValue: - return QString("0x%1"). - arg(cksum, 4, BASE_HEX, QChar('0'));; - case FieldBitSize: - return 16; - default: - break; - } - break; - } - // Meta fields - case udp_isOverrideTotLen: - case udp_isOverrideCksum: - switch(attrib) - { - case FieldIsMeta: - return true; - default: - break; - } - break; + fv.resize(2); + qToBigEndian(cksum, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("0x%1"). + arg(cksum, 4, BASE_HEX, QChar('0'));; + case FieldBitSize: + return 16; + default: + break; + } + break; + } + // Meta fields + case udp_isOverrideTotLen: + case udp_isOverrideCksum: + switch(attrib) + { + case FieldIsMeta: + return true; + default: + break; + } + break; - default: - break; - } + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool UdpProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - //! implement UdpProtocol::setFieldData() - return false; + //! implement UdpProtocol::setFieldData() + return false; } bool UdpProtocol::isProtocolFrameValueVariable() const { - if (data.is_override_totlen() && data.is_override_cksum()) - return false; - else - return isProtocolFramePayloadValueVariable(); + if (data.is_override_totlen() && data.is_override_cksum()) + return false; + else + return isProtocolFramePayloadValueVariable(); } QWidget* UdpProtocol::configWidget() { - if (configForm == NULL) - { - configForm = new UdpConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new UdpConfigForm; + loadConfigWidget(); + } + return configForm; } void UdpProtocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->leUdpSrcPort->setText(fieldData(udp_srcPort, FieldValue).toString()); - configForm->leUdpDstPort->setText(fieldData(udp_dstPort, FieldValue).toString()); + configForm->leUdpSrcPort->setText(fieldData(udp_srcPort, FieldValue).toString()); + configForm->leUdpDstPort->setText(fieldData(udp_dstPort, FieldValue).toString()); - configForm->leUdpLength->setText(fieldData(udp_totLen, FieldValue).toString()); - configForm->cbUdpLengthOverride->setChecked(data.is_override_totlen()); + configForm->leUdpLength->setText(fieldData(udp_totLen, FieldValue).toString()); + configForm->cbUdpLengthOverride->setChecked(data.is_override_totlen()); - configForm->leUdpCksum->setText(QString("%1").arg( - fieldData(udp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); - configForm->cbUdpCksumOverride->setChecked(data.is_override_cksum()); + configForm->leUdpCksum->setText(QString("%1").arg( + fieldData(udp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); + configForm->cbUdpCksumOverride->setChecked(data.is_override_cksum()); } void UdpProtocol::storeConfigWidget() { - bool isOk; + bool isOk; - configWidget(); + configWidget(); - data.set_src_port(configForm->leUdpSrcPort->text().toULong(&isOk)); - data.set_dst_port(configForm->leUdpDstPort->text().toULong(&isOk)); + data.set_src_port(configForm->leUdpSrcPort->text().toULong(&isOk)); + data.set_dst_port(configForm->leUdpDstPort->text().toULong(&isOk)); - data.set_totlen(configForm->leUdpLength->text().toULong(&isOk)); - data.set_is_override_totlen(configForm->cbUdpLengthOverride->isChecked()); + data.set_totlen(configForm->leUdpLength->text().toULong(&isOk)); + data.set_is_override_totlen(configForm->cbUdpLengthOverride->isChecked()); - data.set_cksum(configForm->leUdpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); - data.set_is_override_cksum(configForm->cbUdpCksumOverride->isChecked()); + data.set_cksum(configForm->leUdpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); + data.set_is_override_cksum(configForm->cbUdpCksumOverride->isChecked()); } diff --git a/common/udp.h b/common/udp.h index 663456b..652c03a 100644 --- a/common/udp.h +++ b/common/udp.h @@ -8,57 +8,57 @@ class UdpConfigForm : public QWidget, public Ui::udp { - Q_OBJECT + Q_OBJECT public: - UdpConfigForm(QWidget *parent = 0); + UdpConfigForm(QWidget *parent = 0); }; class UdpProtocol : public AbstractProtocol { private: - OstProto::Udp data; - UdpConfigForm *configForm; - enum udpfield - { - udp_srcPort = 0, - udp_dstPort, - udp_totLen, - udp_cksum, + OstProto::Udp data; + UdpConfigForm *configForm; + enum udpfield + { + udp_srcPort = 0, + udp_dstPort, + udp_totLen, + udp_cksum, - udp_isOverrideTotLen, - udp_isOverrideCksum, + udp_isOverrideTotLen, + udp_isOverrideCksum, - udp_fieldCount - }; + udp_fieldCount + }; public: - UdpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~UdpProtocol(); + UdpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~UdpProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; - virtual quint32 protocolId(ProtocolIdType type) const; + virtual QString name() const; + virtual QString shortName() const; + virtual quint32 protocolId(ProtocolIdType type) const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual bool isProtocolFrameValueVariable() const; + virtual bool isProtocolFrameValueVariable() const; - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/udp.proto b/common/udp.proto index 89e3065..23ed43e 100644 --- a/common/udp.proto +++ b/common/udp.proto @@ -4,15 +4,15 @@ package OstProto; // UDP message Udp { - optional bool is_override_totlen = 1; - optional bool is_override_cksum = 2; + optional bool is_override_totlen = 1; + optional bool is_override_cksum = 2; - optional uint32 src_port = 3 [default = 8902]; - optional uint32 dst_port = 4 [default = 80]; - optional uint32 totlen = 5; - optional uint32 cksum = 6; + optional uint32 src_port = 3 [default = 8902]; + optional uint32 dst_port = 4 [default = 80]; + optional uint32 totlen = 5; + optional uint32 cksum = 6; } extend Protocol { - optional Udp udp = 141; + optional Udp udp = 141; } diff --git a/common/userscript.proto b/common/userscript.proto index 3f26cd2..aaf2621 100644 --- a/common/userscript.proto +++ b/common/userscript.proto @@ -5,10 +5,10 @@ package OstProto; // Sample Protocol message UserScript { - optional string program = 1; + optional string program = 1; } extend Protocol { - optional UserScript userScript = 54; + optional UserScript userScript = 54; } diff --git a/common/vlan.cpp b/common/vlan.cpp index 244a473..83ed52d 100644 --- a/common/vlan.cpp +++ b/common/vlan.cpp @@ -3,235 +3,235 @@ #include "vlan.h" VlanConfigForm::VlanConfigForm(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - setupUi(this); + setupUi(this); } VlanProtocol::VlanProtocol(StreamBase *stream, AbstractProtocol *parent) - : AbstractProtocol(stream, parent) + : AbstractProtocol(stream, parent) { - configForm = NULL; + configForm = NULL; } VlanProtocol::~VlanProtocol() { - delete configForm; + delete configForm; } AbstractProtocol* VlanProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) + AbstractProtocol *parent) { - return new VlanProtocol(stream, parent); + return new VlanProtocol(stream, parent); } quint32 VlanProtocol::protocolNumber() const { - return OstProto::Protocol::kVlanFieldNumber; + return OstProto::Protocol::kVlanFieldNumber; } void VlanProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { - protocol.MutableExtension(OstProto::vlan)->CopyFrom(data); - protocol.mutable_protocol_id()->set_id(protocolNumber()); + protocol.MutableExtension(OstProto::vlan)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); } void VlanProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { - if (protocol.protocol_id().id() == protocolNumber() && - protocol.HasExtension(OstProto::vlan)) - data.MergeFrom(protocol.GetExtension(OstProto::vlan)); + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::vlan)) + data.MergeFrom(protocol.GetExtension(OstProto::vlan)); } QString VlanProtocol::name() const { - return QString("Vlan"); + return QString("Vlan"); } QString VlanProtocol::shortName() const { - return QString("Vlan"); + return QString("Vlan"); } -int VlanProtocol::fieldCount() const +int VlanProtocol::fieldCount() const { - return vlan_fieldCount; + return vlan_fieldCount; } AbstractProtocol::FieldFlags VlanProtocol::fieldFlags(int index) const { - AbstractProtocol::FieldFlags flags; + AbstractProtocol::FieldFlags flags; - flags = AbstractProtocol::fieldFlags(index); + flags = AbstractProtocol::fieldFlags(index); - switch (index) - { - case vlan_tpid: - case vlan_prio: - case vlan_cfiDei: - case vlan_vlanId: - break; + switch (index) + { + case vlan_tpid: + case vlan_prio: + case vlan_cfiDei: + case vlan_vlanId: + break; - // meta-fields - case vlan_isOverrideTpid: - flags |= FieldIsMeta; - break; - } + // meta-fields + case vlan_isOverrideTpid: + flags |= FieldIsMeta; + break; + } - return flags; + return flags; } QVariant VlanProtocol::fieldData(int index, FieldAttrib attrib, - int streamIndex) const + int streamIndex) const { - switch (index) - { - case vlan_tpid: - { - quint16 tpid; + switch (index) + { + case vlan_tpid: + { + quint16 tpid; - tpid = data.is_override_tpid() ? data.tpid() : 0x8100; + tpid = data.is_override_tpid() ? data.tpid() : 0x8100; - switch(attrib) - { - case FieldName: - return QString("Tag Protocol Id"); - case FieldValue: - return tpid; - case FieldTextValue: - return QString("0x%1").arg(tpid, 2, BASE_HEX, QChar('0')); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian(tpid, (uchar*) fv.data()); - return fv; - } - default: - break; - } - break; - } + switch(attrib) + { + case FieldName: + return QString("Tag Protocol Id"); + case FieldValue: + return tpid; + case FieldTextValue: + return QString("0x%1").arg(tpid, 2, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian(tpid, (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } - case vlan_prio: - { - uint prio = ((data.vlan_tag() >> 13) & 0x07); + case vlan_prio: + { + uint prio = ((data.vlan_tag() >> 13) & 0x07); - switch(attrib) - { - case FieldName: - return QString("Priority"); - case FieldValue: - return prio; - case FieldTextValue: - return QString("%1").arg(prio); - case FieldFrameValue: - return QByteArray(1, (char) prio); - case FieldBitSize: - return 3; - default: - break; - } - break; - } + switch(attrib) + { + case FieldName: + return QString("Priority"); + case FieldValue: + return prio; + case FieldTextValue: + return QString("%1").arg(prio); + case FieldFrameValue: + return QByteArray(1, (char) prio); + case FieldBitSize: + return 3; + default: + break; + } + break; + } - case vlan_cfiDei: - { - uint cfiDei = ((data.vlan_tag() >> 12) & 0x01); + case vlan_cfiDei: + { + uint cfiDei = ((data.vlan_tag() >> 12) & 0x01); - switch(attrib) - { - case FieldName: - return QString("CFI/DEI"); - case FieldValue: - return cfiDei; - case FieldTextValue: - return QString("%1").arg(cfiDei); - case FieldFrameValue: - return QByteArray(1, (char) cfiDei); - case FieldBitSize: - return 1; - default: - break; - } - break; - } + switch(attrib) + { + case FieldName: + return QString("CFI/DEI"); + case FieldValue: + return cfiDei; + case FieldTextValue: + return QString("%1").arg(cfiDei); + case FieldFrameValue: + return QByteArray(1, (char) cfiDei); + case FieldBitSize: + return 1; + default: + break; + } + break; + } - case vlan_vlanId: - { - quint16 vlanId = (data.vlan_tag() & 0x0FFF); + case vlan_vlanId: + { + quint16 vlanId = (data.vlan_tag() & 0x0FFF); - switch(attrib) - { - case FieldName: - return QString("VLAN Id"); - case FieldValue: - return vlanId; - case FieldTextValue: - return QString("%1").arg(vlanId); - case FieldFrameValue: - { - QByteArray fv; - fv.resize(2); - qToBigEndian((quint16) vlanId, (uchar*) fv.data()); - return fv; - } - case FieldBitSize: - return 12; - default: - break; - } - break; - } - // Meta fields + switch(attrib) + { + case FieldName: + return QString("VLAN Id"); + case FieldValue: + return vlanId; + case FieldTextValue: + return QString("%1").arg(vlanId); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) vlanId, (uchar*) fv.data()); + return fv; + } + case FieldBitSize: + return 12; + default: + break; + } + break; + } + // Meta fields - case vlan_isOverrideTpid: - default: - break; - } + case vlan_isOverrideTpid: + default: + break; + } - return AbstractProtocol::fieldData(index, attrib, streamIndex); + return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool VlanProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) + FieldAttrib attrib) { - return false; + return false; } QWidget* VlanProtocol::configWidget() { - if (configForm == NULL) - { - configForm = new VlanConfigForm; - loadConfigWidget(); - } - return configForm; + if (configForm == NULL) + { + configForm = new VlanConfigForm; + loadConfigWidget(); + } + return configForm; } void VlanProtocol::loadConfigWidget() { - configWidget(); + configWidget(); - configForm->cbTpidOverride->setChecked(data.is_override_tpid()); - configForm->leTpid->setText(uintToHexStr(fieldData(vlan_tpid, FieldValue).toUInt(), 2)); - configForm->cmbPrio->setCurrentIndex(fieldData(vlan_prio, FieldValue).toUInt()); - configForm->cmbCfiDei->setCurrentIndex(fieldData(vlan_cfiDei, FieldValue).toUInt()); - configForm->leVlanId->setText(fieldData(vlan_vlanId, FieldValue).toString()); + configForm->cbTpidOverride->setChecked(data.is_override_tpid()); + configForm->leTpid->setText(uintToHexStr(fieldData(vlan_tpid, FieldValue).toUInt(), 2)); + configForm->cmbPrio->setCurrentIndex(fieldData(vlan_prio, FieldValue).toUInt()); + configForm->cmbCfiDei->setCurrentIndex(fieldData(vlan_cfiDei, FieldValue).toUInt()); + configForm->leVlanId->setText(fieldData(vlan_vlanId, FieldValue).toString()); } void VlanProtocol::storeConfigWidget() { - bool isOk; + bool isOk; - configWidget(); + configWidget(); - data.set_is_override_tpid(configForm->cbTpidOverride->isChecked()); - data.set_tpid(configForm->leTpid->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); - data.set_vlan_tag( - ((configForm->cmbPrio->currentIndex() & 0x07) << 13) | - ((configForm->cmbCfiDei->currentIndex() & 0x01) << 12) | - (configForm->leVlanId->text().toULong(&isOk) & 0x0FFF)); + data.set_is_override_tpid(configForm->cbTpidOverride->isChecked()); + data.set_tpid(configForm->leTpid->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); + data.set_vlan_tag( + ((configForm->cmbPrio->currentIndex() & 0x07) << 13) | + ((configForm->cmbCfiDei->currentIndex() & 0x01) << 12) | + (configForm->leVlanId->text().toULong(&isOk) & 0x0FFF)); } diff --git a/common/vlan.h b/common/vlan.h index 5e5d7de..f276ce5 100644 --- a/common/vlan.h +++ b/common/vlan.h @@ -8,56 +8,56 @@ class VlanConfigForm : public QWidget, public Ui::Vlan { - Q_OBJECT + Q_OBJECT public: - VlanConfigForm(QWidget *parent = 0); + VlanConfigForm(QWidget *parent = 0); }; class VlanProtocol : public AbstractProtocol { private: - VlanConfigForm *configForm; - enum Vlanfield - { - vlan_tpid, - vlan_prio, - vlan_cfiDei, - vlan_vlanId, + VlanConfigForm *configForm; + enum Vlanfield + { + vlan_tpid, + vlan_prio, + vlan_cfiDei, + vlan_vlanId, - // meta-fields - vlan_isOverrideTpid, + // meta-fields + vlan_isOverrideTpid, - vlan_fieldCount - }; + vlan_fieldCount + }; protected: - OstProto::Vlan data; + OstProto::Vlan data; public: - VlanProtocol(StreamBase *stream, AbstractProtocol *parent = 0); - virtual ~VlanProtocol(); + VlanProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~VlanProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream, - AbstractProtocol *parent = 0); - virtual quint32 protocolNumber() const; + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; - virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; - virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); - virtual QString name() const; - virtual QString shortName() const; + virtual QString name() const; + virtual QString shortName() const; - virtual int fieldCount() const; + virtual int fieldCount() const; - virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; - virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; - virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); - virtual QWidget* configWidget(); - virtual void loadConfigWidget(); - virtual void storeConfigWidget(); + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); }; #endif diff --git a/common/vlan.proto b/common/vlan.proto index 0232612..a963444 100644 --- a/common/vlan.proto +++ b/common/vlan.proto @@ -2,14 +2,14 @@ import "protocol.proto"; package OstProto; message Vlan { - // VLAN presence/absence - optional bool is_override_tpid = 1; + // VLAN presence/absence + optional bool is_override_tpid = 1; - // VLAN values - optional uint32 tpid = 2; - optional uint32 vlan_tag = 3; // includes prio, cfi and vlanid + // VLAN values + optional uint32 tpid = 2; + optional uint32 vlan_tag = 3; // includes prio, cfi and vlanid } extend Protocol { - optional Vlan vlan = 126; + optional Vlan vlan = 126; } diff --git a/common/vlanstack.h b/common/vlanstack.h index f74aaed..4b24464 100644 --- a/common/vlanstack.h +++ b/common/vlanstack.h @@ -6,6 +6,6 @@ #include "vlan.h" typedef ComboProtocol VlanStackProtocol; + SVlanProtocol, VlanProtocol> VlanStackProtocol; #endif diff --git a/common/vlanstack.proto b/common/vlanstack.proto index a54f11f..4e6e9a0 100644 --- a/common/vlanstack.proto +++ b/common/vlanstack.proto @@ -4,9 +4,9 @@ package OstProto; // Stacked VLAN (2 tags) message VlanStack { - // Empty since this is a 'combo' protocol + // Empty since this is a 'combo' protocol } extend Protocol { - optional VlanStack vlanStack = 129; + optional VlanStack vlanStack = 129; } diff --git a/rpc/pbhelper.h b/rpc/pbhelper.h index 7a70c75..ba2b5fe 100644 --- a/rpc/pbhelper.h +++ b/rpc/pbhelper.h @@ -11,141 +11,141 @@ class PbHelper { public: - // FIXME: Change msg from * to & - void ForceSetSingularDefault(::google::protobuf::Message *msg) - { - const ::google::protobuf::Descriptor *desc; - ::google::protobuf::Message::Reflection *refl; + // FIXME: Change msg from * to & + void ForceSetSingularDefault(::google::protobuf::Message *msg) + { + const ::google::protobuf::Descriptor *desc; + ::google::protobuf::Message::Reflection *refl; - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - desc = msg->GetDescriptor(); - refl = msg->GetReflection(); + desc = msg->GetDescriptor(); + refl = msg->GetReflection(); - for (int i=0; i < desc->field_count(); i++) - { - const ::google::protobuf::FieldDescriptor *f; + for (int i=0; i < desc->field_count(); i++) + { + const ::google::protobuf::FieldDescriptor *f; - f = desc->field(i); + f = desc->field(i); - // Ensure field is singular and not already set - if (f->label() == - ::google::protobuf::FieldDescriptor::LABEL_REPEATED) - continue; - if (refl->HasField(f)) - continue; + // Ensure field is singular and not already set + if (f->label() == + ::google::protobuf::FieldDescriptor::LABEL_REPEATED) + continue; + if (refl->HasField(f)) + continue; - switch(f->type()) - { - case ::google::protobuf::FieldDescriptor::TYPE_DOUBLE: - refl->SetDouble(f, refl->GetDouble(f)); - break; + switch(f->type()) + { + case ::google::protobuf::FieldDescriptor::TYPE_DOUBLE: + refl->SetDouble(f, refl->GetDouble(f)); + break; - case ::google::protobuf::FieldDescriptor::TYPE_FLOAT: - refl->SetFloat(f, refl->GetFloat(f)); - break; + case ::google::protobuf::FieldDescriptor::TYPE_FLOAT: + refl->SetFloat(f, refl->GetFloat(f)); + break; - case ::google::protobuf::FieldDescriptor::TYPE_INT32: - case ::google::protobuf::FieldDescriptor::TYPE_SINT32: - case ::google::protobuf::FieldDescriptor::TYPE_SFIXED32: - refl->SetInt32(f, refl->GetInt32(f)); - break; + case ::google::protobuf::FieldDescriptor::TYPE_INT32: + case ::google::protobuf::FieldDescriptor::TYPE_SINT32: + case ::google::protobuf::FieldDescriptor::TYPE_SFIXED32: + refl->SetInt32(f, refl->GetInt32(f)); + break; - case ::google::protobuf::FieldDescriptor::TYPE_INT64: - case ::google::protobuf::FieldDescriptor::TYPE_SINT64: - case ::google::protobuf::FieldDescriptor::TYPE_SFIXED64: - refl->SetInt64(f, refl->GetInt64(f)); - break; + case ::google::protobuf::FieldDescriptor::TYPE_INT64: + case ::google::protobuf::FieldDescriptor::TYPE_SINT64: + case ::google::protobuf::FieldDescriptor::TYPE_SFIXED64: + refl->SetInt64(f, refl->GetInt64(f)); + break; - case ::google::protobuf::FieldDescriptor::TYPE_UINT32: - case ::google::protobuf::FieldDescriptor::TYPE_FIXED32: - refl->SetUInt32(f, refl->GetUInt32(f)); - break; + case ::google::protobuf::FieldDescriptor::TYPE_UINT32: + case ::google::protobuf::FieldDescriptor::TYPE_FIXED32: + refl->SetUInt32(f, refl->GetUInt32(f)); + break; - case ::google::protobuf::FieldDescriptor::TYPE_UINT64: - case ::google::protobuf::FieldDescriptor::TYPE_FIXED64: - refl->SetUInt64(f, refl->GetUInt64(f)); - break; + case ::google::protobuf::FieldDescriptor::TYPE_UINT64: + case ::google::protobuf::FieldDescriptor::TYPE_FIXED64: + refl->SetUInt64(f, refl->GetUInt64(f)); + break; - case ::google::protobuf::FieldDescriptor::TYPE_BOOL: - refl->SetBool(f, refl->GetBool(f)); - break; + case ::google::protobuf::FieldDescriptor::TYPE_BOOL: + refl->SetBool(f, refl->GetBool(f)); + break; - case ::google::protobuf::FieldDescriptor::TYPE_ENUM: - refl->SetEnum(f, refl->GetEnum(f)); - break; + case ::google::protobuf::FieldDescriptor::TYPE_ENUM: + refl->SetEnum(f, refl->GetEnum(f)); + break; - case ::google::protobuf::FieldDescriptor::TYPE_STRING: - case ::google::protobuf::FieldDescriptor::TYPE_BYTES: - refl->SetString(f, refl->GetString(f)); - break; + case ::google::protobuf::FieldDescriptor::TYPE_STRING: + case ::google::protobuf::FieldDescriptor::TYPE_BYTES: + refl->SetString(f, refl->GetString(f)); + break; - case ::google::protobuf::FieldDescriptor::TYPE_MESSAGE: - case ::google::protobuf::FieldDescriptor::TYPE_GROUP: - ForceSetSingularDefault(refl->MutableMessage(f)); // recursion! - break; + case ::google::protobuf::FieldDescriptor::TYPE_MESSAGE: + case ::google::protobuf::FieldDescriptor::TYPE_GROUP: + ForceSetSingularDefault(refl->MutableMessage(f)); // recursion! + break; - default: - qDebug("unhandled Field Type"); - break; - } - } - } + default: + qDebug("unhandled Field Type"); + break; + } + } + } - bool update( - ::google::protobuf::Message *target, - ::google::protobuf::Message *source) - { - // FIXME(HI): Depracate: use MergeFrom() directly - qDebug("In %s", __FUNCTION__); - target->MergeFrom(*source); - return true; + bool update( + ::google::protobuf::Message *target, + ::google::protobuf::Message *source) + { + // FIXME(HI): Depracate: use MergeFrom() directly + qDebug("In %s", __FUNCTION__); + target->MergeFrom(*source); + return true; #if 0 - ::google::protobuf::Message::Reflection *sourceRef; - ::google::protobuf::Message::Reflection *targetRef; - std::vector srcFieldList; + ::google::protobuf::Message::Reflection *sourceRef; + ::google::protobuf::Message::Reflection *targetRef; + std::vector srcFieldList; - if (source->GetDescriptor()->full_name() != - target->GetDescriptor()->full_name()) - goto _error_exit; + if (source->GetDescriptor()->full_name() != + target->GetDescriptor()->full_name()) + goto _error_exit; - sourceRef = source->GetReflection(); - targetRef = target->GetReflection(); + sourceRef = source->GetReflection(); + targetRef = target->GetReflection(); - sourceRef->ListFields(&srcFieldList); - for (uint i=0; i < srcFieldList.size(); i++) - { - const ::google::protobuf::FieldDescriptor *srcField, *targetField; + sourceRef->ListFields(&srcFieldList); + for (uint i=0; i < srcFieldList.size(); i++) + { + const ::google::protobuf::FieldDescriptor *srcField, *targetField; - srcField = srcFieldList[i]; - targetField = target->GetDescriptor()->FindFieldByName( - srcField->name()); + srcField = srcFieldList[i]; + targetField = target->GetDescriptor()->FindFieldByName( + srcField->name()); - switch(targetField->type()) - { - case ::google::protobuf::FieldDescriptor::TYPE_UINT32: - targetRef->SetUInt32(targetField, - sourceRef->GetUInt32(srcField)); - break; - case ::google::protobuf::FieldDescriptor::TYPE_BOOL: - targetRef->SetBool(targetField, - sourceRef->GetBool(srcField)); - break; - case ::google::protobuf::FieldDescriptor::TYPE_STRING: - targetRef->SetString(targetField, - sourceRef->GetString(srcField)); - break; - default: - qDebug("unhandled Field Type"); - break; - } - } - _error_exit: - qDebug("%s: error!", __FUNCTION__); - return false; + switch(targetField->type()) + { + case ::google::protobuf::FieldDescriptor::TYPE_UINT32: + targetRef->SetUInt32(targetField, + sourceRef->GetUInt32(srcField)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_BOOL: + targetRef->SetBool(targetField, + sourceRef->GetBool(srcField)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_STRING: + targetRef->SetString(targetField, + sourceRef->GetString(srcField)); + break; + default: + qDebug("unhandled Field Type"); + break; + } + } + _error_exit: + qDebug("%s: error!", __FUNCTION__); + return false; #endif - } + } }; #endif #endif diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index f99c00b..5c3626e 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -2,309 +2,309 @@ PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) { - isPending = false; - pendingMethodId = -1; // don't care as long as isPending is false + isPending = false; + pendingMethodId = -1; // don't care as long as isPending is false - controller = NULL; - done = NULL; - response = NULL; + controller = NULL; + done = NULL; + response = NULL; - mServerAddress = ip; - mServerPort = port; - mpSocket = new QTcpSocket(this); + mServerAddress = ip; + mServerPort = port; + mpSocket = new QTcpSocket(this); - // FIXME: Not quite sure why this ain't working! - // QMetaObject::connectSlotsByName(this); + // FIXME: Not quite sure why this ain't working! + // QMetaObject::connectSlotsByName(this); - connect(mpSocket, SIGNAL(connected()), - this, SLOT(on_mpSocket_connected())); - connect(mpSocket, SIGNAL(disconnected()), - this, SLOT(on_mpSocket_disconnected())); - connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), - this, SLOT(on_mpSocket_stateChanged(QAbstractSocket::SocketState))); - connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(on_mpSocket_error(QAbstractSocket::SocketError))); + connect(mpSocket, SIGNAL(connected()), + this, SLOT(on_mpSocket_connected())); + connect(mpSocket, SIGNAL(disconnected()), + this, SLOT(on_mpSocket_disconnected())); + connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(on_mpSocket_stateChanged(QAbstractSocket::SocketState))); + connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_mpSocket_error(QAbstractSocket::SocketError))); - connect(mpSocket, SIGNAL(readyRead()), - this, SLOT(on_mpSocket_readyRead())); + connect(mpSocket, SIGNAL(readyRead()), + this, SLOT(on_mpSocket_readyRead())); } PbRpcChannel::~PbRpcChannel() { - delete mpSocket; + delete mpSocket; } void PbRpcChannel::establish() { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - mpSocket->connectToHost(mServerAddress, mServerPort); + mpSocket->connectToHost(mServerAddress, mServerPort); } void PbRpcChannel::establish(QHostAddress ip, quint16 port) { - mServerAddress = ip; - mServerPort = port; - establish(); + mServerAddress = ip; + mServerPort = port; + establish(); } void PbRpcChannel::tearDown() { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - mpSocket->disconnectFromHost(); + mpSocket->disconnectFromHost(); } void PbRpcChannel::CallMethod( - const ::google::protobuf::MethodDescriptor *method, - ::google::protobuf::RpcController *controller, - const ::google::protobuf::Message *req, - ::google::protobuf::Message *response, - ::google::protobuf::Closure* done) + const ::google::protobuf::MethodDescriptor *method, + ::google::protobuf::RpcController *controller, + const ::google::protobuf::Message *req, + ::google::protobuf::Message *response, + ::google::protobuf::Closure* done) { - char msg[MSGBUF_SIZE]; - int len; - bool ret; + char msg[MSGBUF_SIZE]; + int len; + bool ret; - if (isPending) - { - RpcCall call; - qDebug("RpcChannel: queueing method %d since %d is pending", - method->index(), pendingMethodId); + if (isPending) + { + RpcCall call; + qDebug("RpcChannel: queueing method %d since %d is pending", + method->index(), pendingMethodId); - call.method = method; - call.controller = controller; - call.request = req; - call.response = response; - call.done = done; + call.method = method; + call.controller = controller; + call.request = req; + call.response = response; + call.done = done; - pendingCallList.append(call); + pendingCallList.append(call); - Q_ASSERT(pendingCallList.size() < 100); + Q_ASSERT(pendingCallList.size() < 100); - return; - } + return; + } - if (!req->IsInitialized()) - { - qWarning("RpcChannel: missing required fields in request"); - qDebug(req->InitializationErrorString().c_str()); + if (!req->IsInitialized()) + { + qWarning("RpcChannel: missing required fields in request"); + qDebug(req->InitializationErrorString().c_str()); - qFatal("exiting"); + qFatal("exiting"); - controller->SetFailed("Required fields missing"); - done->Run(); - return; - } + controller->SetFailed("Required fields missing"); + done->Run(); + return; + } - pendingMethodId = method->index(); - this->controller=controller; - this->done=done; - this->response=response; - isPending = true; + pendingMethodId = method->index(); + this->controller=controller; + this->done=done; + this->response=response; + isPending = true; - ret = req->SerializeToArray((void*) (&msg[PB_HDR_SIZE]), sizeof(msg)); - Q_ASSERT(ret == true); + ret = req->SerializeToArray((void*) (&msg[PB_HDR_SIZE]), sizeof(msg)); + Q_ASSERT(ret == true); - len = req->ByteSize(); - *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_REQUEST); // type - *((quint16*)(&msg[2])) = HTONS(method->index()); // method id - *((quint32*)(&msg[4])) = HTONL(len); // len + len = req->ByteSize(); + *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_REQUEST); // type + *((quint16*)(&msg[2])) = HTONS(method->index()); // method id + *((quint32*)(&msg[4])) = HTONL(len); // len - // Avoid printing stats since it happens every couple of seconds - if (pendingMethodId != 12) - { - qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, - PB_HDR_SIZE + len, req->DebugString().c_str()); - BUFDUMP(msg, PB_HDR_SIZE + len); - } + // Avoid printing stats since it happens every couple of seconds + if (pendingMethodId != 12) + { + qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, + PB_HDR_SIZE + len, req->DebugString().c_str()); + BUFDUMP(msg, PB_HDR_SIZE + len); + } - mpSocket->write(msg, PB_HDR_SIZE + len); + mpSocket->write(msg, PB_HDR_SIZE + len); } void PbRpcChannel::on_mpSocket_readyRead() { - char msg[MSGBUF_SIZE]; - char *p = (char*)&msg; - int msgLen; - static bool parsing = false; - static quint16 type, method; - static quint32 len; + char msg[MSGBUF_SIZE]; + char *p = (char*)&msg; + int msgLen; + static bool parsing = false; + static quint16 type, method; + static quint32 len; - //qDebug("%s: bytesAvail = %d", __FUNCTION__, mpSocket->bytesAvailable()); + //qDebug("%s: bytesAvail = %d", __FUNCTION__, mpSocket->bytesAvailable()); - if (!parsing) - { - // Do we have an entire header? If not, we'll wait ... - if (mpSocket->bytesAvailable() < PB_HDR_SIZE) - { - qDebug("client: not enough data available for a complete header"); - return; - } + if (!parsing) + { + // Do we have an entire header? If not, we'll wait ... + if (mpSocket->bytesAvailable() < PB_HDR_SIZE) + { + qDebug("client: not enough data available for a complete header"); + return; + } - msgLen = mpSocket->read(msg, PB_HDR_SIZE); + msgLen = mpSocket->read(msg, PB_HDR_SIZE); - Q_ASSERT(msgLen == PB_HDR_SIZE); + Q_ASSERT(msgLen == PB_HDR_SIZE); - type = NTOHS(GET16(p+0)); - method = NTOHS(GET16(p+2)); - len = NTOHL(GET32(p+4)); + type = NTOHS(GET16(p+0)); + method = NTOHS(GET16(p+2)); + len = NTOHL(GET32(p+4)); - //BUFDUMP(msg, PB_HDR_SIZE); - //qDebug("type = %hu, method = %hu, len = %u", type, method, len); + //BUFDUMP(msg, PB_HDR_SIZE); + //qDebug("type = %hu, method = %hu, len = %u", type, method, len); - parsing = true; - } + parsing = true; + } - switch (type) - { - case PB_MSG_TYPE_BINBLOB: - { - static quint32 cumLen = 0; - QIODevice *blob; + switch (type) + { + case PB_MSG_TYPE_BINBLOB: + { + static quint32 cumLen = 0; + QIODevice *blob; - blob = static_cast(controller)->binaryBlob(); - Q_ASSERT(blob != NULL); + blob = static_cast(controller)->binaryBlob(); + Q_ASSERT(blob != NULL); - while ((cumLen < len) && mpSocket->bytesAvailable()) - { - int l; + while ((cumLen < len) && mpSocket->bytesAvailable()) + { + int l; - l = mpSocket->read(msg, sizeof(msg)); - blob->write(msg, l); - cumLen += l; - } + l = mpSocket->read(msg, sizeof(msg)); + blob->write(msg, l); + cumLen += l; + } - qDebug("%s: bin blob rcvd %d/%d", __PRETTY_FUNCTION__, cumLen, len); + qDebug("%s: bin blob rcvd %d/%d", __PRETTY_FUNCTION__, cumLen, len); - if (cumLen < len) - return; + if (cumLen < len) + return; - cumLen = 0; + cumLen = 0; - if (!isPending) - { - qDebug("not waiting for response"); - goto _error_exit; - } + if (!isPending) + { + qDebug("not waiting for response"); + goto _error_exit; + } - if (pendingMethodId != method) - { - qDebug("invalid method id %d (expected = %d)", method, - pendingMethodId); - goto _error_exit; - } + if (pendingMethodId != method) + { + qDebug("invalid method id %d (expected = %d)", method, + pendingMethodId); + goto _error_exit; + } - break; - } + break; + } - case PB_MSG_TYPE_RESPONSE: - // Wait till we have the entire message - if (mpSocket->bytesAvailable() < len) - { - qDebug("client: not enough data available for a complete msg"); - return; - } - - msgLen = mpSocket->read(msg, sizeof(msg)); + case PB_MSG_TYPE_RESPONSE: + // Wait till we have the entire message + if (mpSocket->bytesAvailable() < len) + { + qDebug("client: not enough data available for a complete msg"); + return; + } + + msgLen = mpSocket->read(msg, sizeof(msg)); - Q_ASSERT((unsigned) msgLen == len); + Q_ASSERT((unsigned) msgLen == len); - //qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); - //BUFDUMP(msg, msgLen); + //qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); + //BUFDUMP(msg, msgLen); - if (!isPending) - { - qDebug("not waiting for response"); - goto _error_exit; - } + if (!isPending) + { + qDebug("not waiting for response"); + goto _error_exit; + } - if (pendingMethodId != method) - { - qDebug("invalid method id %d (expected = %d)", method, - pendingMethodId); - goto _error_exit; - } + if (pendingMethodId != method) + { + qDebug("invalid method id %d (expected = %d)", method, + pendingMethodId); + goto _error_exit; + } - response->ParseFromArray((void*) msg, len); + response->ParseFromArray((void*) msg, len); - // Avoid printing stats - if (method != 12) - { - qDebug("client(%s): Parsed as %s", __FUNCTION__, - response->DebugString().c_str()); - } + // Avoid printing stats + if (method != 12) + { + qDebug("client(%s): Parsed as %s", __FUNCTION__, + response->DebugString().c_str()); + } - if (!response->IsInitialized()) - { - qWarning("RpcChannel: missing required fields in response"); - qDebug(response->InitializationErrorString().c_str()); + if (!response->IsInitialized()) + { + qWarning("RpcChannel: missing required fields in response"); + qDebug(response->InitializationErrorString().c_str()); - controller->SetFailed("Required fields missing"); - } - break; + controller->SetFailed("Required fields missing"); + } + break; - default: - qFatal("%s: unexpected type %d", __PRETTY_FUNCTION__, type); - goto _error_exit; - - } + default: + qFatal("%s: unexpected type %d", __PRETTY_FUNCTION__, type); + goto _error_exit; + + } - pendingMethodId = -1; - controller = NULL; - response = NULL; - isPending = false; - parsing = false; + pendingMethodId = -1; + controller = NULL; + response = NULL; + isPending = false; + parsing = false; - done->Run(); + done->Run(); - if (pendingCallList.size()) - { - RpcCall call = pendingCallList.takeFirst(); - CallMethod(call.method, call.controller, call.request, call.response, - call.done); - } + if (pendingCallList.size()) + { + RpcCall call = pendingCallList.takeFirst(); + CallMethod(call.method, call.controller, call.request, call.response, + call.done); + } - return; + return; _error_exit: - parsing = false; - qDebug("client(%s) discarding received msg", __FUNCTION__); - return; + parsing = false; + qDebug("client(%s) discarding received msg", __FUNCTION__); + return; } void PbRpcChannel::on_mpSocket_stateChanged( - QAbstractSocket::SocketState socketState) + QAbstractSocket::SocketState socketState) { - qDebug("In %s", __FUNCTION__); - emit stateChanged(socketState); + qDebug("In %s", __FUNCTION__); + emit stateChanged(socketState); } void PbRpcChannel::on_mpSocket_connected() { - qDebug("In %s", __FUNCTION__); - emit connected(); + qDebug("In %s", __FUNCTION__); + emit connected(); } void PbRpcChannel::on_mpSocket_disconnected() { - qDebug("In %s", __FUNCTION__); + qDebug("In %s", __FUNCTION__); - pendingMethodId = -1; - controller = NULL; - response = NULL; - isPending = false; - // \todo convert parsing from static to data member - //parsing = false - pendingCallList.clear(); + pendingMethodId = -1; + controller = NULL; + response = NULL; + isPending = false; + // \todo convert parsing from static to data member + //parsing = false + pendingCallList.clear(); - emit disconnected(); + emit disconnected(); } void PbRpcChannel::on_mpSocket_error(QAbstractSocket::SocketError socketError) { - qDebug("In %s", __FUNCTION__); - emit error(socketError); + qDebug("In %s", __FUNCTION__); + emit error(socketError); } diff --git a/rpc/pbrpcchannel.h b/rpc/pbrpcchannel.h index 17f287a..e467781 100644 --- a/rpc/pbrpcchannel.h +++ b/rpc/pbrpcchannel.h @@ -13,71 +13,71 @@ class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel { - Q_OBJECT - - // If isPending is TRUE, then controller, done, response - // and pendingMethodId correspond to the last method called by - // the service stub - bool isPending; - int pendingMethodId; + Q_OBJECT + + // If isPending is TRUE, then controller, done, response + // and pendingMethodId correspond to the last method called by + // the service stub + bool isPending; + int pendingMethodId; - // controller, done, response are set to the corresponding values - // passed by the stub to CallMethod(). They are reset to NULL when - // we get a response back from the server in on_mpSocket_readyRead() - // after calling done->Run(). + // controller, done, response are set to the corresponding values + // passed by the stub to CallMethod(). They are reset to NULL when + // we get a response back from the server in on_mpSocket_readyRead() + // after calling done->Run(). - /*! \todo (MED) : change controller, done and response to references - instead of pointers? */ - ::google::protobuf::RpcController *controller; - ::google::protobuf::Closure *done; - ::google::protobuf::Message *response; + /*! \todo (MED) : change controller, done and response to references + instead of pointers? */ + ::google::protobuf::RpcController *controller; + ::google::protobuf::Closure *done; + ::google::protobuf::Message *response; - typedef struct _RpcCall { - const ::google::protobuf::MethodDescriptor *method; - ::google::protobuf::RpcController *controller; - const ::google::protobuf::Message *request; - ::google::protobuf::Message *response; - ::google::protobuf::Closure *done; - } RpcCall; - QList pendingCallList; + typedef struct _RpcCall { + const ::google::protobuf::MethodDescriptor *method; + ::google::protobuf::RpcController *controller; + const ::google::protobuf::Message *request; + ::google::protobuf::Message *response; + ::google::protobuf::Closure *done; + } RpcCall; + QList pendingCallList; - QHostAddress mServerAddress; - quint16 mServerPort; - QTcpSocket *mpSocket; + QHostAddress mServerAddress; + quint16 mServerPort; + QTcpSocket *mpSocket; public: - PbRpcChannel(QHostAddress ip, quint16 port); - ~PbRpcChannel(); + PbRpcChannel(QHostAddress ip, quint16 port); + ~PbRpcChannel(); - void establish(); - void establish(QHostAddress ip, quint16 port); - void tearDown(); + void establish(); + void establish(QHostAddress ip, quint16 port); + void tearDown(); - const QHostAddress& serverAddress() const { return mServerAddress; } - quint16 serverPort() const { return mServerPort; } + const QHostAddress& serverAddress() const { return mServerAddress; } + quint16 serverPort() const { return mServerPort; } - QAbstractSocket::SocketState state() const - { return mpSocket->state(); } + QAbstractSocket::SocketState state() const + { return mpSocket->state(); } - void CallMethod(const ::google::protobuf::MethodDescriptor *method, - ::google::protobuf::RpcController *controller, - const ::google::protobuf::Message *req, - ::google::protobuf::Message *response, - ::google::protobuf::Closure* done); + void CallMethod(const ::google::protobuf::MethodDescriptor *method, + ::google::protobuf::RpcController *controller, + const ::google::protobuf::Message *req, + ::google::protobuf::Message *response, + ::google::protobuf::Closure* done); signals: - void connected(); - void disconnected(); - void error(QAbstractSocket::SocketError socketError); - void stateChanged(QAbstractSocket::SocketState socketState); + void connected(); + void disconnected(); + void error(QAbstractSocket::SocketError socketError); + void stateChanged(QAbstractSocket::SocketState socketState); private slots: - void on_mpSocket_connected(); - void on_mpSocket_disconnected(); - void on_mpSocket_stateChanged(QAbstractSocket::SocketState socketState); - void on_mpSocket_error(QAbstractSocket::SocketError socketError); + void on_mpSocket_connected(); + void on_mpSocket_disconnected(); + void on_mpSocket_stateChanged(QAbstractSocket::SocketState socketState); + void on_mpSocket_error(QAbstractSocket::SocketError socketError); - void on_mpSocket_readyRead(); + void on_mpSocket_readyRead(); }; #endif diff --git a/rpc/pbrpccommon.h b/rpc/pbrpccommon.h index ef4b1ee..4ea1281 100644 --- a/rpc/pbrpccommon.h +++ b/rpc/pbrpccommon.h @@ -3,18 +3,18 @@ //! \todo (LOW) check which one is right - wrong one seems to be working!!!!! #if 0 -#define GET16(p) (quint16)( \ - (*((quint8*)(p)+0) << 8 ) \ - | (*((quint8*)(p)+1))) +#define GET16(p) (quint16)( \ + (*((quint8*)(p)+0) << 8 ) \ + | (*((quint8*)(p)+1))) #else -#define GET16(p) (quint16)( \ - (*((quint8*)(p)+1) << 8 ) \ - | (*((quint8*)(p)+0))) -#define GET32(p) (quint32)( \ - (*((quint8*)(p)+3) << 24) \ - | (*((quint8*)(p)+2) << 16) \ - | (*((quint8*)(p)+1) << 8 ) \ - | (*((quint8*)(p)+0))) +#define GET16(p) (quint16)( \ + (*((quint8*)(p)+1) << 8 ) \ + | (*((quint8*)(p)+0))) +#define GET32(p) (quint32)( \ + (*((quint8*)(p)+3) << 24) \ + | (*((quint8*)(p)+2) << 16) \ + | (*((quint8*)(p)+1) << 8 ) \ + | (*((quint8*)(p)+0))) #endif #define BYTESWAP4(x) \ @@ -29,33 +29,33 @@ //! \todo (LOW) : portability #if 1 -#define HTONL(x) BYTESWAP4(x) -#define NTOHL(x) BYTESWAP4(x) -#define HTONS(x) BYTESWAP2(x) -#define NTOHS(x) BYTESWAP2(x) +#define HTONL(x) BYTESWAP4(x) +#define NTOHL(x) BYTESWAP4(x) +#define HTONS(x) BYTESWAP2(x) +#define NTOHS(x) BYTESWAP2(x) #else -#define HTONL(x) (x) -#define NTOHL(x) (x) -#define HTONS(x) (x) -#define NTOHS(x) (x) +#define HTONL(x) (x) +#define NTOHL(x) (x) +#define HTONS(x) (x) +#define NTOHS(x) (x) #endif // Print a HexDump #define BUFDUMP(ptr, len) qDebug("%s", QString(QByteArray((char*)(ptr), \ - (len)).toHex()).toAscii().data()); + (len)).toHex()).toAscii().data()); /* ** RPC Header (8) -** - MSG_TYPE (2) -** - METHOD_ID (2) -** - LEN (4) [not including this header] +** - MSG_TYPE (2) +** - METHOD_ID (2) +** - LEN (4) [not including this header] */ -#define PB_HDR_SIZE 8 +#define PB_HDR_SIZE 8 -#define PB_MSG_TYPE_REQUEST 1 -#define PB_MSG_TYPE_RESPONSE 2 -#define PB_MSG_TYPE_BINBLOB 3 +#define PB_MSG_TYPE_REQUEST 1 +#define PB_MSG_TYPE_RESPONSE 2 +#define PB_MSG_TYPE_BINBLOB 3 -#define MSGBUF_SIZE 4096 +#define MSGBUF_SIZE 4096 #endif diff --git a/rpc/pbrpccontroller.h b/rpc/pbrpccontroller.h index 916cb95..b446c73 100644 --- a/rpc/pbrpccontroller.h +++ b/rpc/pbrpccontroller.h @@ -7,28 +7,28 @@ class QIODevice; class PbRpcController : public ::google::protobuf::RpcController { - bool failed; - QIODevice *blob; - std::string errStr; + bool failed; + QIODevice *blob; + std::string errStr; public: - PbRpcController() { Reset(); } + PbRpcController() { Reset(); } - // Client Side Methods - void Reset() { failed=false; blob = NULL; } - bool Failed() const { return failed; } - void StartCancel() { /*! \todo (MED) */} - std::string ErrorText() const { return errStr; } + // Client Side Methods + void Reset() { failed=false; blob = NULL; } + bool Failed() const { return failed; } + void StartCancel() { /*! \todo (MED) */} + std::string ErrorText() const { return errStr; } - // Server Side Methods - void SetFailed(const std::string &reason) - { failed = true; errStr = reason; } - bool IsCanceled() const { return false; }; - void NotifyOnCancel(::google::protobuf::Closure *callback) { /*! \todo (MED) */ } + // Server Side Methods + void SetFailed(const std::string &reason) + { failed = true; errStr = reason; } + bool IsCanceled() const { return false; }; + void NotifyOnCancel(::google::protobuf::Closure *callback) { /*! \todo (MED) */ } - // srivatsp added - QIODevice* binaryBlob() { return blob; }; - void setBinaryBlob(QIODevice *binaryBlob) { blob = binaryBlob; }; + // srivatsp added + QIODevice* binaryBlob() { return blob; }; + void setBinaryBlob(QIODevice *binaryBlob) { blob = binaryBlob; }; }; #endif diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index 3d5a10c..804c4ee 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -3,254 +3,254 @@ RpcServer::RpcServer() { - server = NULL; - clientSock = NULL; + server = NULL; + clientSock = NULL; - service = NULL; + service = NULL; - isPending = false; - pendingMethodId = -1; // don't care as long as isPending is false + isPending = false; + pendingMethodId = -1; // don't care as long as isPending is false } RpcServer::~RpcServer() { - if (server) - delete server; + if (server) + delete server; } bool RpcServer::registerService(::google::protobuf::Service *service, - quint16 tcpPortNum) + quint16 tcpPortNum) { - this->service = service; + this->service = service; - server = new QTcpServer(); - connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); - if (!server->listen(QHostAddress::Any, tcpPortNum)) - { - qDebug("Unable to start the server: %s", - server->errorString().toAscii().constData()); - errorString_ = QString("Error starting Ostinato server: %1").arg( - server->errorString()); - return false; - } + server = new QTcpServer(); + connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); + if (!server->listen(QHostAddress::Any, tcpPortNum)) + { + qDebug("Unable to start the server: %s", + server->errorString().toAscii().constData()); + errorString_ = QString("Error starting Ostinato server: %1").arg( + server->errorString()); + return false; + } - qDebug("The server is running on %s: %d", - server->serverAddress().toString().toAscii().constData(), - server->serverPort()); - errorString_ = QString(); - return true; + qDebug("The server is running on %s: %d", + server->serverAddress().toString().toAscii().constData(), + server->serverPort()); + errorString_ = QString(); + return true; } QString RpcServer::errorString() { - return errorString_; + return errorString_; } void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController) { - QIODevice *blob; - char msg[MSGBUF_SIZE]; - int len; + QIODevice *blob; + char msg[MSGBUF_SIZE]; + int len; - //qDebug("In RpcServer::done"); + //qDebug("In RpcServer::done"); - if (PbRpcController->Failed()) - { - qDebug("rpc failed"); - goto _exit; - } + if (PbRpcController->Failed()) + { + qDebug("rpc failed"); + goto _exit; + } - blob = PbRpcController->binaryBlob(); - if (blob) - { - len = blob->size(); - qDebug("is binary blob of len %d", len); + blob = PbRpcController->binaryBlob(); + if (blob) + { + len = blob->size(); + qDebug("is binary blob of len %d", len); - *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_BINBLOB); // type - *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method - (*(quint32*)(&msg[4])) = HTONL(len); // len + *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_BINBLOB); // type + *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method + (*(quint32*)(&msg[4])) = HTONL(len); // len - clientSock->write(msg, PB_HDR_SIZE); + clientSock->write(msg, PB_HDR_SIZE); - blob->seek(0); - while (!blob->atEnd()) - { - int l; + blob->seek(0); + while (!blob->atEnd()) + { + int l; - len = blob->read(msg, sizeof(msg)); - l = clientSock->write(msg, len); - Q_ASSERT(l == len); - } + len = blob->read(msg, sizeof(msg)); + l = clientSock->write(msg, len); + Q_ASSERT(l == len); + } - goto _exit; - } + goto _exit; + } - if (!resp->IsInitialized()) - { - qWarning("response missing required fields!!"); - qDebug(resp->InitializationErrorString().c_str()); - qFatal("exiting"); - goto _exit; - } + if (!resp->IsInitialized()) + { + qWarning("response missing required fields!!"); + qDebug(resp->InitializationErrorString().c_str()); + qFatal("exiting"); + goto _exit; + } - resp->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg)); + resp->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg)); - len = resp->ByteSize(); + len = resp->ByteSize(); - *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_RESPONSE); // type - *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method - *((quint32*)(&msg[4])) = HTONL(len); // len + *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_RESPONSE); // type + *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method + *((quint32*)(&msg[4])) = HTONL(len); // len - // Avoid printing stats since it happens once every couple of seconds - if (pendingMethodId != 12) - { - qDebug("Server(%s): sending %d bytes to client encoding <%s>", - __FUNCTION__, len + PB_HDR_SIZE, resp->DebugString().c_str()); - //BUFDUMP(msg, len + 8); - } + // Avoid printing stats since it happens once every couple of seconds + if (pendingMethodId != 12) + { + qDebug("Server(%s): sending %d bytes to client encoding <%s>", + __FUNCTION__, len + PB_HDR_SIZE, resp->DebugString().c_str()); + //BUFDUMP(msg, len + 8); + } - clientSock->write(msg, PB_HDR_SIZE + len); + clientSock->write(msg, PB_HDR_SIZE + len); _exit: - delete PbRpcController; - isPending = false; + delete PbRpcController; + isPending = false; } void RpcServer::when_newConnection() { - if (clientSock) - { - QTcpSocket *sock; + if (clientSock) + { + QTcpSocket *sock; - qDebug("already connected, no new connections will be accepted"); + qDebug("already connected, no new connections will be accepted"); - // Accept and close connection - //! \todo (MED) Send reason msg to client - sock = server->nextPendingConnection(); - sock->disconnectFromHost(); - sock->deleteLater(); - goto _exit; - } + // Accept and close connection + //! \todo (MED) Send reason msg to client + sock = server->nextPendingConnection(); + sock->disconnectFromHost(); + sock->deleteLater(); + goto _exit; + } - clientSock = server->nextPendingConnection(); - qDebug("accepting new connection from %s: %d", - clientSock->peerAddress().toString().toAscii().constData(), - clientSock->peerPort()); + clientSock = server->nextPendingConnection(); + qDebug("accepting new connection from %s: %d", + clientSock->peerAddress().toString().toAscii().constData(), + clientSock->peerPort()); - connect(clientSock, SIGNAL(readyRead()), - this, SLOT(when_dataAvail())); - connect(clientSock, SIGNAL(disconnected()), - this, SLOT(when_disconnected())); - connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(when_error(QAbstractSocket::SocketError))); + connect(clientSock, SIGNAL(readyRead()), + this, SLOT(when_dataAvail())); + connect(clientSock, SIGNAL(disconnected()), + this, SLOT(when_disconnected())); + connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(when_error(QAbstractSocket::SocketError))); _exit: - return; + return; } void RpcServer::when_disconnected() { - qDebug("connection closed from %s: %d", - clientSock->peerAddress().toString().toAscii().constData(), - clientSock->peerPort()); + qDebug("connection closed from %s: %d", + clientSock->peerAddress().toString().toAscii().constData(), + clientSock->peerPort()); - clientSock->deleteLater(); - clientSock = NULL; + clientSock->deleteLater(); + clientSock = NULL; } void RpcServer::when_error(QAbstractSocket::SocketError socketError) { - qDebug("%s", clientSock->errorString().toAscii().constData()); + qDebug("%s", clientSock->errorString().toAscii().constData()); } void RpcServer::when_dataAvail() { - char msg[MSGBUF_SIZE]; - int msgLen; - static bool parsing = false; - static quint16 type, method; - static quint32 len; - const ::google::protobuf::MethodDescriptor *methodDesc; - ::google::protobuf::Message *req, *resp; - PbRpcController *controller; + char msg[MSGBUF_SIZE]; + int msgLen; + static bool parsing = false; + static quint16 type, method; + static quint32 len; + const ::google::protobuf::MethodDescriptor *methodDesc; + ::google::protobuf::Message *req, *resp; + PbRpcController *controller; - if (!parsing) - { - if (clientSock->bytesAvailable() < PB_HDR_SIZE) - return; + if (!parsing) + { + if (clientSock->bytesAvailable() < PB_HDR_SIZE) + return; - msgLen = clientSock->read(msg, PB_HDR_SIZE); + msgLen = clientSock->read(msg, PB_HDR_SIZE); - Q_ASSERT(msgLen == PB_HDR_SIZE); + Q_ASSERT(msgLen == PB_HDR_SIZE); - type = NTOHS(GET16(&msg[0])); - method = NTOHS(GET16(&msg[2])); - len = NTOHL(GET32(&msg[4])); - //qDebug("type = %d, method = %d, len = %d", type, method, len); + type = NTOHS(GET16(&msg[0])); + method = NTOHS(GET16(&msg[2])); + len = NTOHL(GET32(&msg[4])); + //qDebug("type = %d, method = %d, len = %d", type, method, len); - parsing = true; - } + parsing = true; + } - if (clientSock->bytesAvailable() < len) - return; + if (clientSock->bytesAvailable() < len) + return; - msgLen = clientSock->read(msg, sizeof(msg)); - Q_ASSERT((unsigned) msgLen == len); + msgLen = clientSock->read(msg, sizeof(msg)); + Q_ASSERT((unsigned) msgLen == len); - if (type != PB_MSG_TYPE_REQUEST) - { - qDebug("server(%s): unexpected msg type %d (expected %d)", __FUNCTION__, - type, PB_MSG_TYPE_REQUEST); - goto _error_exit; - } + if (type != PB_MSG_TYPE_REQUEST) + { + qDebug("server(%s): unexpected msg type %d (expected %d)", __FUNCTION__, + type, PB_MSG_TYPE_REQUEST); + goto _error_exit; + } - methodDesc = service->GetDescriptor()->method(method); - if (!methodDesc) - { - qDebug("server(%s): invalid method id %d", __FUNCTION__, method); - goto _error_exit; //! \todo Return Error to client - } + methodDesc = service->GetDescriptor()->method(method); + if (!methodDesc) + { + qDebug("server(%s): invalid method id %d", __FUNCTION__, method); + goto _error_exit; //! \todo Return Error to client + } - if (isPending) - { - qDebug("server(%s): rpc pending, try again", __FUNCTION__); - goto _error_exit; //! \todo Return Error to client - } + if (isPending) + { + qDebug("server(%s): rpc pending, try again", __FUNCTION__); + goto _error_exit; //! \todo Return Error to client + } - pendingMethodId = method; - isPending = true; + pendingMethodId = method; + isPending = true; - req = service->GetRequestPrototype(methodDesc).New(); - resp = service->GetResponsePrototype(methodDesc).New(); + req = service->GetRequestPrototype(methodDesc).New(); + resp = service->GetResponsePrototype(methodDesc).New(); - req->ParseFromArray((void*)msg, len); - if (!req->IsInitialized()) - { - qWarning("Missing required fields in request"); - qDebug(req->InitializationErrorString().c_str()); - qFatal("exiting"); - delete req; - delete resp; + req->ParseFromArray((void*)msg, len); + if (!req->IsInitialized()) + { + qWarning("Missing required fields in request"); + qDebug(req->InitializationErrorString().c_str()); + qFatal("exiting"); + delete req; + delete resp; - goto _error_exit; - } - //qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, - //resp->DebugString().c_str()); + goto _error_exit; + } + //qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, + //resp->DebugString().c_str()); - controller = new PbRpcController; + controller = new PbRpcController; - //qDebug("before service->callmethod()"); + //qDebug("before service->callmethod()"); - service->CallMethod(methodDesc, controller, req, resp, - NewCallback(this, &RpcServer::done, resp, controller)); + service->CallMethod(methodDesc, controller, req, resp, + NewCallback(this, &RpcServer::done, resp, controller)); - parsing = false; + parsing = false; - return; + return; _error_exit: - parsing = false; - qDebug("server(%s): discarding msg from client", __FUNCTION__); - return; + parsing = false; + qDebug("server(%s): discarding msg from client", __FUNCTION__); + return; } diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h index 619cb2d..e353628 100644 --- a/rpc/rpcserver.h +++ b/rpc/rpcserver.h @@ -14,31 +14,31 @@ class RpcServer : public QObject { - Q_OBJECT + Q_OBJECT - QTcpServer *server; - QTcpSocket *clientSock; + QTcpServer *server; + QTcpSocket *clientSock; - ::google::protobuf::Service *service; + ::google::protobuf::Service *service; - bool isPending; - int pendingMethodId; - QString errorString_; + bool isPending; + int pendingMethodId; + QString errorString_; public: - RpcServer(); //! \todo (LOW) use 'parent' param - virtual ~RpcServer(); + RpcServer(); //! \todo (LOW) use 'parent' param + virtual ~RpcServer(); - bool registerService(::google::protobuf::Service *service, - quint16 tcpPortNum); - QString errorString(); - void done(::google::protobuf::Message *resp, PbRpcController *controller); + bool registerService(::google::protobuf::Service *service, + quint16 tcpPortNum); + QString errorString(); + void done(::google::protobuf::Message *resp, PbRpcController *controller); private slots: - void when_newConnection(); - void when_disconnected(); - void when_dataAvail(); - void when_error(QAbstractSocket::SocketError socketError); + void when_newConnection(); + void when_disconnected(); + void when_dataAvail(); + void when_error(QAbstractSocket::SocketError socketError); }; #endif diff --git a/server/drone.cpp b/server/drone.cpp index c84aec5..d7609de 100644 --- a/server/drone.cpp +++ b/server/drone.cpp @@ -19,58 +19,58 @@ Drone::Drone(QWidget *parent) Drone::~Drone() { - trayIcon_->hide(); - delete rpcServer; - delete service; + trayIcon_->hide(); + delete rpcServer; + delete service; } bool Drone::init() { - Q_ASSERT(rpcServer); + Q_ASSERT(rpcServer); if (!rpcServer->registerService(service, myport ? myport : 7878)) - { - QMessageBox::critical(0, qApp->applicationName(), - rpcServer->errorString()); - return false; - } + { + QMessageBox::critical(0, qApp->applicationName(), + rpcServer->errorString()); + return false; + } - trayIconMenu_ = new QMenu(this); + trayIconMenu_ = new QMenu(this); - trayIconMenu_->addAction(actionShow); - trayIconMenu_->addAction(actionExit); - trayIconMenu_->setDefaultAction(actionShow); - trayIcon_ = new QSystemTrayIcon(); - trayIcon_->setIcon(QIcon(":/icons/portgroup.png")); - trayIcon_->setToolTip(qApp->applicationName()); - trayIcon_->setContextMenu(trayIconMenu_); - trayIcon_->show(); + trayIconMenu_->addAction(actionShow); + trayIconMenu_->addAction(actionExit); + trayIconMenu_->setDefaultAction(actionShow); + trayIcon_ = new QSystemTrayIcon(); + trayIcon_->setIcon(QIcon(":/icons/portgroup.png")); + trayIcon_->setToolTip(qApp->applicationName()); + trayIcon_->setContextMenu(trayIconMenu_); + trayIcon_->show(); - connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); - connect(this, SIGNAL(hideMe(bool)), this, SLOT(setHidden(bool)), - Qt::QueuedConnection); + connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + connect(this, SIGNAL(hideMe(bool)), this, SLOT(setHidden(bool)), + Qt::QueuedConnection); - return true; + return true; } void Drone::changeEvent(QEvent *event) { - if (event->type() == QEvent::WindowStateChange && isMinimized()) - { - emit hideMe(true); - event->ignore(); - return; - } + if (event->type() == QEvent::WindowStateChange && isMinimized()) + { + emit hideMe(true); + event->ignore(); + return; + } - QWidget::changeEvent(event); + QWidget::changeEvent(event); } void Drone::trayIconActivated(QSystemTrayIcon::ActivationReason reason) { - if (reason == QSystemTrayIcon::DoubleClick) - { - showNormal(); - activateWindow(); - } + if (reason == QSystemTrayIcon::DoubleClick) + { + showNormal(); + activateWindow(); + } } diff --git a/server/drone.h b/server/drone.h index 5930dd0..c441af7 100644 --- a/server/drone.h +++ b/server/drone.h @@ -15,23 +15,23 @@ class Drone : public QWidget, Ui::Drone public: Drone(QWidget *parent = 0); - ~Drone(); + ~Drone(); bool init(); signals: - void hideMe(bool hidden); + void hideMe(bool hidden); protected: - void changeEvent(QEvent *event); + void changeEvent(QEvent *event); private: - QSystemTrayIcon *trayIcon_; - QMenu *trayIconMenu_; + QSystemTrayIcon *trayIcon_; + QMenu *trayIconMenu_; RpcServer *rpcServer; OstProto::OstService *service; private slots: - void trayIconActivated(QSystemTrayIcon::ActivationReason reason); + void trayIconActivated(QSystemTrayIcon::ActivationReason reason); }; #endif diff --git a/server/drone.pro b/server/drone.pro index fe06b4e..a402b4c 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -15,12 +15,12 @@ RESOURCES += drone.qrc HEADERS += drone.h FORMS += drone.ui SOURCES += \ - drone_main.cpp \ - drone.cpp \ - portmanager.cpp \ - abstractport.cpp \ - pcapport.cpp \ - winpcapport.cpp + drone_main.cpp \ + drone.cpp \ + portmanager.cpp \ + abstractport.cpp \ + pcapport.cpp \ + winpcapport.cpp SOURCES += myservice.cpp SOURCES += pcapextra.cpp diff --git a/server/drone_main.cpp b/server/drone_main.cpp index 6a9052f..f6baad2 100644 --- a/server/drone_main.cpp +++ b/server/drone_main.cpp @@ -5,21 +5,21 @@ int myport; int main(int argc, char *argv[]) { QApplication app(argc, argv); - Drone drone; + Drone drone; - app.setApplicationName(drone.objectName()); + app.setApplicationName(drone.objectName()); - if (argc > 1) - myport = atoi(argv[1]); + if (argc > 1) + myport = atoi(argv[1]); - if (!drone.init()) - exit(-1); + if (!drone.init()) + exit(-1); - drone.setWindowFlags(drone.windowFlags() - | Qt::WindowMaximizeButtonHint - | Qt::WindowMinimizeButtonHint); + drone.setWindowFlags(drone.windowFlags() + | Qt::WindowMaximizeButtonHint + | Qt::WindowMinimizeButtonHint); drone.showMinimized(); app.exec(); - return 0; + return 0; } diff --git a/server/pcapextra.cpp b/server/pcapextra.cpp index 8274d48..b4fdba7 100644 --- a/server/pcapextra.cpp +++ b/server/pcapextra.cpp @@ -1,6 +1,6 @@ #include "pcapextra.h" -#include // memcpy() +#include // memcpy() #include // malloc(), free() /* NOTE: All code borrowed from WinPcap */ @@ -8,51 +8,51 @@ #ifndef Q_OS_WIN32 pcap_send_queue* pcap_sendqueue_alloc (u_int memsize) { - pcap_send_queue *tqueue; + pcap_send_queue *tqueue; - /* Allocate the queue */ - tqueue = (pcap_send_queue*)malloc(sizeof(pcap_send_queue)); - if(tqueue == NULL){ - return NULL; - } + /* Allocate the queue */ + tqueue = (pcap_send_queue*)malloc(sizeof(pcap_send_queue)); + if(tqueue == NULL){ + return NULL; + } - /* Allocate the buffer */ - tqueue->buffer = (char*)malloc(memsize); - if(tqueue->buffer == NULL){ - free(tqueue); - return NULL; - } + /* Allocate the buffer */ + tqueue->buffer = (char*)malloc(memsize); + if(tqueue->buffer == NULL){ + free(tqueue); + return NULL; + } - tqueue->maxlen = memsize; - tqueue->len = 0; + tqueue->maxlen = memsize; + tqueue->len = 0; - return tqueue; + return tqueue; } void pcap_sendqueue_destroy (pcap_send_queue *queue) { - free(queue->buffer); - free(queue); + free(queue->buffer); + free(queue); } int pcap_sendqueue_queue (pcap_send_queue *queue, - const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) + const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) { - if(queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > - queue->maxlen) - { - return -1; - } + if(queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > + queue->maxlen) + { + return -1; + } - /* Copy the pcap_pkthdr header*/ - memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr)); - queue->len += sizeof(struct pcap_pkthdr); + /* Copy the pcap_pkthdr header*/ + memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr)); + queue->len += sizeof(struct pcap_pkthdr); - /* copy the packet */ - memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen); - queue->len += pkt_header->caplen; + /* copy the packet */ + memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen); + queue->len += pkt_header->caplen; - return 0; + return 0; } #endif diff --git a/server/pcapextra.h b/server/pcapextra.h index e0dd23b..1f1c9f3 100644 --- a/server/pcapextra.h +++ b/server/pcapextra.h @@ -6,19 +6,19 @@ #ifndef Q_OS_WIN32 -//#define PCAP_OPENFLAG_PROMISCUOUS 1 +//#define PCAP_OPENFLAG_PROMISCUOUS 1 struct pcap_send_queue { - u_int maxlen; - u_int len; - char *buffer; + u_int maxlen; + u_int len; + char *buffer; }; pcap_send_queue* pcap_sendqueue_alloc (u_int memsize); void pcap_sendqueue_destroy (pcap_send_queue *queue); int pcap_sendqueue_queue (pcap_send_queue *queue, - const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); + const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); #endif From a9e9a7db07cd0290aff7830a01099683caedd4a5 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 28 Dec 2009 08:34:47 +0000 Subject: [PATCH 37/98] Removed vim modelines since we have a project .vimrc now --- server/abstractport.cpp | 2 -- server/abstractport.h | 2 -- server/myservice.cpp | 2 -- server/myservice.h | 2 -- server/pcapport.cpp | 2 -- server/pcapport.h | 2 -- server/portmanager.cpp | 3 --- server/portmanager.h | 2 -- server/winpcapport.cpp | 2 -- server/winpcapport.h | 2 -- 10 files changed, 21 deletions(-) diff --git a/server/abstractport.cpp b/server/abstractport.cpp index 8cbecd9..dfaf5b9 100644 --- a/server/abstractport.cpp +++ b/server/abstractport.cpp @@ -210,5 +210,3 @@ void AbstractPort::stats(PortStats *stats) stats->txPps = stats_.txPps; stats->txBps = stats_.txBps; } - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/abstractport.h b/server/abstractport.h index 6c0bcc3..e39d0f9 100644 --- a/server/abstractport.h +++ b/server/abstractport.h @@ -78,5 +78,3 @@ private: }; #endif - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/myservice.cpp b/server/myservice.cpp index e742fe6..4da9b7e 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -419,5 +419,3 @@ void MyService::clearStats(::google::protobuf::RpcController* controller, done->Run(); } - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/myservice.h b/server/myservice.h index 5d434ee..a813367 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -81,5 +81,3 @@ private: }; #endif - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/pcapport.cpp b/server/pcapport.cpp index 86a5086..a133812 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -403,5 +403,3 @@ QFile* PcapPort::PortCapturer::captureFile() { return &capFile_; } - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/pcapport.h b/server/pcapport.h index 8fee855..a17e665 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -117,5 +117,3 @@ private: }; #endif - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/portmanager.cpp b/server/portmanager.cpp index bd7fd78..6105559 100644 --- a/server/portmanager.cpp +++ b/server/portmanager.cpp @@ -52,6 +52,3 @@ PortManager* PortManager::instance() return instance_; } - - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/portmanager.h b/server/portmanager.h index c71c6a6..1d4bd73 100644 --- a/server/portmanager.h +++ b/server/portmanager.h @@ -22,5 +22,3 @@ private: }; #endif - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp index 7e04a42..4e64913 100644 --- a/server/winpcapport.cpp +++ b/server/winpcapport.cpp @@ -140,5 +140,3 @@ void WinPcapPort::PortMonitor::run() QThread::msleep(1000); } } - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ diff --git a/server/winpcapport.h b/server/winpcapport.h index 100ad2a..3f2a3b0 100644 --- a/server/winpcapport.h +++ b/server/winpcapport.h @@ -27,5 +27,3 @@ private: }; #endif - -/* vim: set shiftwidth=4 tabstop=8 softtabstop=4 expandtab: */ From c5bcc2e0c2580ffa1f1e9ffbd38abec482e0b4e7 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 28 Dec 2009 10:05:42 +0000 Subject: [PATCH 38/98] Converted all EOLs to unix-style '\n' only --- client/dumpview.cpp | 774 ++++++------- client/dumpview.h | 84 +- client/hexlineedit.cpp | 144 +-- client/hexlineedit.h | 48 +- client/main.cpp | 24 +- client/mainwindow.cpp | 130 +-- client/mainwindow.h | 66 +- client/ostinato.pro | 114 +- client/packetmodel.cpp | 440 +++---- client/packetmodel.h | 80 +- client/port.cpp | 394 +++---- client/port.h | 196 ++-- client/portgroup.cpp | 1436 +++++++++++------------ client/portgroup.h | 238 ++-- client/portgrouplist.cpp | 196 ++-- client/portgrouplist.h | 104 +- client/portmodel.cpp | 622 +++++----- client/portmodel.h | 102 +- client/portstatsfilterdialog.cpp | 222 ++-- client/portstatsfilterdialog.h | 70 +- client/portstatsmodel.cpp | 576 +++++----- client/portstatsmodel.h | 234 ++-- client/portstatswindow.cpp | 322 +++--- client/portstatswindow.h | 74 +- client/portswindow.cpp | 832 +++++++------- client/portswindow.h | 116 +- client/stream.cpp | 120 +- client/stream.h | 46 +- client/streamconfigdialog.cpp | 1850 +++++++++++++++--------------- client/streamconfigdialog.h | 226 ++-- client/streammodel.cpp | 484 ++++---- client/streammodel.h | 114 +- common/protocol.proto | 420 +++---- rpc/pbhelper.h | 302 ++--- rpc/pbrpc.pro | 16 +- rpc/pbrpcchannel.cpp | 620 +++++----- rpc/pbrpcchannel.h | 166 +-- rpc/pbrpccommon.h | 122 +- rpc/pbrpccontroller.h | 68 +- rpc/rpcserver.cpp | 512 ++++----- rpc/rpcserver.h | 88 +- server/drone.cpp | 152 +-- server/drone.h | 74 +- server/drone.pro | 52 +- server/drone_main.cpp | 50 +- server/myservice.cpp | 842 +++++++------- 46 files changed, 6981 insertions(+), 6981 deletions(-) diff --git a/client/dumpview.cpp b/client/dumpview.cpp index d846164..0056502 100644 --- a/client/dumpview.cpp +++ b/client/dumpview.cpp @@ -1,387 +1,387 @@ -#include "dumpview.h" - -//! \todo Enable Scrollbars - -DumpView::DumpView(QWidget *parent) -{ - int w, h; - - // NOTE: Monospaced fonts only !!!!!!!!!!! - setFont(QFont("Courier")); - w = fontMetrics().width('X'); - h = fontMetrics().height(); - - mLineHeight = h; - mCharWidth = w; - - mSelectedRow = mSelectedCol = -1; - - // calculate width for offset column and the whitespace that follows it - // 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ - mOffsetPaneTopRect = QRect(0, 0, w*4, h); - mDumpPaneTopRect = QRect(mOffsetPaneTopRect.right()+w*3, 0, - w*((8*3-1)+2+(8*3-1)), h); - mAsciiPaneTopRect = QRect(mDumpPaneTopRect.right()+w*3, 0, - w*(8+1+8), h); - qDebug("DumpView::DumpView"); -} - -QModelIndex DumpView::indexAt( const QPoint &point ) const -{ -#if 0 - int x = point.x(); - int row, col; - - if (x > mAsciiPaneTopRect.left()) - { - col = (x - mAsciiPaneTopRect.left()) / mCharWidth; - if (col == 8) // don't select whitespace - goto _exit; - else if (col > 8) // adjust for whitespace - col--; - } - else if (x > mDumpPaneTopRect.left()) - { - col = (x - mDumpPaneTopRect.left()) / (mCharWidth*3); - } - row = point.y()/mLineHeight; - - if ((col < 16) && (row < ((data.size()+16)/16))) - { - selrow = row; - selcol = col; - } - else - goto _exit; - - // last row check col - if ((row == (((data.size()+16)/16) - 1)) && (col >= (data.size() % 16))) - goto _exit; - - qDebug("dumpview::selection(%d, %d)", selrow, selcol); - - offset = selrow * 16 + selcol; -#if 0 - for(int i = 0; i < model()->rowCount(parent); i++) - { - QModelIndex index = model()->index(i, 0, parent); - - if (model()->hasChildren(index)) - indexAtOffset(offset, index); // Non Leaf - else - if ( - dump.append(model()->data(index, Qt::UserRole).toByteArray()); // Leaf - // FIXME: Use RawValueRole instead of UserRole - } -#endif -} - -_exit: - // Clear existing selection - selrow = -1; - -#endif - return QModelIndex(); -} - -void DumpView::scrollTo( const QModelIndex &index, ScrollHint hint ) -{ - // FIXME: implement scrolling -} - -QRect DumpView::visualRect( const QModelIndex &index ) const -{ - // FIXME: calculate actual rect - return rect(); -} - -//protected: -int DumpView::horizontalOffset() const -{ - return horizontalScrollBar()->value(); -} - -bool DumpView::isIndexHidden( const QModelIndex &index ) const -{ - return false; -} - -QModelIndex DumpView::moveCursor( CursorAction cursorAction, - Qt::KeyboardModifiers modifiers ) -{ - // FIXME(MED): need to implement movement using cursor - return currentIndex(); -} - -void DumpView::setSelection( const QRect &rect, - QItemSelectionModel::SelectionFlags flags ) -{ - // FIXME(HI): calculate indexes using rect - selectionModel()->select(QModelIndex(), flags); -} - -int DumpView::verticalOffset() const -{ - return verticalScrollBar()->value(); -} - -QRegion DumpView::visualRegionForSelection( const QItemSelection &selection ) const -{ - // FIXME(HI) - return QRegion(rect()); -} - -//protected slots: -void DumpView::dataChanged( const QModelIndex &topLeft, - const QModelIndex &bottomRight ) -{ - // FIXME(HI) - update(); -} - -void DumpView::selectionChanged( const QItemSelection &selected, - const QItemSelection &deselected ) -{ - // FIXME(HI) - update(); -} - -void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize, - QModelIndex parent) -{ - // FIXME: Use new enum instead of Qt::UserRole - //! \todo (low): generalize this for any model not just our pkt model - - Q_ASSERT(!parent.isValid()); - - qDebug("!!!! %d $$$$", dump.size()); - - for(int i = 0; i < model()->rowCount(parent); i++) - { - QModelIndex index = model()->index(i, 0, parent); - - Q_ASSERT(index.isValid()); - - // Assumption: protocol data is in bytes (not bits) - qDebug("%d: %d bytes", i, model()->data(index, Qt::UserRole).toByteArray().size()); - dump.append(model()->data(index, Qt::UserRole).toByteArray()); - - } - - if (selectionModel()->selectedIndexes().size()) - { - int j, bits; - QModelIndex index; - - Q_ASSERT(selectionModel()->selectedIndexes().size() == 1); - index = selectionModel()->selectedIndexes().at(0); - - if (index.parent().isValid()) - { - // Field - - // SelOfs = SUM(protocol sizes before selected field's protocol) + - // SUM(field sizes before selected field) - - selOfs = 0; - j = index.parent().row() - 1; - while (j >= 0) - { - selOfs += model()->data(index.parent().sibling(j,0), - Qt::UserRole).toByteArray().size(); - j--; - } - - bits = 0; - j = index.row() - 1; - while (j >= 0) - { - bits += model()->data(index.sibling(j,0), Qt::UserRole+1). - toInt(); - j--; - } - selOfs += bits/8; - selSize = model()->data(index, Qt::UserRole).toByteArray().size(); - } - else - { - // Protocol - selOfs = 0; - j = index.row() - 1; - while (j >= 0) - { - selOfs += model()->data(index.sibling(j,0), Qt::UserRole). - toByteArray().size(); - j--; - } - selSize = model()->data(index, Qt::UserRole).toByteArray().size(); - } - } -} - -// TODO(LOW): rewrite this function - it's a mess! -void DumpView::paintEvent(QPaintEvent* event) -{ - QStylePainter painter(viewport()); - QRect offsetRect = mOffsetPaneTopRect; - QRect dumpRect = mDumpPaneTopRect; - QRect asciiRect = mAsciiPaneTopRect; - QPalette pal = palette(); - static QByteArray data; - //QByteArray ba; - int selOfs = -1, selSize; - int curSelOfs, curSelSize; - - qDebug("dumpview::paintEvent"); - - // FIXME(LOW): unable to set the self widget's font in constructor - painter.setFont(QFont("Courier")); - - // set a white background - painter.fillRect(rect(), QBrush(QColor(Qt::white))); - - if (model()) - { - data.clear(); - populateDump(data, selOfs, selSize); - } - - // display the offset, dump and ascii panes 8 + 8 bytes on a line - for (int i = 0; i < data.size(); i+=16) - { - QString dumpStr, asciiStr; - - //ba = data.mid(i, 16); - - // display offset - painter.drawItemText(offsetRect, Qt::AlignLeft | Qt::AlignTop, pal, - true, QString("%1").arg(i, 4, 16, QChar('0')), QPalette::WindowText); - // construct the dumpStr and asciiStr - for (int j = i; (j < (i+16)) && (j < data.size()); j++) - { - unsigned char c = data.at(j); - - // extra space after 8 bytes - if (((j+8) % 16) == 0) - { - dumpStr.append(" "); - asciiStr.append(" "); - } - - dumpStr.append(QString("%1").arg((uint)c, 2, 16, QChar('0')). - toUpper()).append(" "); - - if (isPrintable(c)) - asciiStr.append(QChar(c)); - else - asciiStr.append(QChar('.')); - } - - // display dump - painter.drawItemText(dumpRect, Qt::AlignLeft | Qt::AlignTop, pal, - true, dumpStr, QPalette::WindowText); - - // display ascii - painter.drawItemText(asciiRect, Qt::AlignLeft | Qt::AlignTop, pal, - true, asciiStr, QPalette::WindowText); - - // if no selection, skip selection painting - if (selOfs < 0) - goto _next; - - // Check overlap between current row and selection - { - QRect r1(i, 0, qMin(16, data.size()-i), 8); - QRect s1(selOfs, 0, selSize, 8); - if (r1.intersects(s1)) - { - QRect t = r1.intersected(s1); - - curSelOfs = t.x(); - curSelSize = t.width(); - } - else - curSelSize = 0; - - } - - // overpaint selection on current row (if any) - if (curSelSize > 0) - { - QRect r; - QString selectedAsciiStr, selectedDumpStr; - - qDebug("dumpview::paintEvent - Highlighted (%d, %d)", - curSelOfs, curSelSize); - - // construct the dumpStr and asciiStr - for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++) - { - unsigned char c = data.at(k); - - // extra space after 8 bytes - if (((k+8) % 16) == 0) - { - // Avoid adding space at the start for fields starting - // at second column 8 byte boundary - if (k!=curSelOfs) - { - selectedDumpStr.append(" "); - selectedAsciiStr.append(" "); - } - } - - selectedDumpStr.append(QString("%1").arg((uint)c, 2, 16, - QChar('0')).toUpper()).append(" "); - - if (isPrintable(c)) - selectedAsciiStr.append(QChar(c)); - else - selectedAsciiStr.append(QChar('.')); - } - - // display dump - r = dumpRect; - if ((curSelOfs - i) < 8) - r.translate(mCharWidth*(curSelOfs-i)*3, 0); - else - r.translate(mCharWidth*((curSelOfs-i)*3+1), 0); - - // adjust width taking care of selection stretching between - // the two 8byte columns - if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) - r.setWidth((curSelSize * 3 + 1) * mCharWidth); - else - r.setWidth((curSelSize * 3) * mCharWidth); - - painter.fillRect(r, pal.highlight()); - painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, - true, selectedDumpStr, QPalette::HighlightedText); - - // display ascii - r = asciiRect; - if ((curSelOfs - i) < 8) - r.translate(mCharWidth*(curSelOfs-i)*1, 0); - else - r.translate(mCharWidth*((curSelOfs-i)*1+1), 0); - - // adjust width taking care of selection stretching between - // the two 8byte columns - if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) - r.setWidth((curSelSize * 1 + 1) * mCharWidth); - else - r.setWidth((curSelSize * 1) * mCharWidth); - - painter.fillRect(r, pal.highlight()); - painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, - true, selectedAsciiStr, QPalette::HighlightedText); - } - -_next: - // move the rects down - offsetRect.translate(0, mLineHeight); - dumpRect.translate(0, mLineHeight); - asciiRect.translate(0, mLineHeight); - } -} - +#include "dumpview.h" + +//! \todo Enable Scrollbars + +DumpView::DumpView(QWidget *parent) +{ + int w, h; + + // NOTE: Monospaced fonts only !!!!!!!!!!! + setFont(QFont("Courier")); + w = fontMetrics().width('X'); + h = fontMetrics().height(); + + mLineHeight = h; + mCharWidth = w; + + mSelectedRow = mSelectedCol = -1; + + // calculate width for offset column and the whitespace that follows it + // 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ + mOffsetPaneTopRect = QRect(0, 0, w*4, h); + mDumpPaneTopRect = QRect(mOffsetPaneTopRect.right()+w*3, 0, + w*((8*3-1)+2+(8*3-1)), h); + mAsciiPaneTopRect = QRect(mDumpPaneTopRect.right()+w*3, 0, + w*(8+1+8), h); + qDebug("DumpView::DumpView"); +} + +QModelIndex DumpView::indexAt( const QPoint &point ) const +{ +#if 0 + int x = point.x(); + int row, col; + + if (x > mAsciiPaneTopRect.left()) + { + col = (x - mAsciiPaneTopRect.left()) / mCharWidth; + if (col == 8) // don't select whitespace + goto _exit; + else if (col > 8) // adjust for whitespace + col--; + } + else if (x > mDumpPaneTopRect.left()) + { + col = (x - mDumpPaneTopRect.left()) / (mCharWidth*3); + } + row = point.y()/mLineHeight; + + if ((col < 16) && (row < ((data.size()+16)/16))) + { + selrow = row; + selcol = col; + } + else + goto _exit; + + // last row check col + if ((row == (((data.size()+16)/16) - 1)) && (col >= (data.size() % 16))) + goto _exit; + + qDebug("dumpview::selection(%d, %d)", selrow, selcol); + + offset = selrow * 16 + selcol; +#if 0 + for(int i = 0; i < model()->rowCount(parent); i++) + { + QModelIndex index = model()->index(i, 0, parent); + + if (model()->hasChildren(index)) + indexAtOffset(offset, index); // Non Leaf + else + if ( + dump.append(model()->data(index, Qt::UserRole).toByteArray()); // Leaf + // FIXME: Use RawValueRole instead of UserRole + } +#endif +} + +_exit: + // Clear existing selection + selrow = -1; + +#endif + return QModelIndex(); +} + +void DumpView::scrollTo( const QModelIndex &index, ScrollHint hint ) +{ + // FIXME: implement scrolling +} + +QRect DumpView::visualRect( const QModelIndex &index ) const +{ + // FIXME: calculate actual rect + return rect(); +} + +//protected: +int DumpView::horizontalOffset() const +{ + return horizontalScrollBar()->value(); +} + +bool DumpView::isIndexHidden( const QModelIndex &index ) const +{ + return false; +} + +QModelIndex DumpView::moveCursor( CursorAction cursorAction, + Qt::KeyboardModifiers modifiers ) +{ + // FIXME(MED): need to implement movement using cursor + return currentIndex(); +} + +void DumpView::setSelection( const QRect &rect, + QItemSelectionModel::SelectionFlags flags ) +{ + // FIXME(HI): calculate indexes using rect + selectionModel()->select(QModelIndex(), flags); +} + +int DumpView::verticalOffset() const +{ + return verticalScrollBar()->value(); +} + +QRegion DumpView::visualRegionForSelection( const QItemSelection &selection ) const +{ + // FIXME(HI) + return QRegion(rect()); +} + +//protected slots: +void DumpView::dataChanged( const QModelIndex &topLeft, + const QModelIndex &bottomRight ) +{ + // FIXME(HI) + update(); +} + +void DumpView::selectionChanged( const QItemSelection &selected, + const QItemSelection &deselected ) +{ + // FIXME(HI) + update(); +} + +void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize, + QModelIndex parent) +{ + // FIXME: Use new enum instead of Qt::UserRole + //! \todo (low): generalize this for any model not just our pkt model + + Q_ASSERT(!parent.isValid()); + + qDebug("!!!! %d $$$$", dump.size()); + + for(int i = 0; i < model()->rowCount(parent); i++) + { + QModelIndex index = model()->index(i, 0, parent); + + Q_ASSERT(index.isValid()); + + // Assumption: protocol data is in bytes (not bits) + qDebug("%d: %d bytes", i, model()->data(index, Qt::UserRole).toByteArray().size()); + dump.append(model()->data(index, Qt::UserRole).toByteArray()); + + } + + if (selectionModel()->selectedIndexes().size()) + { + int j, bits; + QModelIndex index; + + Q_ASSERT(selectionModel()->selectedIndexes().size() == 1); + index = selectionModel()->selectedIndexes().at(0); + + if (index.parent().isValid()) + { + // Field + + // SelOfs = SUM(protocol sizes before selected field's protocol) + + // SUM(field sizes before selected field) + + selOfs = 0; + j = index.parent().row() - 1; + while (j >= 0) + { + selOfs += model()->data(index.parent().sibling(j,0), + Qt::UserRole).toByteArray().size(); + j--; + } + + bits = 0; + j = index.row() - 1; + while (j >= 0) + { + bits += model()->data(index.sibling(j,0), Qt::UserRole+1). + toInt(); + j--; + } + selOfs += bits/8; + selSize = model()->data(index, Qt::UserRole).toByteArray().size(); + } + else + { + // Protocol + selOfs = 0; + j = index.row() - 1; + while (j >= 0) + { + selOfs += model()->data(index.sibling(j,0), Qt::UserRole). + toByteArray().size(); + j--; + } + selSize = model()->data(index, Qt::UserRole).toByteArray().size(); + } + } +} + +// TODO(LOW): rewrite this function - it's a mess! +void DumpView::paintEvent(QPaintEvent* event) +{ + QStylePainter painter(viewport()); + QRect offsetRect = mOffsetPaneTopRect; + QRect dumpRect = mDumpPaneTopRect; + QRect asciiRect = mAsciiPaneTopRect; + QPalette pal = palette(); + static QByteArray data; + //QByteArray ba; + int selOfs = -1, selSize; + int curSelOfs, curSelSize; + + qDebug("dumpview::paintEvent"); + + // FIXME(LOW): unable to set the self widget's font in constructor + painter.setFont(QFont("Courier")); + + // set a white background + painter.fillRect(rect(), QBrush(QColor(Qt::white))); + + if (model()) + { + data.clear(); + populateDump(data, selOfs, selSize); + } + + // display the offset, dump and ascii panes 8 + 8 bytes on a line + for (int i = 0; i < data.size(); i+=16) + { + QString dumpStr, asciiStr; + + //ba = data.mid(i, 16); + + // display offset + painter.drawItemText(offsetRect, Qt::AlignLeft | Qt::AlignTop, pal, + true, QString("%1").arg(i, 4, 16, QChar('0')), QPalette::WindowText); + // construct the dumpStr and asciiStr + for (int j = i; (j < (i+16)) && (j < data.size()); j++) + { + unsigned char c = data.at(j); + + // extra space after 8 bytes + if (((j+8) % 16) == 0) + { + dumpStr.append(" "); + asciiStr.append(" "); + } + + dumpStr.append(QString("%1").arg((uint)c, 2, 16, QChar('0')). + toUpper()).append(" "); + + if (isPrintable(c)) + asciiStr.append(QChar(c)); + else + asciiStr.append(QChar('.')); + } + + // display dump + painter.drawItemText(dumpRect, Qt::AlignLeft | Qt::AlignTop, pal, + true, dumpStr, QPalette::WindowText); + + // display ascii + painter.drawItemText(asciiRect, Qt::AlignLeft | Qt::AlignTop, pal, + true, asciiStr, QPalette::WindowText); + + // if no selection, skip selection painting + if (selOfs < 0) + goto _next; + + // Check overlap between current row and selection + { + QRect r1(i, 0, qMin(16, data.size()-i), 8); + QRect s1(selOfs, 0, selSize, 8); + if (r1.intersects(s1)) + { + QRect t = r1.intersected(s1); + + curSelOfs = t.x(); + curSelSize = t.width(); + } + else + curSelSize = 0; + + } + + // overpaint selection on current row (if any) + if (curSelSize > 0) + { + QRect r; + QString selectedAsciiStr, selectedDumpStr; + + qDebug("dumpview::paintEvent - Highlighted (%d, %d)", + curSelOfs, curSelSize); + + // construct the dumpStr and asciiStr + for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++) + { + unsigned char c = data.at(k); + + // extra space after 8 bytes + if (((k+8) % 16) == 0) + { + // Avoid adding space at the start for fields starting + // at second column 8 byte boundary + if (k!=curSelOfs) + { + selectedDumpStr.append(" "); + selectedAsciiStr.append(" "); + } + } + + selectedDumpStr.append(QString("%1").arg((uint)c, 2, 16, + QChar('0')).toUpper()).append(" "); + + if (isPrintable(c)) + selectedAsciiStr.append(QChar(c)); + else + selectedAsciiStr.append(QChar('.')); + } + + // display dump + r = dumpRect; + if ((curSelOfs - i) < 8) + r.translate(mCharWidth*(curSelOfs-i)*3, 0); + else + r.translate(mCharWidth*((curSelOfs-i)*3+1), 0); + + // adjust width taking care of selection stretching between + // the two 8byte columns + if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) + r.setWidth((curSelSize * 3 + 1) * mCharWidth); + else + r.setWidth((curSelSize * 3) * mCharWidth); + + painter.fillRect(r, pal.highlight()); + painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, + true, selectedDumpStr, QPalette::HighlightedText); + + // display ascii + r = asciiRect; + if ((curSelOfs - i) < 8) + r.translate(mCharWidth*(curSelOfs-i)*1, 0); + else + r.translate(mCharWidth*((curSelOfs-i)*1+1), 0); + + // adjust width taking care of selection stretching between + // the two 8byte columns + if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 )) + r.setWidth((curSelSize * 1 + 1) * mCharWidth); + else + r.setWidth((curSelSize * 1) * mCharWidth); + + painter.fillRect(r, pal.highlight()); + painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal, + true, selectedAsciiStr, QPalette::HighlightedText); + } + +_next: + // move the rects down + offsetRect.translate(0, mLineHeight); + dumpRect.translate(0, mLineHeight); + asciiRect.translate(0, mLineHeight); + } +} + diff --git a/client/dumpview.h b/client/dumpview.h index db17002..6f7db2e 100644 --- a/client/dumpview.h +++ b/client/dumpview.h @@ -1,42 +1,42 @@ -#include // FIXME: High - - -class DumpView: public QAbstractItemView -{ -public: - DumpView(QWidget *parent=0); - - QModelIndex indexAt( const QPoint &point ) const; - void scrollTo( const QModelIndex &index, ScrollHint hint = EnsureVisible ); - QRect visualRect( const QModelIndex &index ) const; - -protected: - int horizontalOffset() const; - bool isIndexHidden( const QModelIndex &index ) const; - QModelIndex moveCursor( CursorAction cursorAction, - Qt::KeyboardModifiers modifiers ); - void setSelection( const QRect &rect, QItemSelectionModel::SelectionFlags flags ); - int verticalOffset() const; - QRegion visualRegionForSelection( const QItemSelection &selection ) const; -protected slots: - void dataChanged( const QModelIndex &topLeft, - const QModelIndex &bottomRight ); - void selectionChanged( const QItemSelection &selected, - const QItemSelection &deselected ); - void paintEvent(QPaintEvent *event); - -private: - void populateDump(QByteArray &dump, int &selOfs, int &selSize, - QModelIndex parent = QModelIndex()); - bool inline isPrintable(char c) - {if ((c > 48) && (c < 126)) return true; else return false; } - -private: - QRect mOffsetPaneTopRect; - QRect mDumpPaneTopRect; - QRect mAsciiPaneTopRect; - int mSelectedRow, mSelectedCol; - int mLineHeight; - int mCharWidth; -}; - +#include // FIXME: High + + +class DumpView: public QAbstractItemView +{ +public: + DumpView(QWidget *parent=0); + + QModelIndex indexAt( const QPoint &point ) const; + void scrollTo( const QModelIndex &index, ScrollHint hint = EnsureVisible ); + QRect visualRect( const QModelIndex &index ) const; + +protected: + int horizontalOffset() const; + bool isIndexHidden( const QModelIndex &index ) const; + QModelIndex moveCursor( CursorAction cursorAction, + Qt::KeyboardModifiers modifiers ); + void setSelection( const QRect &rect, QItemSelectionModel::SelectionFlags flags ); + int verticalOffset() const; + QRegion visualRegionForSelection( const QItemSelection &selection ) const; +protected slots: + void dataChanged( const QModelIndex &topLeft, + const QModelIndex &bottomRight ); + void selectionChanged( const QItemSelection &selected, + const QItemSelection &deselected ); + void paintEvent(QPaintEvent *event); + +private: + void populateDump(QByteArray &dump, int &selOfs, int &selSize, + QModelIndex parent = QModelIndex()); + bool inline isPrintable(char c) + {if ((c > 48) && (c < 126)) return true; else return false; } + +private: + QRect mOffsetPaneTopRect; + QRect mDumpPaneTopRect; + QRect mAsciiPaneTopRect; + int mSelectedRow, mSelectedCol; + int mLineHeight; + int mCharWidth; +}; + diff --git a/client/hexlineedit.cpp b/client/hexlineedit.cpp index 5f099d0..4497710 100644 --- a/client/hexlineedit.cpp +++ b/client/hexlineedit.cpp @@ -1,72 +1,72 @@ -#include "hexlineedit.h" -#include "qdebug.h" - -QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets); - -HexLineEdit::HexLineEdit( QWidget * parent) - : QLineEdit(parent) -{ - //QLineEdit::QLineEdit(parent); -} - -void HexLineEdit::focusOutEvent( QFocusEvent *e ) -{ -#if 0 - const QValidator *v = validator(); - if ( v ) - { - int curpos = cursorPosition(); - QString str = text(); - if ( v->validate( str, curpos ) == QValidator::Acceptable ) - { - if ( curpos != cursorPosition() ) - setCursorPosition( curpos ); - if ( str != text() ) - setText( str ); - } - else - { - if ( curpos != cursorPosition() ) - setCursorPosition( curpos ); - str = text(); - v->fixup( str ); - if ( str != text() ) - { - setText( str ); - } - } - } - QLineEdit::focusOutEvent( e ); - emit focusOut(); -#else -#define uintToHexStr(num, bytesize) \ - QString("%1").arg((num), (bytesize)*2 , 16, QChar('0')) - - bool isOk; - ulong num; - - qDebug("before = %s\n", text().toAscii().data()); - num = text().remove(QChar(' ')).toULong(&isOk, 16); - setText(uintToHexStr(num, 4)); - qDebug("after = %s\n", text().toAscii().data()); -#undef uintToHexStr -#endif -} - -#if 0 -void HexLineEdit::focusInEvent( QFocusEvent *e ) -{ - QLineEdit::focusInEvent( e ); - emit focusIn(); -} - -void HexLineEdit::keyPressEvent( QKeyEvent *e ) -{ - QLineEdit::keyPressEvent( e ); - if ( e->key() == Key_Enter || e->key() == Key_Return ) - { - setSelection( 0, text().length() ); - } -} -#endif - +#include "hexlineedit.h" +#include "qdebug.h" + +QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets); + +HexLineEdit::HexLineEdit( QWidget * parent) + : QLineEdit(parent) +{ + //QLineEdit::QLineEdit(parent); +} + +void HexLineEdit::focusOutEvent( QFocusEvent *e ) +{ +#if 0 + const QValidator *v = validator(); + if ( v ) + { + int curpos = cursorPosition(); + QString str = text(); + if ( v->validate( str, curpos ) == QValidator::Acceptable ) + { + if ( curpos != cursorPosition() ) + setCursorPosition( curpos ); + if ( str != text() ) + setText( str ); + } + else + { + if ( curpos != cursorPosition() ) + setCursorPosition( curpos ); + str = text(); + v->fixup( str ); + if ( str != text() ) + { + setText( str ); + } + } + } + QLineEdit::focusOutEvent( e ); + emit focusOut(); +#else +#define uintToHexStr(num, bytesize) \ + QString("%1").arg((num), (bytesize)*2 , 16, QChar('0')) + + bool isOk; + ulong num; + + qDebug("before = %s\n", text().toAscii().data()); + num = text().remove(QChar(' ')).toULong(&isOk, 16); + setText(uintToHexStr(num, 4)); + qDebug("after = %s\n", text().toAscii().data()); +#undef uintToHexStr +#endif +} + +#if 0 +void HexLineEdit::focusInEvent( QFocusEvent *e ) +{ + QLineEdit::focusInEvent( e ); + emit focusIn(); +} + +void HexLineEdit::keyPressEvent( QKeyEvent *e ) +{ + QLineEdit::keyPressEvent( e ); + if ( e->key() == Key_Enter || e->key() == Key_Return ) + { + setSelection( 0, text().length() ); + } +} +#endif + diff --git a/client/hexlineedit.h b/client/hexlineedit.h index 937d263..09f638a 100644 --- a/client/hexlineedit.h +++ b/client/hexlineedit.h @@ -1,24 +1,24 @@ -#ifndef _HEXLINEEDIT -#define _HEXLINEEDIT - -#include - -class HexLineEdit : public QLineEdit -{ - Q_OBJECT -public: - // Constructors - HexLineEdit ( QWidget * parent); - -protected: - void focusOutEvent( QFocusEvent *e ); - //void focusInEvent( QFocusEvent *e ); - //void keyPressEvent( QKeyEvent *e ); - -signals: - //void focusIn(); - void focusOut(); -}; - -#endif - +#ifndef _HEXLINEEDIT +#define _HEXLINEEDIT + +#include + +class HexLineEdit : public QLineEdit +{ + Q_OBJECT +public: + // Constructors + HexLineEdit ( QWidget * parent); + +protected: + void focusOutEvent( QFocusEvent *e ); + //void focusInEvent( QFocusEvent *e ); + //void keyPressEvent( QKeyEvent *e ); + +signals: + //void focusIn(); + void focusOut(); +}; + +#endif + diff --git a/client/main.cpp b/client/main.cpp index 9a9a5d8..994952a 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -1,12 +1,12 @@ -#include "mainwindow.h" - -#include - -int main(int argc, char* argv[]) -{ - QApplication app(argc, argv); - MainWindow mainWin; - - mainWin.show(); - return app.exec(); -} +#include "mainwindow.h" + +#include + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + MainWindow mainWin; + + mainWin.show(); + return app.exec(); +} diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 2aee434..0f818c5 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -1,65 +1,65 @@ -#include "mainwindow.h" - -#if 0 -#include "dbgthread.h" -#endif - -#include "portgrouplist.h" -#include "portstatswindow.h" -#include "portswindow.h" -#include "ui_about.h" - -#include -#include - -PortGroupList *pgl; - -MainWindow::MainWindow(QWidget *parent) - : QMainWindow (parent) -{ - localServer_ = new QProcess(this); - localServer_->start("drone.exe"); - - pgl = new PortGroupList; - - portsWindow = new PortsWindow(pgl, this); - statsWindow = new PortStatsWindow(pgl, this); - portsDock = new QDockWidget(tr("Ports"), this); - statsDock = new QDockWidget(tr("Stats"), this); - - setupUi(this); - - statsDock->setWidget(statsWindow); - addDockWidget(Qt::BottomDockWidgetArea, statsDock); - portsDock->setWidget(portsWindow); - addDockWidget(Qt::TopDockWidgetArea, portsDock); - - connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close())); -#if 0 - { - DbgThread *dbg = new DbgThread(pgl); - dbg->start(); - } -#endif -} - -MainWindow::~MainWindow() -{ - delete pgl; - localServer_->terminate(); - localServer_->waitForFinished(); - delete localServer_; -} - -void MainWindow::on_actionHelpAbout_triggered() -{ - QDialog *aboutDialog = new QDialog; - - Ui::About about; - about.setupUi(aboutDialog); - - aboutDialog->exec(); - - delete aboutDialog; -} - +#include "mainwindow.h" + +#if 0 +#include "dbgthread.h" +#endif + +#include "portgrouplist.h" +#include "portstatswindow.h" +#include "portswindow.h" +#include "ui_about.h" + +#include +#include + +PortGroupList *pgl; + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow (parent) +{ + localServer_ = new QProcess(this); + localServer_->start("drone.exe"); + + pgl = new PortGroupList; + + portsWindow = new PortsWindow(pgl, this); + statsWindow = new PortStatsWindow(pgl, this); + portsDock = new QDockWidget(tr("Ports"), this); + statsDock = new QDockWidget(tr("Stats"), this); + + setupUi(this); + + statsDock->setWidget(statsWindow); + addDockWidget(Qt::BottomDockWidgetArea, statsDock); + portsDock->setWidget(portsWindow); + addDockWidget(Qt::TopDockWidgetArea, portsDock); + + connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close())); +#if 0 + { + DbgThread *dbg = new DbgThread(pgl); + dbg->start(); + } +#endif +} + +MainWindow::~MainWindow() +{ + delete pgl; + localServer_->terminate(); + localServer_->waitForFinished(); + delete localServer_; +} + +void MainWindow::on_actionHelpAbout_triggered() +{ + QDialog *aboutDialog = new QDialog; + + Ui::About about; + about.setupUi(aboutDialog); + + aboutDialog->exec(); + + delete aboutDialog; +} + diff --git a/client/mainwindow.h b/client/mainwindow.h index 53c8eac..9ddd926 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -1,33 +1,33 @@ -#ifndef _MAIN_WINDOW_H -#define _MAIN_WINDOW_H - -#include "ui_mainwindow.h" -#include - -class PortsWindow; -class PortStatsWindow; - -class QDockWidget; -class QProcess; - -class MainWindow : public QMainWindow, private Ui::MainWindow -{ - Q_OBJECT - -private: - QProcess *localServer_; - PortsWindow *portsWindow; - PortStatsWindow *statsWindow; - QDockWidget *portsDock; - QDockWidget *statsDock; - -public: - MainWindow(QWidget *parent = 0); - ~MainWindow(); - -public slots: - void on_actionHelpAbout_triggered(); -}; - -#endif - +#ifndef _MAIN_WINDOW_H +#define _MAIN_WINDOW_H + +#include "ui_mainwindow.h" +#include + +class PortsWindow; +class PortStatsWindow; + +class QDockWidget; +class QProcess; + +class MainWindow : public QMainWindow, private Ui::MainWindow +{ + Q_OBJECT + +private: + QProcess *localServer_; + PortsWindow *portsWindow; + PortStatsWindow *statsWindow; + QDockWidget *portsDock; + QDockWidget *statsDock; + +public: + MainWindow(QWidget *parent = 0); + ~MainWindow(); + +public slots: + void on_actionHelpAbout_triggered(); +}; + +#endif + diff --git a/client/ostinato.pro b/client/ostinato.pro index b0dd570..3afbdc2 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -1,57 +1,57 @@ -TEMPLATE = app -CONFIG += qt debug -QT += network script -INCLUDEPATH += "../rpc/" "../common/" -LIBS += -lprotobuf -win32:LIBS += -L"../common/debug" -lostproto -unix: LIBS += -L"../common" -lostproto -win32:LIBS += -L"../rpc/debug" -lpbrpc -unix:LIBS += -L"../rpc" -lpbrpc -POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" -RESOURCES += ostinato.qrc -HEADERS += \ - dumpview.h \ - hexlineedit.h \ - mainwindow.h \ - packetmodel.h \ - port.h \ - portgroup.h \ - portgrouplist.h \ - portmodel.h \ - portstatsmodel.h \ - portstatsfilterdialog.h \ - portstatswindow.h \ - portswindow.h \ - streamconfigdialog.h \ - streamlistdelegate.h \ - streammodel.h - -FORMS += \ - about.ui \ - mainwindow.ui \ - portstatsfilter.ui \ - portstatswindow.ui \ - portswindow.ui \ - streamconfigdialog.ui - -SOURCES += \ - dumpview.cpp \ - stream.cpp \ - hexlineedit.cpp \ - main.cpp \ - mainwindow.cpp \ - packetmodel.cpp \ - port.cpp \ - portgroup.cpp \ - portgrouplist.cpp \ - portmodel.cpp \ - portstatsmodel.cpp \ - portstatsfilterdialog.cpp \ - portstatswindow.cpp \ - portswindow.cpp \ - streamconfigdialog.cpp \ - streamlistdelegate.cpp \ - streammodel.cpp - -# TODO(LOW): Test only -include(modeltest.pri) +TEMPLATE = app +CONFIG += qt debug +QT += network script +INCLUDEPATH += "../rpc/" "../common/" +LIBS += -lprotobuf +win32:LIBS += -L"../common/debug" -lostproto +unix: LIBS += -L"../common" -lostproto +win32:LIBS += -L"../rpc/debug" -lpbrpc +unix:LIBS += -L"../rpc" -lpbrpc +POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" +RESOURCES += ostinato.qrc +HEADERS += \ + dumpview.h \ + hexlineedit.h \ + mainwindow.h \ + packetmodel.h \ + port.h \ + portgroup.h \ + portgrouplist.h \ + portmodel.h \ + portstatsmodel.h \ + portstatsfilterdialog.h \ + portstatswindow.h \ + portswindow.h \ + streamconfigdialog.h \ + streamlistdelegate.h \ + streammodel.h + +FORMS += \ + about.ui \ + mainwindow.ui \ + portstatsfilter.ui \ + portstatswindow.ui \ + portswindow.ui \ + streamconfigdialog.ui + +SOURCES += \ + dumpview.cpp \ + stream.cpp \ + hexlineedit.cpp \ + main.cpp \ + mainwindow.cpp \ + packetmodel.cpp \ + port.cpp \ + portgroup.cpp \ + portgrouplist.cpp \ + portmodel.cpp \ + portstatsmodel.cpp \ + portstatsfilterdialog.cpp \ + portstatswindow.cpp \ + portswindow.cpp \ + streamconfigdialog.cpp \ + streamlistdelegate.cpp \ + streammodel.cpp + +# TODO(LOW): Test only +include(modeltest.pri) diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index a3aee4d..df5a30b 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -1,220 +1,220 @@ -#include - -#include "packetmodel.h" -#include "../common/protocollistiterator.h" -#include "../common/abstractprotocol.h" - -PacketModel::PacketModel(QObject *parent) -{ -} - -void PacketModel::setSelectedProtocols(ProtocolListIterator &iter) -{ - QList currentProtocols; - - iter.toFront(); - while (iter.hasNext()) - currentProtocols.append(iter.next()); - - if (mSelectedProtocols != currentProtocols) - { - mSelectedProtocols = currentProtocols; - reset(); - } -} - -int PacketModel::rowCount(const QModelIndex &parent) const -{ - IndexId parentId; - - // qDebug("in %s", __FUNCTION__); - - // Parent == Invalid i.e. Invisible Root. - // ==> Children are Protocol (Top Level) Items - if (!parent.isValid()) - return mSelectedProtocols.size(); - - // Parent - Valid Item - parentId.w = parent.internalId(); - switch(parentId.ws.type) - { - case ITYP_PROTOCOL: - return mSelectedProtocols.at(parentId.ws.protocol)->frameFieldCount(); - case ITYP_FIELD: - return 0; - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } - - Q_ASSERT(1 == 0); // Unreachable code - qWarning("%s: Catch all - need to investigate", __FUNCTION__); - return 0; // catch all -} - -int PacketModel::columnCount(const QModelIndex &parent) const -{ - return 1; -} - -QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) const -{ - QModelIndex index; - IndexId id, parentId; - - if (!hasIndex(row, col, parent)) - goto _exit; - - // Parent is Invisible Root - // Request for a Protocol Item - if (!parent.isValid()) - { - id.w = 0; - id.ws.type = ITYP_PROTOCOL; - id.ws.protocol = row; - index = createIndex(row, col, id.w); - goto _exit; - } - - // Parent is a Valid Item - parentId.w = parent.internalId(); - id.w = parentId.w; - switch(parentId.ws.type) - { - case ITYP_PROTOCOL: - id.ws.type = ITYP_FIELD; - index = createIndex(row, col, id.w); - goto _exit; - - case ITYP_FIELD: - Q_ASSERT(1 == 0); // Unreachable code - goto _exit; - - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } - - Q_ASSERT(1 == 0); // Unreachable code - -_exit: - return index; -} - -QModelIndex PacketModel::parent(const QModelIndex &index) const -{ - QModelIndex parentIndex; - IndexId id, parentId; - - if (!index.isValid()) - return QModelIndex(); - - id.w = index.internalId(); - parentId.w = id.w; - switch(id.ws.type) - { - case ITYP_PROTOCOL: - // return invalid index for invisible root - goto _exit; - - case ITYP_FIELD: - parentId.ws.type = ITYP_PROTOCOL; - parentIndex = createIndex(id.ws.protocol, 0, parentId.w); - goto _exit; - - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } - - Q_ASSERT(1 == 1); // Unreachable code - -_exit: - return parentIndex; -} - -QVariant PacketModel::data(const QModelIndex &index, int role) const -{ - IndexId id; - int fieldIdx = 0; - - if (!index.isValid()) - return QVariant(); - - id.w = index.internalId(); - - if (id.ws.type == ITYP_FIELD) - { - const AbstractProtocol *p = mSelectedProtocols.at(id.ws.protocol); - int n = index.row() + 1; - - while (n) - { - if (!(p->fieldFlags(fieldIdx).testFlag( - AbstractProtocol::FieldIsMeta))) - n--; - fieldIdx++; - } - fieldIdx--; - } - - // FIXME(HI): Relook at this completely - if (role == Qt::UserRole) - { - switch(id.ws.type) - { - case ITYP_PROTOCOL: - qDebug("*** %d/%d", id.ws.protocol, mSelectedProtocols.size()); - return mSelectedProtocols.at(id.ws.protocol)-> - protocolFrameValue(); - - case ITYP_FIELD: - return mSelectedProtocols.at(id.ws.protocol)->fieldData( - fieldIdx, AbstractProtocol::FieldFrameValue); - - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } - return QByteArray(); - } - - // FIXME: Use a new enum here instead of UserRole - if (role == (Qt::UserRole+1)) - { - switch(id.ws.type) - { - case ITYP_PROTOCOL: - return mSelectedProtocols.at(id.ws.protocol)-> - protocolFrameValue().size(); - - case ITYP_FIELD: - return mSelectedProtocols.at(id.ws.protocol)->fieldData( - fieldIdx, AbstractProtocol::FieldBitSize); - - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } - return QVariant(); - } - - if (role != Qt::DisplayRole) - return QVariant(); - - switch(id.ws.type) - { - case ITYP_PROTOCOL: - return QString("%1 (%2)") - .arg(mSelectedProtocols.at(id.ws.protocol)->shortName()) - .arg(mSelectedProtocols.at(id.ws.protocol)->name()); - - case ITYP_FIELD: - return mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, - AbstractProtocol::FieldName).toString() + QString(" : ") + - mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, - AbstractProtocol::FieldTextValue).toString(); - - default: - qWarning("%s: Unhandled ItemType", __FUNCTION__); - } - - Q_ASSERT(1 == 1); // Unreachable code - - return QVariant(); -} +#include + +#include "packetmodel.h" +#include "../common/protocollistiterator.h" +#include "../common/abstractprotocol.h" + +PacketModel::PacketModel(QObject *parent) +{ +} + +void PacketModel::setSelectedProtocols(ProtocolListIterator &iter) +{ + QList currentProtocols; + + iter.toFront(); + while (iter.hasNext()) + currentProtocols.append(iter.next()); + + if (mSelectedProtocols != currentProtocols) + { + mSelectedProtocols = currentProtocols; + reset(); + } +} + +int PacketModel::rowCount(const QModelIndex &parent) const +{ + IndexId parentId; + + // qDebug("in %s", __FUNCTION__); + + // Parent == Invalid i.e. Invisible Root. + // ==> Children are Protocol (Top Level) Items + if (!parent.isValid()) + return mSelectedProtocols.size(); + + // Parent - Valid Item + parentId.w = parent.internalId(); + switch(parentId.ws.type) + { + case ITYP_PROTOCOL: + return mSelectedProtocols.at(parentId.ws.protocol)->frameFieldCount(); + case ITYP_FIELD: + return 0; + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + + Q_ASSERT(1 == 0); // Unreachable code + qWarning("%s: Catch all - need to investigate", __FUNCTION__); + return 0; // catch all +} + +int PacketModel::columnCount(const QModelIndex &parent) const +{ + return 1; +} + +QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) const +{ + QModelIndex index; + IndexId id, parentId; + + if (!hasIndex(row, col, parent)) + goto _exit; + + // Parent is Invisible Root + // Request for a Protocol Item + if (!parent.isValid()) + { + id.w = 0; + id.ws.type = ITYP_PROTOCOL; + id.ws.protocol = row; + index = createIndex(row, col, id.w); + goto _exit; + } + + // Parent is a Valid Item + parentId.w = parent.internalId(); + id.w = parentId.w; + switch(parentId.ws.type) + { + case ITYP_PROTOCOL: + id.ws.type = ITYP_FIELD; + index = createIndex(row, col, id.w); + goto _exit; + + case ITYP_FIELD: + Q_ASSERT(1 == 0); // Unreachable code + goto _exit; + + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + + Q_ASSERT(1 == 0); // Unreachable code + +_exit: + return index; +} + +QModelIndex PacketModel::parent(const QModelIndex &index) const +{ + QModelIndex parentIndex; + IndexId id, parentId; + + if (!index.isValid()) + return QModelIndex(); + + id.w = index.internalId(); + parentId.w = id.w; + switch(id.ws.type) + { + case ITYP_PROTOCOL: + // return invalid index for invisible root + goto _exit; + + case ITYP_FIELD: + parentId.ws.type = ITYP_PROTOCOL; + parentIndex = createIndex(id.ws.protocol, 0, parentId.w); + goto _exit; + + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + + Q_ASSERT(1 == 1); // Unreachable code + +_exit: + return parentIndex; +} + +QVariant PacketModel::data(const QModelIndex &index, int role) const +{ + IndexId id; + int fieldIdx = 0; + + if (!index.isValid()) + return QVariant(); + + id.w = index.internalId(); + + if (id.ws.type == ITYP_FIELD) + { + const AbstractProtocol *p = mSelectedProtocols.at(id.ws.protocol); + int n = index.row() + 1; + + while (n) + { + if (!(p->fieldFlags(fieldIdx).testFlag( + AbstractProtocol::FieldIsMeta))) + n--; + fieldIdx++; + } + fieldIdx--; + } + + // FIXME(HI): Relook at this completely + if (role == Qt::UserRole) + { + switch(id.ws.type) + { + case ITYP_PROTOCOL: + qDebug("*** %d/%d", id.ws.protocol, mSelectedProtocols.size()); + return mSelectedProtocols.at(id.ws.protocol)-> + protocolFrameValue(); + + case ITYP_FIELD: + return mSelectedProtocols.at(id.ws.protocol)->fieldData( + fieldIdx, AbstractProtocol::FieldFrameValue); + + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + return QByteArray(); + } + + // FIXME: Use a new enum here instead of UserRole + if (role == (Qt::UserRole+1)) + { + switch(id.ws.type) + { + case ITYP_PROTOCOL: + return mSelectedProtocols.at(id.ws.protocol)-> + protocolFrameValue().size(); + + case ITYP_FIELD: + return mSelectedProtocols.at(id.ws.protocol)->fieldData( + fieldIdx, AbstractProtocol::FieldBitSize); + + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + return QVariant(); + } + + if (role != Qt::DisplayRole) + return QVariant(); + + switch(id.ws.type) + { + case ITYP_PROTOCOL: + return QString("%1 (%2)") + .arg(mSelectedProtocols.at(id.ws.protocol)->shortName()) + .arg(mSelectedProtocols.at(id.ws.protocol)->name()); + + case ITYP_FIELD: + return mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, + AbstractProtocol::FieldName).toString() + QString(" : ") + + mSelectedProtocols.at(id.ws.protocol)->fieldData(fieldIdx, + AbstractProtocol::FieldTextValue).toString(); + + default: + qWarning("%s: Unhandled ItemType", __FUNCTION__); + } + + Q_ASSERT(1 == 1); // Unreachable code + + return QVariant(); +} diff --git a/client/packetmodel.h b/client/packetmodel.h index 2568724..cd81a8f 100644 --- a/client/packetmodel.h +++ b/client/packetmodel.h @@ -1,40 +1,40 @@ -#ifndef _PACKET_MODEL_H -#define _PACKET_MODEL_H - -#include - -class ProtocolListIterator; -class AbstractProtocol; - -class PacketModel: public QAbstractItemModel -{ - -public: - PacketModel(QObject *parent = 0); - void setSelectedProtocols(ProtocolListIterator &iter); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const { return QVariant(); } ; - QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; - QModelIndex parent(const QModelIndex &index) const; - -private: - typedef union _IndexId - { - quint32 w; - struct - { - quint16 type; -#define ITYP_PROTOCOL 1 -#define ITYP_FIELD 2 - quint16 protocol; // protocol is valid for both ITYPs - } ws; - } IndexId; - - QList mSelectedProtocols; -}; -#endif - +#ifndef _PACKET_MODEL_H +#define _PACKET_MODEL_H + +#include + +class ProtocolListIterator; +class AbstractProtocol; + +class PacketModel: public QAbstractItemModel +{ + +public: + PacketModel(QObject *parent = 0); + void setSelectedProtocols(ProtocolListIterator &iter); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const { return QVariant(); } ; + QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; + QModelIndex parent(const QModelIndex &index) const; + +private: + typedef union _IndexId + { + quint32 w; + struct + { + quint16 type; +#define ITYP_PROTOCOL 1 +#define ITYP_FIELD 2 + quint16 protocol; // protocol is valid for both ITYPs + } ws; + } IndexId; + + QList mSelectedProtocols; +}; +#endif + diff --git a/client/port.cpp b/client/port.cpp index 8f708f1..2509927 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -1,197 +1,197 @@ -#include - -#include - -#include "port.h" -#include "pbhelper.h" - -uint Port::mAllocStreamId = 0; - -uint Port::newStreamId() -{ - return mAllocStreamId++; -} - -Port::Port(quint32 id, quint32 portGroupId) -{ - mPortId = id; - d.mutable_port_id()->set_id(id); - stats.mutable_port_id()->set_id(id); - mPortGroupId = portGroupId; -} - -Port::~Port() -{ -} - -void Port::updatePortConfig(OstProto::Port *port) -{ - d.MergeFrom(*port); -} - -void Port::updateStreamOrdinalsFromIndex() -{ - for (int i=0; i < mStreams.size(); i++) - mStreams[i]->setOrdinal(i); -} - -void Port::reorderStreamsByOrdinals() -{ - qSort(mStreams); -} - -bool Port::newStreamAt(int index) -{ - Stream *s = new Stream; - - if (index > mStreams.size()) - return false; - - s->setId(newStreamId()); - mStreams.insert(index, s); - updateStreamOrdinalsFromIndex(); - - return true; -} - -bool Port::deleteStreamAt(int index) -{ - if (index >= mStreams.size()) - return false; - - delete mStreams.takeAt(index); - updateStreamOrdinalsFromIndex(); - - return true; -} - -bool Port::insertStream(uint streamId) -{ - Stream *s = new Stream; - - s->setId(streamId); - - // FIXME(MED): If a stream with id already exists, what do we do? - mStreams.append(s); - - // Update mAllocStreamId to take into account the stream id received - // from server - if (mAllocStreamId <= streamId) - mAllocStreamId = streamId + 1; - - return true; -} - -bool Port::updateStream(uint streamId, OstProto::Stream *stream) -{ - int i, streamIndex; - - for (i = 0; i < mStreams.size(); i++) - { - if (streamId == mStreams[i]->id()) - goto _found; - } - - qDebug("%s: Invalid stream id %d", __FUNCTION__, streamId); - return false; - -_found: - streamIndex = i; - - mStreams[streamIndex]->protoDataCopyFrom(*stream); - reorderStreamsByOrdinals(); - - return true; -} - -void Port::getDeletedStreamsSinceLastSync( - OstProto::StreamIdList &streamIdList) -{ - streamIdList.clear_stream_id(); - for (int i = 0; i < mLastSyncStreamList.size(); i++) - { - int j; - - for (j = 0; j < mStreams.size(); j++) - { - if (mLastSyncStreamList[i] == mStreams[j]->id()) - break; - } - - if (j < mStreams.size()) - { - // stream still exists! - continue; - } - else - { - // stream has been deleted since last sync - OstProto::StreamId *s; - - s = streamIdList.add_stream_id(); - s->set_id(mLastSyncStreamList.at(i)); - } - } -} - -void Port::getNewStreamsSinceLastSync( - OstProto::StreamIdList &streamIdList) -{ - streamIdList.clear_stream_id(); - for (int i = 0; i < mStreams.size(); i++) - { - if (mLastSyncStreamList.contains(mStreams[i]->id())) - { - // existing stream! - continue; - } - else - { - // new stream! - OstProto::StreamId *s; - - s = streamIdList.add_stream_id(); - s->set_id(mStreams[i]->id()); - } - } -} - -void Port::getModifiedStreamsSinceLastSync( - OstProto::StreamConfigList &streamConfigList) -{ - qDebug("In %s", __FUNCTION__); - - //streamConfigList.mutable_port_id()->set_id(mPortId); - for (int i = 0; i < mStreams.size(); i++) - { - OstProto::Stream *s; - - s = streamConfigList.add_stream(); - mStreams[i]->protoDataCopyInto(*s); - } - qDebug("Done %s", __FUNCTION__); -} - -void Port::when_syncComplete() -{ - qSort(mStreams); - - mLastSyncStreamList.clear(); - for (int i=0; iid()); -} - -void Port::updateStats(OstProto::PortStats *portStats) -{ - OstProto::PortState oldState; - - oldState = stats.state(); - stats.MergeFrom(*portStats); - - if (oldState.link_state() != stats.state().link_state()) - { - qDebug("portstate changed"); - emit portDataChanged(mPortGroupId, mPortId); - } -} - +#include + +#include + +#include "port.h" +#include "pbhelper.h" + +uint Port::mAllocStreamId = 0; + +uint Port::newStreamId() +{ + return mAllocStreamId++; +} + +Port::Port(quint32 id, quint32 portGroupId) +{ + mPortId = id; + d.mutable_port_id()->set_id(id); + stats.mutable_port_id()->set_id(id); + mPortGroupId = portGroupId; +} + +Port::~Port() +{ +} + +void Port::updatePortConfig(OstProto::Port *port) +{ + d.MergeFrom(*port); +} + +void Port::updateStreamOrdinalsFromIndex() +{ + for (int i=0; i < mStreams.size(); i++) + mStreams[i]->setOrdinal(i); +} + +void Port::reorderStreamsByOrdinals() +{ + qSort(mStreams); +} + +bool Port::newStreamAt(int index) +{ + Stream *s = new Stream; + + if (index > mStreams.size()) + return false; + + s->setId(newStreamId()); + mStreams.insert(index, s); + updateStreamOrdinalsFromIndex(); + + return true; +} + +bool Port::deleteStreamAt(int index) +{ + if (index >= mStreams.size()) + return false; + + delete mStreams.takeAt(index); + updateStreamOrdinalsFromIndex(); + + return true; +} + +bool Port::insertStream(uint streamId) +{ + Stream *s = new Stream; + + s->setId(streamId); + + // FIXME(MED): If a stream with id already exists, what do we do? + mStreams.append(s); + + // Update mAllocStreamId to take into account the stream id received + // from server + if (mAllocStreamId <= streamId) + mAllocStreamId = streamId + 1; + + return true; +} + +bool Port::updateStream(uint streamId, OstProto::Stream *stream) +{ + int i, streamIndex; + + for (i = 0; i < mStreams.size(); i++) + { + if (streamId == mStreams[i]->id()) + goto _found; + } + + qDebug("%s: Invalid stream id %d", __FUNCTION__, streamId); + return false; + +_found: + streamIndex = i; + + mStreams[streamIndex]->protoDataCopyFrom(*stream); + reorderStreamsByOrdinals(); + + return true; +} + +void Port::getDeletedStreamsSinceLastSync( + OstProto::StreamIdList &streamIdList) +{ + streamIdList.clear_stream_id(); + for (int i = 0; i < mLastSyncStreamList.size(); i++) + { + int j; + + for (j = 0; j < mStreams.size(); j++) + { + if (mLastSyncStreamList[i] == mStreams[j]->id()) + break; + } + + if (j < mStreams.size()) + { + // stream still exists! + continue; + } + else + { + // stream has been deleted since last sync + OstProto::StreamId *s; + + s = streamIdList.add_stream_id(); + s->set_id(mLastSyncStreamList.at(i)); + } + } +} + +void Port::getNewStreamsSinceLastSync( + OstProto::StreamIdList &streamIdList) +{ + streamIdList.clear_stream_id(); + for (int i = 0; i < mStreams.size(); i++) + { + if (mLastSyncStreamList.contains(mStreams[i]->id())) + { + // existing stream! + continue; + } + else + { + // new stream! + OstProto::StreamId *s; + + s = streamIdList.add_stream_id(); + s->set_id(mStreams[i]->id()); + } + } +} + +void Port::getModifiedStreamsSinceLastSync( + OstProto::StreamConfigList &streamConfigList) +{ + qDebug("In %s", __FUNCTION__); + + //streamConfigList.mutable_port_id()->set_id(mPortId); + for (int i = 0; i < mStreams.size(); i++) + { + OstProto::Stream *s; + + s = streamConfigList.add_stream(); + mStreams[i]->protoDataCopyInto(*s); + } + qDebug("Done %s", __FUNCTION__); +} + +void Port::when_syncComplete() +{ + qSort(mStreams); + + mLastSyncStreamList.clear(); + for (int i=0; iid()); +} + +void Port::updateStats(OstProto::PortStats *portStats) +{ + OstProto::PortState oldState; + + oldState = stats.state(); + stats.MergeFrom(*portStats); + + if (oldState.link_state() != stats.state().link_state()) + { + qDebug("portstate changed"); + emit portDataChanged(mPortGroupId, mPortId); + } +} + diff --git a/client/port.h b/client/port.h index 09e025a..53842a5 100644 --- a/client/port.h +++ b/client/port.h @@ -1,98 +1,98 @@ -#ifndef _PORT_H -#define _PORT_H - -#include -#include -#include -#include "stream.h" - -//class StreamModel; - -class Port : public QObject { - - Q_OBJECT - - static uint mAllocStreamId; - OstProto::Port d; - OstProto::PortStats stats; - - // FIXME(HI): consider removing mPortId as it is duplicated inside 'd' - quint32 mPortId; - quint32 mPortGroupId; - QString mUserAlias; // user defined - - QList mLastSyncStreamList; - QList mStreams; // sorted by stream's ordinal value - - uint newStreamId(); - void updateStreamOrdinalsFromIndex(); - void reorderStreamsByOrdinals(); - -public: - enum AdminStatus { AdminDisable, AdminEnable }; - enum ControlMode { ControlShared, ControlExclusive }; - - // FIXME(HIGH): default args is a hack for QList operations on Port - Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF); - ~Port(); - - quint32 portGroupId() const { return mPortGroupId; } - const QString& userAlias() const { return mUserAlias; } - - quint32 id() const - { return d.port_id().id(); } - const QString name() const - { return QString().fromStdString(d.name()); } - const QString description() const - { return QString().fromStdString(d.description()); } - AdminStatus adminStatus() - { return (d.is_enabled()?AdminEnable:AdminDisable); } - ControlMode controlMode() - { return (d.is_exclusive_control()?ControlExclusive:ControlShared); } - - //void setAdminEnable(AdminStatus status) { mAdminStatus = status; } - void setAlias(QString &alias) { mUserAlias = alias; } - //void setExclusive(bool flag); - - int numStreams() { return mStreams.size(); } - Stream* streamByIndex(int index) - { - Q_ASSERT(index < mStreams.size()); - return mStreams[index]; - } - OstProto::LinkState linkState() - { return stats.state().link_state(); } - - OstProto::PortStats getStats() { return stats; } - - // FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal - void updatePortConfig(OstProto::Port *port); - - //! Used by StreamModel - //@{ - bool newStreamAt(int index); - bool deleteStreamAt(int index); - //@} - - //! Used by MyService::Stub to update from config received from server - //@{ - bool insertStream(uint streamId); - bool updateStream(uint streamId, OstProto::Stream *stream); - //@} - - void getDeletedStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); - void getNewStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); - void getModifiedStreamsSinceLastSync( - OstProto::StreamConfigList &streamConfigList); - - - void when_syncComplete(); - - void updateStats(OstProto::PortStats *portStats); - -signals: - void portDataChanged(int portGroupId, int portId); - -}; - -#endif +#ifndef _PORT_H +#define _PORT_H + +#include +#include +#include +#include "stream.h" + +//class StreamModel; + +class Port : public QObject { + + Q_OBJECT + + static uint mAllocStreamId; + OstProto::Port d; + OstProto::PortStats stats; + + // FIXME(HI): consider removing mPortId as it is duplicated inside 'd' + quint32 mPortId; + quint32 mPortGroupId; + QString mUserAlias; // user defined + + QList mLastSyncStreamList; + QList mStreams; // sorted by stream's ordinal value + + uint newStreamId(); + void updateStreamOrdinalsFromIndex(); + void reorderStreamsByOrdinals(); + +public: + enum AdminStatus { AdminDisable, AdminEnable }; + enum ControlMode { ControlShared, ControlExclusive }; + + // FIXME(HIGH): default args is a hack for QList operations on Port + Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF); + ~Port(); + + quint32 portGroupId() const { return mPortGroupId; } + const QString& userAlias() const { return mUserAlias; } + + quint32 id() const + { return d.port_id().id(); } + const QString name() const + { return QString().fromStdString(d.name()); } + const QString description() const + { return QString().fromStdString(d.description()); } + AdminStatus adminStatus() + { return (d.is_enabled()?AdminEnable:AdminDisable); } + ControlMode controlMode() + { return (d.is_exclusive_control()?ControlExclusive:ControlShared); } + + //void setAdminEnable(AdminStatus status) { mAdminStatus = status; } + void setAlias(QString &alias) { mUserAlias = alias; } + //void setExclusive(bool flag); + + int numStreams() { return mStreams.size(); } + Stream* streamByIndex(int index) + { + Q_ASSERT(index < mStreams.size()); + return mStreams[index]; + } + OstProto::LinkState linkState() + { return stats.state().link_state(); } + + OstProto::PortStats getStats() { return stats; } + + // FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal + void updatePortConfig(OstProto::Port *port); + + //! Used by StreamModel + //@{ + bool newStreamAt(int index); + bool deleteStreamAt(int index); + //@} + + //! Used by MyService::Stub to update from config received from server + //@{ + bool insertStream(uint streamId); + bool updateStream(uint streamId, OstProto::Stream *stream); + //@} + + void getDeletedStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); + void getNewStreamsSinceLastSync(OstProto::StreamIdList &streamIdList); + void getModifiedStreamsSinceLastSync( + OstProto::StreamConfigList &streamConfigList); + + + void when_syncComplete(); + + void updateStats(OstProto::PortStats *portStats); + +signals: + void portDataChanged(int portGroupId, int portId); + +}; + +#endif diff --git a/client/portgroup.cpp b/client/portgroup.cpp index e26d2a1..4ec94c3 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -1,718 +1,718 @@ -#include -#include - -#include "portgroup.h" - - -quint32 PortGroup::mPortGroupAllocId = 0; - -PortGroup::PortGroup(QHostAddress ip, quint16 port) -{ - // Allocate an id for self - mPortGroupId = PortGroup::mPortGroupAllocId++; - - rpcChannel = new PbRpcChannel(ip, port); - - /*! - \todo (HIGH) RPC Controller should be allocated and deleted for each RPC invocation - as implemented currently, if a RPC is invoked before the previous completes, - rpc controller is overwritten due to the Reset() call - maybe we need to pass the - pointer to the controller to the callback function also? - */ - rpcController = new PbRpcController; - rpcControllerStats = new PbRpcController; - isGetStatsPending_ = false; - serviceStub = new OstProto::OstService::Stub(rpcChannel, - OstProto::OstService::STUB_OWNS_CHANNEL); - - // FIXME(LOW):Can't for my life figure out why this ain't working! - //QMetaObject::connectSlotsByName(this); - connect(rpcChannel, SIGNAL(stateChanged(QAbstractSocket::SocketState)), - this, SLOT(on_rpcChannel_stateChanged())); - connect(rpcChannel, SIGNAL(connected()), - this, SLOT(on_rpcChannel_connected())); - connect(rpcChannel, SIGNAL(disconnected()), - this, SLOT(on_rpcChannel_disconnected())); - connect(rpcChannel, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(on_rpcChannel_error(QAbstractSocket::SocketError))); -} - -PortGroup::~PortGroup() -{ - qDebug("PortGroup Destructor"); - // Disconnect and free rpc channel etc. - PortGroup::disconnectFromHost(); - delete serviceStub; -} - - -// ------------------------------------------------ -// Slots -// ------------------------------------------------ -void PortGroup::on_rpcChannel_stateChanged() -{ - qDebug("state changed"); - emit portGroupDataChanged(mPortGroupId); -} - -void PortGroup::on_rpcChannel_connected() -{ - OstProto::Void void_; - OstProto::PortIdList *portIdList; - - qDebug("connected\n"); - emit portGroupDataChanged(mPortGroupId); - - qDebug("requesting portlist ..."); - portIdList = new OstProto::PortIdList(); - rpcController->Reset(); - serviceStub->getPortIdList(rpcController, &void_, portIdList, - NewCallback(this, &PortGroup::processPortIdList, portIdList)); -} - -void PortGroup::on_rpcChannel_disconnected() -{ - qDebug("disconnected\n"); - emit portListAboutToBeChanged(mPortGroupId); - - while (!mPorts.isEmpty()) - delete mPorts.takeFirst(); - - emit portListChanged(mPortGroupId); - emit portGroupDataChanged(mPortGroupId); -} - -void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) -{ - qDebug("error\n"); - emit portGroupDataChanged(mPortGroupId); -} - -void PortGroup::when_configApply(int portIndex, uint *cookie) -{ - uint *op; - OstProto::Ack *ack; - - Q_ASSERT(portIndex < mPorts.size()); - - if (state() != QAbstractSocket::ConnectedState) - { - if (cookie != NULL) - delete cookie; - return; - } - - if (cookie == NULL) - { - // cookie[0]: op [0 - delete, 1 - add, 2 - modify, 3 - Done!] - // cookie[1]: *ack - cookie = new uint[2]; - ack = new OstProto::Ack; - - cookie[0] = (uint) 0; - cookie[1] = (uint) ack; - } - else - { - ack = (OstProto::Ack*) cookie[1]; - } - - Q_ASSERT(cookie != NULL); - op = &cookie[0]; - - switch (*op) - { - case 0: - { - OstProto::StreamIdList streamIdList; - - qDebug("applying 'deleted streams' ..."); - - streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - mPorts[portIndex]->getDeletedStreamsSinceLastSync(streamIdList); - - (*op)++; - rpcController->Reset(); - serviceStub->deleteStream(rpcController, &streamIdList, ack, - ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); - break; - } - - case 1: - { - OstProto::StreamIdList streamIdList; - - qDebug("applying 'new streams' ..."); - - streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - mPorts[portIndex]->getNewStreamsSinceLastSync(streamIdList); - - (*op)++; - rpcController->Reset(); - serviceStub->addStream(rpcController, &streamIdList, ack, - ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); - break; - } - - case 2: - { - OstProto::StreamConfigList streamConfigList; - - qDebug("applying 'modified streams' ..."); - - streamConfigList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - mPorts[portIndex]->getModifiedStreamsSinceLastSync(streamConfigList); - - (*op)++; - rpcController->Reset(); - serviceStub->modifyStream(rpcController, &streamConfigList, ack, - ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); - break; - } - - case 3: - qDebug("apply completed"); - mPorts[portIndex]->when_syncComplete(); - delete cookie; - break; - - default: - qDebug("%s: Unknown Op!!!", __FUNCTION__); - break; - } -} - -void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) -{ - qDebug("got a portlist ..."); - - if (rpcController->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _error_exit; - } - - emit portListAboutToBeChanged(mPortGroupId); - - for(int i = 0; i < portIdList->port_id_size(); i++) - { - Port *p; - - p = new Port(portIdList->port_id(i).id(), mPortGroupId); - connect(p, SIGNAL(portDataChanged(int, int)), - this, SIGNAL(portGroupDataChanged(int, int))); - qDebug("before port append\n"); - mPorts.append(p); - } - - emit portListChanged(mPortGroupId); - - this->portIdList.CopyFrom(*portIdList); - - // Request PortConfigList - { - OstProto::PortConfigList *portConfigList; - - qDebug("requesting port config list ..."); - portConfigList = new OstProto::PortConfigList(); - rpcController->Reset(); - serviceStub->getPortConfig(rpcController, - portIdList, portConfigList, NewCallback(this, - &PortGroup::processPortConfigList, portConfigList)); - } - - goto _exit; - -_error_exit: -_exit: - delete portIdList; -} - -void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) -{ - qDebug("In %s", __FUNCTION__); - - if (rpcController->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _error_exit; - } - - emit portListAboutToBeChanged(mPortGroupId); - - for(int i = 0; i < portConfigList->port_size(); i++) - { - uint id; - - id = portConfigList->port(i).port_id().id(); - // FIXME: don't mix port id & index into mPorts[] - mPorts[id]->updatePortConfig(portConfigList->mutable_port(i)); - } - - emit portListChanged(mPortGroupId); - - // FIXME: check if we need new signals since we are not changing the - // number of ports, just the port data - - if (numPorts() > 0) - getStreamIdList(); - -_error_exit: - delete portConfigList; -} - -void PortGroup::getStreamIdList(int portIndex, - OstProto::StreamIdList *streamIdList) -{ - ::OstProto::PortId portId; - - qDebug("In %s", __FUNCTION__); - - if (streamIdList == NULL) - { - // First invocation (uses default params) - - // request StreamIdList for first port - - Q_ASSERT(portIndex == 0); - Q_ASSERT(numPorts() > 0); - streamIdList = new ::OstProto::StreamIdList(); - - goto _request; - } - - qDebug("got a streamIdlist ..."); - - if (rpcController->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _next_port; // FIXME(MED): Partial RPC - } - - Q_ASSERT(portIndex < numPorts()); - - if (streamIdList->port_id().id() != mPorts[portIndex]->id()) - { - qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", - __FUNCTION__, streamIdList->port_id().id(), mPorts[portIndex]->id(), - portIndex); - goto _next_port; // FIXME(MED): Partial RPC - } - - // FIXME(MED): need to mPorts.clear()??? - for(int i = 0; i < streamIdList->stream_id_size(); i++) - { - uint streamId; - - streamId = streamIdList->stream_id(i).id(); - mPorts[portIndex]->insertStream(streamId); - } - -_next_port: - // FIXME(HI): ideally we shd use signals/slots but this means - // we will have to use Port* instead of Port with QList<> - - // need to find a way for this - mPorts[portIndex]->when_syncComplete(); - portIndex++; - if (portIndex >= numPorts()) - { - // We're done for all ports !!! - - // FIXME(HI): some way to reset streammodel - - delete streamIdList; - - if (numPorts() > 0) - getStreamConfigList(); - - goto _exit; - } - -_request: - portId.set_id(mPorts[portIndex]->id()); - streamIdList->Clear(); - - rpcController->Reset(); - serviceStub->getStreamIdList(rpcController, &portId, streamIdList, - NewCallback(this, &PortGroup::getStreamIdList, - portIndex, streamIdList)); - - goto _exit; - - - -_exit: - return; -} - -void PortGroup::getStreamConfigList(int portIndex, - OstProto::StreamConfigList *streamConfigList) -{ - OstProto::StreamIdList streamIdList; - - qDebug("In %s", __PRETTY_FUNCTION__); - - if (streamConfigList == NULL) - { - // First invocation using default params - // - request for first port - - Q_ASSERT(portIndex == 0); - Q_ASSERT(numPorts() > 0); - - streamConfigList = new OstProto::StreamConfigList; - - goto _request; - } - - qDebug("got a streamconfiglist"); - - if (rpcController->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _next_port; - } - - Q_ASSERT(portIndex < numPorts()); - - if (streamConfigList->port_id().id() != mPorts[portIndex]->id()) - { - qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", - __FUNCTION__, streamConfigList->port_id().id(), - mPorts[portIndex]->id(), portIndex); - goto _next_port; // FIXME(MED): Partial RPC - } - - // FIXME(MED): need to mStreams.clear()??? - for(int i = 0; i < streamConfigList->stream_size(); i++) - { - uint streamId; - - streamId = streamConfigList->stream(i).stream_id().id(); - mPorts[portIndex]->updateStream(streamId, - streamConfigList->mutable_stream(i)); - } - -_next_port: - portIndex++; - - if (portIndex >= numPorts()) - { - // We're done for all ports !!! - - // FIXME(HI): some way to reset streammodel - - delete streamConfigList; - goto _exit; - } - -_request: - qDebug("requesting stream config list ..."); - - streamIdList.Clear(); - streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - for (int j = 0; j < mPorts[portIndex]->numStreams(); j++) - { - OstProto::StreamId *s; - - s = streamIdList.add_stream_id(); - s->set_id(mPorts[portIndex]->streamByIndex(j)->id()); - } - streamConfigList->Clear(); - - rpcController->Reset(); - serviceStub->getStreamConfig(rpcController, - &streamIdList, streamConfigList, NewCallback(this, - &PortGroup::getStreamConfigList, portIndex, streamConfigList)); - -_exit: - return; -} - -void PortGroup::processModifyStreamAck(OstProto::Ack *ack) -{ - qDebug("In %s", __FUNCTION__); - - qDebug("Modify Successful!!"); - - // TODO(HI): Apply Button should now be disabled???!!!!??? -} - -void PortGroup::startTx(QList *portList) -{ - OstProto::PortIdList portIdList; - OstProto::Ack *ack; - - qDebug("In %s", __FUNCTION__); - - if (state() != QAbstractSocket::ConnectedState) - return; - - ack = new OstProto::Ack; - if (portList == NULL) - goto _exit; - else - { - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } - } - - serviceStub->startTx(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStartTxAck, ack)); -_exit: - return; -} - -void PortGroup::stopTx(QList *portList) -{ - OstProto::PortIdList portIdList; - OstProto::Ack *ack; - - qDebug("In %s", __FUNCTION__); - - if (state() != QAbstractSocket::ConnectedState) - goto _exit; - - if ((portList == NULL) || (portList->size() == 0)) - goto _exit; - - ack = new OstProto::Ack; - - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } - - rpcController->Reset(); - serviceStub->stopTx(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStopTxAck, ack)); -_exit: - return; -} - -void PortGroup::startCapture(QList *portList) -{ - OstProto::PortIdList portIdList; - OstProto::Ack *ack; - - qDebug("In %s", __FUNCTION__); - - if (state() != QAbstractSocket::ConnectedState) - return; - - if ((portList == NULL) || (portList->size() == 0)) - goto _exit; - - ack = new OstProto::Ack; - - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } - - rpcController->Reset(); - serviceStub->startCapture(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStartCaptureAck, ack)); -_exit: - return; -} - -void PortGroup::stopCapture(QList *portList) -{ - OstProto::PortIdList portIdList; - OstProto::Ack *ack; - - qDebug("In %s", __FUNCTION__); - - if (state() != QAbstractSocket::ConnectedState) - return; - - if ((portList == NULL) || (portList->size() == 0)) - goto _exit; - - ack = new OstProto::Ack; - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } - - rpcController->Reset(); - serviceStub->stopCapture(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStopCaptureAck, ack)); -_exit: - return; -} - -void PortGroup::viewCapture(QList *portList) -{ - static QTemporaryFile *capFile = NULL; - - qDebug("In %s", __FUNCTION__); - - if (state() != QAbstractSocket::ConnectedState) - goto _exit; - - if ((portList == NULL) || (portList->size() != 1)) - goto _exit; - - if (capFile) - delete capFile; - - /*! \todo (MED) unable to reuse the same file 'coz capFile->resize(0) is - not working - it fails everytime */ - capFile = new QTemporaryFile(); - capFile->open(); - qDebug("Temp CapFile = %s", capFile->fileName().toAscii().constData()); - - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId portId; - OstProto::CaptureBuffer *buf; - - portId.set_id(portList->at(i)); - - buf = new OstProto::CaptureBuffer; - rpcController->Reset(); - rpcController->setBinaryBlob(capFile); - serviceStub->getCaptureBuffer(rpcController, &portId, buf, - NewCallback(this, &PortGroup::processViewCaptureAck, buf, (QFile*) capFile)); - } -_exit: - return; -} - -void PortGroup::processStartTxAck(OstProto::Ack *ack) -{ - qDebug("In %s", __FUNCTION__); - - delete ack; -} - -void PortGroup::processStopTxAck(OstProto::Ack *ack) -{ - qDebug("In %s", __FUNCTION__); - - delete ack; -} - -void PortGroup::processStartCaptureAck(OstProto::Ack *ack) -{ - qDebug("In %s", __FUNCTION__); - - delete ack; -} - -void PortGroup::processStopCaptureAck(OstProto::Ack *ack) -{ - qDebug("In %s", __FUNCTION__); - - delete ack; -} - -void PortGroup::processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile) -{ - qDebug("In %s", __FUNCTION__); - - capFile->flush(); - capFile->close(); - - if (!QProcess::startDetached("C:/Program Files/Wireshark/wireshark.exe", - QStringList() << capFile->fileName())) - qDebug("Failed starting Wireshark"); - - delete buf; -} - -void PortGroup::getPortStats() -{ - OstProto::PortStatsList *portStatsList; - - //qDebug("In %s", __FUNCTION__); - - if (state() != QAbstractSocket::ConnectedState) - return; - - if (isGetStatsPending_) - return; - - portStatsList = new OstProto::PortStatsList; - rpcControllerStats->Reset(); - isGetStatsPending_ = true; - serviceStub->getStats(rpcControllerStats, &portIdList, portStatsList, - NewCallback(this, &PortGroup::processPortStatsList, portStatsList)); -} - -void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList) -{ - //qDebug("In %s", __FUNCTION__); - - if (rpcControllerStats->Failed()) - { - qDebug("%s: rpc failed", __FUNCTION__); - goto _error_exit; - } - - for(int i = 0; i < portStatsList->port_stats_size(); i++) - { - uint id; - - id = portStatsList->port_stats(i).port_id().id(); - // FIXME: don't mix port id & index into mPorts[] - mPorts[id]->updateStats(portStatsList->mutable_port_stats(i)); - } - - emit statsChanged(mPortGroupId); - -_error_exit: - delete portStatsList; - isGetStatsPending_ = false; -} - -void PortGroup::clearPortStats(QList *portList) -{ - OstProto::PortIdList portIdList; - OstProto::Ack *ack; - - qDebug("In %s", __FUNCTION__); - - if (state() != QAbstractSocket::ConnectedState) - return; - - ack = new OstProto::Ack; - if (portList == NULL) - portIdList.CopyFrom(this->portIdList); - else - { - for (int i = 0; i < portList->size(); i++) - { - OstProto::PortId *portId; - - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } - } - - rpcController->Reset(); - serviceStub->clearStats(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processClearStatsAck, ack)); -} - -void PortGroup::processClearStatsAck(OstProto::Ack *ack) -{ - qDebug("In %s", __FUNCTION__); - - // Refresh stats immediately after a stats clear/reset - getPortStats(); - - delete ack; -} - +#include +#include + +#include "portgroup.h" + + +quint32 PortGroup::mPortGroupAllocId = 0; + +PortGroup::PortGroup(QHostAddress ip, quint16 port) +{ + // Allocate an id for self + mPortGroupId = PortGroup::mPortGroupAllocId++; + + rpcChannel = new PbRpcChannel(ip, port); + + /*! + \todo (HIGH) RPC Controller should be allocated and deleted for each RPC invocation + as implemented currently, if a RPC is invoked before the previous completes, + rpc controller is overwritten due to the Reset() call - maybe we need to pass the + pointer to the controller to the callback function also? + */ + rpcController = new PbRpcController; + rpcControllerStats = new PbRpcController; + isGetStatsPending_ = false; + serviceStub = new OstProto::OstService::Stub(rpcChannel, + OstProto::OstService::STUB_OWNS_CHANNEL); + + // FIXME(LOW):Can't for my life figure out why this ain't working! + //QMetaObject::connectSlotsByName(this); + connect(rpcChannel, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(on_rpcChannel_stateChanged())); + connect(rpcChannel, SIGNAL(connected()), + this, SLOT(on_rpcChannel_connected())); + connect(rpcChannel, SIGNAL(disconnected()), + this, SLOT(on_rpcChannel_disconnected())); + connect(rpcChannel, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_rpcChannel_error(QAbstractSocket::SocketError))); +} + +PortGroup::~PortGroup() +{ + qDebug("PortGroup Destructor"); + // Disconnect and free rpc channel etc. + PortGroup::disconnectFromHost(); + delete serviceStub; +} + + +// ------------------------------------------------ +// Slots +// ------------------------------------------------ +void PortGroup::on_rpcChannel_stateChanged() +{ + qDebug("state changed"); + emit portGroupDataChanged(mPortGroupId); +} + +void PortGroup::on_rpcChannel_connected() +{ + OstProto::Void void_; + OstProto::PortIdList *portIdList; + + qDebug("connected\n"); + emit portGroupDataChanged(mPortGroupId); + + qDebug("requesting portlist ..."); + portIdList = new OstProto::PortIdList(); + rpcController->Reset(); + serviceStub->getPortIdList(rpcController, &void_, portIdList, + NewCallback(this, &PortGroup::processPortIdList, portIdList)); +} + +void PortGroup::on_rpcChannel_disconnected() +{ + qDebug("disconnected\n"); + emit portListAboutToBeChanged(mPortGroupId); + + while (!mPorts.isEmpty()) + delete mPorts.takeFirst(); + + emit portListChanged(mPortGroupId); + emit portGroupDataChanged(mPortGroupId); +} + +void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) +{ + qDebug("error\n"); + emit portGroupDataChanged(mPortGroupId); +} + +void PortGroup::when_configApply(int portIndex, uint *cookie) +{ + uint *op; + OstProto::Ack *ack; + + Q_ASSERT(portIndex < mPorts.size()); + + if (state() != QAbstractSocket::ConnectedState) + { + if (cookie != NULL) + delete cookie; + return; + } + + if (cookie == NULL) + { + // cookie[0]: op [0 - delete, 1 - add, 2 - modify, 3 - Done!] + // cookie[1]: *ack + cookie = new uint[2]; + ack = new OstProto::Ack; + + cookie[0] = (uint) 0; + cookie[1] = (uint) ack; + } + else + { + ack = (OstProto::Ack*) cookie[1]; + } + + Q_ASSERT(cookie != NULL); + op = &cookie[0]; + + switch (*op) + { + case 0: + { + OstProto::StreamIdList streamIdList; + + qDebug("applying 'deleted streams' ..."); + + streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getDeletedStreamsSinceLastSync(streamIdList); + + (*op)++; + rpcController->Reset(); + serviceStub->deleteStream(rpcController, &streamIdList, ack, + ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); + break; + } + + case 1: + { + OstProto::StreamIdList streamIdList; + + qDebug("applying 'new streams' ..."); + + streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getNewStreamsSinceLastSync(streamIdList); + + (*op)++; + rpcController->Reset(); + serviceStub->addStream(rpcController, &streamIdList, ack, + ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); + break; + } + + case 2: + { + OstProto::StreamConfigList streamConfigList; + + qDebug("applying 'modified streams' ..."); + + streamConfigList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getModifiedStreamsSinceLastSync(streamConfigList); + + (*op)++; + rpcController->Reset(); + serviceStub->modifyStream(rpcController, &streamConfigList, ack, + ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); + break; + } + + case 3: + qDebug("apply completed"); + mPorts[portIndex]->when_syncComplete(); + delete cookie; + break; + + default: + qDebug("%s: Unknown Op!!!", __FUNCTION__); + break; + } +} + +void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) +{ + qDebug("got a portlist ..."); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } + + emit portListAboutToBeChanged(mPortGroupId); + + for(int i = 0; i < portIdList->port_id_size(); i++) + { + Port *p; + + p = new Port(portIdList->port_id(i).id(), mPortGroupId); + connect(p, SIGNAL(portDataChanged(int, int)), + this, SIGNAL(portGroupDataChanged(int, int))); + qDebug("before port append\n"); + mPorts.append(p); + } + + emit portListChanged(mPortGroupId); + + this->portIdList.CopyFrom(*portIdList); + + // Request PortConfigList + { + OstProto::PortConfigList *portConfigList; + + qDebug("requesting port config list ..."); + portConfigList = new OstProto::PortConfigList(); + rpcController->Reset(); + serviceStub->getPortConfig(rpcController, + portIdList, portConfigList, NewCallback(this, + &PortGroup::processPortConfigList, portConfigList)); + } + + goto _exit; + +_error_exit: +_exit: + delete portIdList; +} + +void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) +{ + qDebug("In %s", __FUNCTION__); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } + + emit portListAboutToBeChanged(mPortGroupId); + + for(int i = 0; i < portConfigList->port_size(); i++) + { + uint id; + + id = portConfigList->port(i).port_id().id(); + // FIXME: don't mix port id & index into mPorts[] + mPorts[id]->updatePortConfig(portConfigList->mutable_port(i)); + } + + emit portListChanged(mPortGroupId); + + // FIXME: check if we need new signals since we are not changing the + // number of ports, just the port data + + if (numPorts() > 0) + getStreamIdList(); + +_error_exit: + delete portConfigList; +} + +void PortGroup::getStreamIdList(int portIndex, + OstProto::StreamIdList *streamIdList) +{ + ::OstProto::PortId portId; + + qDebug("In %s", __FUNCTION__); + + if (streamIdList == NULL) + { + // First invocation (uses default params) - + // request StreamIdList for first port + + Q_ASSERT(portIndex == 0); + Q_ASSERT(numPorts() > 0); + streamIdList = new ::OstProto::StreamIdList(); + + goto _request; + } + + qDebug("got a streamIdlist ..."); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _next_port; // FIXME(MED): Partial RPC + } + + Q_ASSERT(portIndex < numPorts()); + + if (streamIdList->port_id().id() != mPorts[portIndex]->id()) + { + qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", + __FUNCTION__, streamIdList->port_id().id(), mPorts[portIndex]->id(), + portIndex); + goto _next_port; // FIXME(MED): Partial RPC + } + + // FIXME(MED): need to mPorts.clear()??? + for(int i = 0; i < streamIdList->stream_id_size(); i++) + { + uint streamId; + + streamId = streamIdList->stream_id(i).id(); + mPorts[portIndex]->insertStream(streamId); + } + +_next_port: + // FIXME(HI): ideally we shd use signals/slots but this means + // we will have to use Port* instead of Port with QList<> - + // need to find a way for this + mPorts[portIndex]->when_syncComplete(); + portIndex++; + if (portIndex >= numPorts()) + { + // We're done for all ports !!! + + // FIXME(HI): some way to reset streammodel + + delete streamIdList; + + if (numPorts() > 0) + getStreamConfigList(); + + goto _exit; + } + +_request: + portId.set_id(mPorts[portIndex]->id()); + streamIdList->Clear(); + + rpcController->Reset(); + serviceStub->getStreamIdList(rpcController, &portId, streamIdList, + NewCallback(this, &PortGroup::getStreamIdList, + portIndex, streamIdList)); + + goto _exit; + + + +_exit: + return; +} + +void PortGroup::getStreamConfigList(int portIndex, + OstProto::StreamConfigList *streamConfigList) +{ + OstProto::StreamIdList streamIdList; + + qDebug("In %s", __PRETTY_FUNCTION__); + + if (streamConfigList == NULL) + { + // First invocation using default params + // - request for first port + + Q_ASSERT(portIndex == 0); + Q_ASSERT(numPorts() > 0); + + streamConfigList = new OstProto::StreamConfigList; + + goto _request; + } + + qDebug("got a streamconfiglist"); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _next_port; + } + + Q_ASSERT(portIndex < numPorts()); + + if (streamConfigList->port_id().id() != mPorts[portIndex]->id()) + { + qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", + __FUNCTION__, streamConfigList->port_id().id(), + mPorts[portIndex]->id(), portIndex); + goto _next_port; // FIXME(MED): Partial RPC + } + + // FIXME(MED): need to mStreams.clear()??? + for(int i = 0; i < streamConfigList->stream_size(); i++) + { + uint streamId; + + streamId = streamConfigList->stream(i).stream_id().id(); + mPorts[portIndex]->updateStream(streamId, + streamConfigList->mutable_stream(i)); + } + +_next_port: + portIndex++; + + if (portIndex >= numPorts()) + { + // We're done for all ports !!! + + // FIXME(HI): some way to reset streammodel + + delete streamConfigList; + goto _exit; + } + +_request: + qDebug("requesting stream config list ..."); + + streamIdList.Clear(); + streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); + for (int j = 0; j < mPorts[portIndex]->numStreams(); j++) + { + OstProto::StreamId *s; + + s = streamIdList.add_stream_id(); + s->set_id(mPorts[portIndex]->streamByIndex(j)->id()); + } + streamConfigList->Clear(); + + rpcController->Reset(); + serviceStub->getStreamConfig(rpcController, + &streamIdList, streamConfigList, NewCallback(this, + &PortGroup::getStreamConfigList, portIndex, streamConfigList)); + +_exit: + return; +} + +void PortGroup::processModifyStreamAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + qDebug("Modify Successful!!"); + + // TODO(HI): Apply Button should now be disabled???!!!!??? +} + +void PortGroup::startTx(QList *portList) +{ + OstProto::PortIdList portIdList; + OstProto::Ack *ack; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + ack = new OstProto::Ack; + if (portList == NULL) + goto _exit; + else + { + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + } + + serviceStub->startTx(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStartTxAck, ack)); +_exit: + return; +} + +void PortGroup::stopTx(QList *portList) +{ + OstProto::PortIdList portIdList; + OstProto::Ack *ack; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + goto _exit; + + if ((portList == NULL) || (portList->size() == 0)) + goto _exit; + + ack = new OstProto::Ack; + + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + + rpcController->Reset(); + serviceStub->stopTx(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStopTxAck, ack)); +_exit: + return; +} + +void PortGroup::startCapture(QList *portList) +{ + OstProto::PortIdList portIdList; + OstProto::Ack *ack; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + if ((portList == NULL) || (portList->size() == 0)) + goto _exit; + + ack = new OstProto::Ack; + + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + + rpcController->Reset(); + serviceStub->startCapture(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStartCaptureAck, ack)); +_exit: + return; +} + +void PortGroup::stopCapture(QList *portList) +{ + OstProto::PortIdList portIdList; + OstProto::Ack *ack; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + if ((portList == NULL) || (portList->size() == 0)) + goto _exit; + + ack = new OstProto::Ack; + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + + rpcController->Reset(); + serviceStub->stopCapture(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processStopCaptureAck, ack)); +_exit: + return; +} + +void PortGroup::viewCapture(QList *portList) +{ + static QTemporaryFile *capFile = NULL; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + goto _exit; + + if ((portList == NULL) || (portList->size() != 1)) + goto _exit; + + if (capFile) + delete capFile; + + /*! \todo (MED) unable to reuse the same file 'coz capFile->resize(0) is + not working - it fails everytime */ + capFile = new QTemporaryFile(); + capFile->open(); + qDebug("Temp CapFile = %s", capFile->fileName().toAscii().constData()); + + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId portId; + OstProto::CaptureBuffer *buf; + + portId.set_id(portList->at(i)); + + buf = new OstProto::CaptureBuffer; + rpcController->Reset(); + rpcController->setBinaryBlob(capFile); + serviceStub->getCaptureBuffer(rpcController, &portId, buf, + NewCallback(this, &PortGroup::processViewCaptureAck, buf, (QFile*) capFile)); + } +_exit: + return; +} + +void PortGroup::processStartTxAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + delete ack; +} + +void PortGroup::processStopTxAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + delete ack; +} + +void PortGroup::processStartCaptureAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + delete ack; +} + +void PortGroup::processStopCaptureAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + delete ack; +} + +void PortGroup::processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile) +{ + qDebug("In %s", __FUNCTION__); + + capFile->flush(); + capFile->close(); + + if (!QProcess::startDetached("C:/Program Files/Wireshark/wireshark.exe", + QStringList() << capFile->fileName())) + qDebug("Failed starting Wireshark"); + + delete buf; +} + +void PortGroup::getPortStats() +{ + OstProto::PortStatsList *portStatsList; + + //qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + if (isGetStatsPending_) + return; + + portStatsList = new OstProto::PortStatsList; + rpcControllerStats->Reset(); + isGetStatsPending_ = true; + serviceStub->getStats(rpcControllerStats, &portIdList, portStatsList, + NewCallback(this, &PortGroup::processPortStatsList, portStatsList)); +} + +void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList) +{ + //qDebug("In %s", __FUNCTION__); + + if (rpcControllerStats->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } + + for(int i = 0; i < portStatsList->port_stats_size(); i++) + { + uint id; + + id = portStatsList->port_stats(i).port_id().id(); + // FIXME: don't mix port id & index into mPorts[] + mPorts[id]->updateStats(portStatsList->mutable_port_stats(i)); + } + + emit statsChanged(mPortGroupId); + +_error_exit: + delete portStatsList; + isGetStatsPending_ = false; +} + +void PortGroup::clearPortStats(QList *portList) +{ + OstProto::PortIdList portIdList; + OstProto::Ack *ack; + + qDebug("In %s", __FUNCTION__); + + if (state() != QAbstractSocket::ConnectedState) + return; + + ack = new OstProto::Ack; + if (portList == NULL) + portIdList.CopyFrom(this->portIdList); + else + { + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId; + + portId = portIdList.add_port_id(); + portId->set_id(portList->at(i)); + } + } + + rpcController->Reset(); + serviceStub->clearStats(rpcController, &portIdList, ack, + NewCallback(this, &PortGroup::processClearStatsAck, ack)); +} + +void PortGroup::processClearStatsAck(OstProto::Ack *ack) +{ + qDebug("In %s", __FUNCTION__); + + // Refresh stats immediately after a stats clear/reset + getPortStats(); + + delete ack; +} + diff --git a/client/portgroup.h b/client/portgroup.h index a503910..4566b46 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -1,119 +1,119 @@ -#ifndef _PORT_GROUP_H -#define _PORT_GROUP_H - -#include "port.h" -#include -#include - -#include "../common/protocol.pb.h" -#include "pbrpcchannel.h" - -/* TODO -HIGH -MED -LOW -- Allow hostnames in addition to IP Address as "server address" -*/ - -#define DEFAULT_SERVER_PORT 7878 - -class QFile; - -class PortGroup : public QObject { - Q_OBJECT - -private: - quint32 mPortGroupId; - static quint32 mPortGroupAllocId; - QString mUserAlias; // user defined -#if 0 // PB - QTcpSocket *mpSocket; - QHostAddress mServerAddress; - quint16 mServerPort; -#endif - PbRpcChannel *rpcChannel; - PbRpcController *rpcController; - PbRpcController *rpcControllerStats; - bool isGetStatsPending_; - ::OstProto::OstService::Stub *serviceStub; - - ::OstProto::PortIdList portIdList; -public: // FIXME(HIGH): member access - QList mPorts; - -public: - PortGroup(QHostAddress ip = QHostAddress::LocalHost, - quint16 port = DEFAULT_SERVER_PORT); - ~PortGroup(); - - void connectToHost() { rpcChannel->establish(); } - void connectToHost(QHostAddress ip, quint16 port) - { rpcChannel->establish(ip, port); } - void disconnectFromHost() { rpcChannel->tearDown(); } - - int numPorts() const { return mPorts.size(); } - quint32 id() const { return mPortGroupId; } - - const QString& userAlias() const { return mUserAlias; } - void setUserAlias(QString alias) { mUserAlias = alias; }; - - const QHostAddress& serverAddress() const - { return rpcChannel->serverAddress(); } - quint16 serverPort() const - { return rpcChannel->serverPort(); } - QAbstractSocket::SocketState state() const - { return rpcChannel->state(); } - - void processPortIdList(OstProto::PortIdList *portIdList); - void processPortConfigList(OstProto::PortConfigList *portConfigList); - - void getStreamIdList(int portIndex = 0, - OstProto::StreamIdList *streamIdList = NULL); - void getStreamConfigList(int portIndex = 0, - OstProto::StreamConfigList *streamConfigList = NULL); - - void processModifyStreamAck(OstProto::Ack *ack); - - void startTx(QList *portList = NULL); - void processStartTxAck(OstProto::Ack *ack); - void stopTx(QList *portList = NULL); - void processStopTxAck(OstProto::Ack *ack); - - void startCapture(QList *portList = NULL); - void processStartCaptureAck(OstProto::Ack *ack); - void stopCapture(QList *portList = NULL); - void processStopCaptureAck(OstProto::Ack *ack); - void viewCapture(QList *portList = NULL); - void processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile); - - void getPortStats(); - void processPortStatsList(OstProto::PortStatsList *portStatsList); - void clearPortStats(QList *portList = NULL); - void processClearStatsAck(OstProto::Ack *ack); - -signals: - void portGroupDataChanged(int portGroupId, int portId = 0xFFFF); - void portListAboutToBeChanged(quint32 portGroupId); - void portListChanged(quint32 portGroupId); - void statsChanged(quint32 portGroupId); - -private slots: - void on_rpcChannel_stateChanged(); - void on_rpcChannel_connected(); - void on_rpcChannel_disconnected(); - void on_rpcChannel_error(QAbstractSocket::SocketError socketError); - -public slots: - void when_configApply(int portIndex, uint *cookie = NULL); -#if 0 // PB - void on_rpcChannel_when_dataAvail(); -#endif - -private: -#if 0 // PB - void ProcessCapabilityInfo(const char *msg, qint32 size); - void ProcessMsg(const char *msg, quint32 size); -#endif -}; - -#endif +#ifndef _PORT_GROUP_H +#define _PORT_GROUP_H + +#include "port.h" +#include +#include + +#include "../common/protocol.pb.h" +#include "pbrpcchannel.h" + +/* TODO +HIGH +MED +LOW +- Allow hostnames in addition to IP Address as "server address" +*/ + +#define DEFAULT_SERVER_PORT 7878 + +class QFile; + +class PortGroup : public QObject { + Q_OBJECT + +private: + quint32 mPortGroupId; + static quint32 mPortGroupAllocId; + QString mUserAlias; // user defined +#if 0 // PB + QTcpSocket *mpSocket; + QHostAddress mServerAddress; + quint16 mServerPort; +#endif + PbRpcChannel *rpcChannel; + PbRpcController *rpcController; + PbRpcController *rpcControllerStats; + bool isGetStatsPending_; + ::OstProto::OstService::Stub *serviceStub; + + ::OstProto::PortIdList portIdList; +public: // FIXME(HIGH): member access + QList mPorts; + +public: + PortGroup(QHostAddress ip = QHostAddress::LocalHost, + quint16 port = DEFAULT_SERVER_PORT); + ~PortGroup(); + + void connectToHost() { rpcChannel->establish(); } + void connectToHost(QHostAddress ip, quint16 port) + { rpcChannel->establish(ip, port); } + void disconnectFromHost() { rpcChannel->tearDown(); } + + int numPorts() const { return mPorts.size(); } + quint32 id() const { return mPortGroupId; } + + const QString& userAlias() const { return mUserAlias; } + void setUserAlias(QString alias) { mUserAlias = alias; }; + + const QHostAddress& serverAddress() const + { return rpcChannel->serverAddress(); } + quint16 serverPort() const + { return rpcChannel->serverPort(); } + QAbstractSocket::SocketState state() const + { return rpcChannel->state(); } + + void processPortIdList(OstProto::PortIdList *portIdList); + void processPortConfigList(OstProto::PortConfigList *portConfigList); + + void getStreamIdList(int portIndex = 0, + OstProto::StreamIdList *streamIdList = NULL); + void getStreamConfigList(int portIndex = 0, + OstProto::StreamConfigList *streamConfigList = NULL); + + void processModifyStreamAck(OstProto::Ack *ack); + + void startTx(QList *portList = NULL); + void processStartTxAck(OstProto::Ack *ack); + void stopTx(QList *portList = NULL); + void processStopTxAck(OstProto::Ack *ack); + + void startCapture(QList *portList = NULL); + void processStartCaptureAck(OstProto::Ack *ack); + void stopCapture(QList *portList = NULL); + void processStopCaptureAck(OstProto::Ack *ack); + void viewCapture(QList *portList = NULL); + void processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile); + + void getPortStats(); + void processPortStatsList(OstProto::PortStatsList *portStatsList); + void clearPortStats(QList *portList = NULL); + void processClearStatsAck(OstProto::Ack *ack); + +signals: + void portGroupDataChanged(int portGroupId, int portId = 0xFFFF); + void portListAboutToBeChanged(quint32 portGroupId); + void portListChanged(quint32 portGroupId); + void statsChanged(quint32 portGroupId); + +private slots: + void on_rpcChannel_stateChanged(); + void on_rpcChannel_connected(); + void on_rpcChannel_disconnected(); + void on_rpcChannel_error(QAbstractSocket::SocketError socketError); + +public slots: + void when_configApply(int portIndex, uint *cookie = NULL); +#if 0 // PB + void on_rpcChannel_when_dataAvail(); +#endif + +private: +#if 0 // PB + void ProcessCapabilityInfo(const char *msg, qint32 size); + void ProcessMsg(const char *msg, quint32 size); +#endif +}; + +#endif diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index 3e67d01..49aa539 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -1,98 +1,98 @@ -#include "portgrouplist.h" - -// TODO(LOW): Remove -#include - -PortGroupList::PortGroupList() - : mPortGroupListModel(this), - mStreamListModel(this), - mPortStatsModel(this, this) -{ - PortGroup *pg; - - // TODO(LOW): Remove - new ModelTest(getStreamModel()); - new ModelTest(getPortModel()); - new ModelTest(getPortStatsModel()); - - // Add the "Local" Port Group - pg = new PortGroup; - addPortGroup(*pg); -} - -bool PortGroupList::isPortGroup(const QModelIndex& index) -{ - return mPortGroupListModel.isPortGroup(index); -} - -bool PortGroupList::isPort(const QModelIndex& index) -{ - return mPortGroupListModel.isPort(index); -} - -PortGroup& PortGroupList::portGroup(const QModelIndex& index) -{ - Q_ASSERT(mPortGroupListModel.isPortGroup(index)); - - return *(mPortGroups[index.row()]); -} - -Port& PortGroupList::port(const QModelIndex& index) -{ - Q_ASSERT(mPortGroupListModel.isPort(index)); - return (*mPortGroups.at(index.parent().row())->mPorts[index.row()]); -} - -void PortGroupList::addPortGroup(PortGroup &portGroup) -{ - mPortGroupListModel.portGroupAboutToBeAppended(); - - connect(&portGroup, SIGNAL(portGroupDataChanged(int, int)), - &mPortGroupListModel, SLOT(when_portGroupDataChanged(int, int))); -#if 0 - connect(&portGroup, SIGNAL(portListAboutToBeChanged(quint32)), - &mPortGroupListModel, SLOT(triggerLayoutAboutToBeChanged())); - connect(&portGroup, SIGNAL(portListChanged(quint32)), - &mPortGroupListModel, SLOT(triggerLayoutChanged())); -#endif - connect(&portGroup, SIGNAL(portListChanged(quint32)), - &mPortGroupListModel, SLOT(when_portListChanged())); - - connect(&portGroup, SIGNAL(portListChanged(quint32)), - &mPortStatsModel, SLOT(when_portListChanged())); - - connect(&portGroup, SIGNAL(statsChanged(quint32)), - &mPortStatsModel, SLOT(when_portGroup_stats_update(quint32))); - - mPortGroups.append(&portGroup); - portGroup.connectToHost(); - - mPortGroupListModel.portGroupAppended(); - - mPortStatsModel.when_portListChanged(); -} - -void PortGroupList::removePortGroup(PortGroup &portGroup) -{ - mPortGroupListModel.portGroupAboutToBeRemoved(&portGroup); - - PortGroup* pg = mPortGroups.takeAt(mPortGroups.indexOf(&portGroup)); - qDebug("after takeAt()"); - mPortGroupListModel.portGroupRemoved(); - - delete pg; - - mPortStatsModel.when_portListChanged(); -} - -//.................... -// Private Methods -//.................... -int PortGroupList::indexOfPortGroup(quint32 portGroupId) -{ - for (int i = 0; i < mPortGroups.size(); i++) { - if (mPortGroups.value(i)->id() == portGroupId) - return i; - } - return -1; -} +#include "portgrouplist.h" + +// TODO(LOW): Remove +#include + +PortGroupList::PortGroupList() + : mPortGroupListModel(this), + mStreamListModel(this), + mPortStatsModel(this, this) +{ + PortGroup *pg; + + // TODO(LOW): Remove + new ModelTest(getStreamModel()); + new ModelTest(getPortModel()); + new ModelTest(getPortStatsModel()); + + // Add the "Local" Port Group + pg = new PortGroup; + addPortGroup(*pg); +} + +bool PortGroupList::isPortGroup(const QModelIndex& index) +{ + return mPortGroupListModel.isPortGroup(index); +} + +bool PortGroupList::isPort(const QModelIndex& index) +{ + return mPortGroupListModel.isPort(index); +} + +PortGroup& PortGroupList::portGroup(const QModelIndex& index) +{ + Q_ASSERT(mPortGroupListModel.isPortGroup(index)); + + return *(mPortGroups[index.row()]); +} + +Port& PortGroupList::port(const QModelIndex& index) +{ + Q_ASSERT(mPortGroupListModel.isPort(index)); + return (*mPortGroups.at(index.parent().row())->mPorts[index.row()]); +} + +void PortGroupList::addPortGroup(PortGroup &portGroup) +{ + mPortGroupListModel.portGroupAboutToBeAppended(); + + connect(&portGroup, SIGNAL(portGroupDataChanged(int, int)), + &mPortGroupListModel, SLOT(when_portGroupDataChanged(int, int))); +#if 0 + connect(&portGroup, SIGNAL(portListAboutToBeChanged(quint32)), + &mPortGroupListModel, SLOT(triggerLayoutAboutToBeChanged())); + connect(&portGroup, SIGNAL(portListChanged(quint32)), + &mPortGroupListModel, SLOT(triggerLayoutChanged())); +#endif + connect(&portGroup, SIGNAL(portListChanged(quint32)), + &mPortGroupListModel, SLOT(when_portListChanged())); + + connect(&portGroup, SIGNAL(portListChanged(quint32)), + &mPortStatsModel, SLOT(when_portListChanged())); + + connect(&portGroup, SIGNAL(statsChanged(quint32)), + &mPortStatsModel, SLOT(when_portGroup_stats_update(quint32))); + + mPortGroups.append(&portGroup); + portGroup.connectToHost(); + + mPortGroupListModel.portGroupAppended(); + + mPortStatsModel.when_portListChanged(); +} + +void PortGroupList::removePortGroup(PortGroup &portGroup) +{ + mPortGroupListModel.portGroupAboutToBeRemoved(&portGroup); + + PortGroup* pg = mPortGroups.takeAt(mPortGroups.indexOf(&portGroup)); + qDebug("after takeAt()"); + mPortGroupListModel.portGroupRemoved(); + + delete pg; + + mPortStatsModel.when_portListChanged(); +} + +//.................... +// Private Methods +//.................... +int PortGroupList::indexOfPortGroup(quint32 portGroupId) +{ + for (int i = 0; i < mPortGroups.size(); i++) { + if (mPortGroups.value(i)->id() == portGroupId) + return i; + } + return -1; +} diff --git a/client/portgrouplist.h b/client/portgrouplist.h index e5e398b..3dd8f5f 100644 --- a/client/portgrouplist.h +++ b/client/portgrouplist.h @@ -1,52 +1,52 @@ -#ifndef _PORT_GROUP_LIST_H -#define _PORT_GROUP_LIST_H - -#include "portgroup.h" -#include -#include -#include "portmodel.h" -#include "streammodel.h" -#include "portstatsmodel.h" - -class PortModel; -class StreamModel; - -class PortGroupList : public QObject { - - Q_OBJECT - - friend class PortModel; - friend class StreamModel; - friend class PortStatsModel; - - QList mPortGroups; - PortModel mPortGroupListModel; - StreamModel mStreamListModel; - PortStatsModel mPortStatsModel; - -// Methods -public: - PortGroupList(); - - - PortModel* getPortModel() { return &mPortGroupListModel; } - PortStatsModel* getPortStatsModel() { return &mPortStatsModel; } - StreamModel* getStreamModel() { return &mStreamListModel; } - - bool isPortGroup(const QModelIndex& index); - bool isPort(const QModelIndex& index); - PortGroup& portGroup(const QModelIndex& index); - Port& port(const QModelIndex& index); - - int numPortGroups() { return mPortGroups.size(); } - PortGroup& portGroupByIndex(int index) { return *(mPortGroups[index]); } - - void addPortGroup(PortGroup &portGroup); - void removePortGroup(PortGroup &portGroup); - -private: - int indexOfPortGroup(quint32 portGroupId); - -}; - -#endif +#ifndef _PORT_GROUP_LIST_H +#define _PORT_GROUP_LIST_H + +#include "portgroup.h" +#include +#include +#include "portmodel.h" +#include "streammodel.h" +#include "portstatsmodel.h" + +class PortModel; +class StreamModel; + +class PortGroupList : public QObject { + + Q_OBJECT + + friend class PortModel; + friend class StreamModel; + friend class PortStatsModel; + + QList mPortGroups; + PortModel mPortGroupListModel; + StreamModel mStreamListModel; + PortStatsModel mPortStatsModel; + +// Methods +public: + PortGroupList(); + + + PortModel* getPortModel() { return &mPortGroupListModel; } + PortStatsModel* getPortStatsModel() { return &mPortStatsModel; } + StreamModel* getStreamModel() { return &mStreamListModel; } + + bool isPortGroup(const QModelIndex& index); + bool isPort(const QModelIndex& index); + PortGroup& portGroup(const QModelIndex& index); + Port& port(const QModelIndex& index); + + int numPortGroups() { return mPortGroups.size(); } + PortGroup& portGroupByIndex(int index) { return *(mPortGroups[index]); } + + void addPortGroup(PortGroup &portGroup); + void removePortGroup(PortGroup &portGroup); + +private: + int indexOfPortGroup(quint32 portGroupId); + +}; + +#endif diff --git a/client/portmodel.cpp b/client/portmodel.cpp index ff5c482..6ab422e 100644 --- a/client/portmodel.cpp +++ b/client/portmodel.cpp @@ -1,311 +1,311 @@ -#include "portmodel.h" -#include "portgrouplist.h" -#include - -#if 0 -#define DBG0(x) qDebug(x) -#define DBG1(x, p1) qDebug(x, (p1)) -#else -#define DBG0(x) {} -#define DBG1(x, p1) {} -#endif - -PortModel::PortModel(PortGroupList *p, QObject *parent) - : QAbstractItemModel(parent) -{ - pgl = p; -} - -int PortModel::rowCount(const QModelIndex &parent) const -{ - // qDebug("RowCount Enter\n"); - if (!parent.isValid()) - { - // Top Level Item - //qDebug("RowCount (Top) Exit: %d\n", pgl->mPortGroups.size()); - return pgl->mPortGroups.size(); - } - // qDebug("RowCount non top %d, %d, %llx\n", - // parent.row(), parent.column(), parent.internalId()); - - quint16 pg = (parent.internalId() >> 16) & 0xFFFF; - quint16 p = parent.internalId() & 0xFFFF; - if (p == 0xFFFF) - { -#if 0 // wrong code? - int count = 0; - foreach(PortGroup *pg, pgl->mPortGroups) - { - count += pg->numPorts(); - } - //qDebug("RowCount (Mid) Exit: %d\n", count); - return count; -#endif - if (parent.column() == 0) - return pgl->mPortGroups.value(pgl->indexOfPortGroup(pg))->numPorts(); - else - return 0; - } - else - { - // Leaf Item - return 0; - } -} - -int PortModel::columnCount(const QModelIndex &parent ) const -{ - return 1; // FIXME: hardcoding -} - -Qt::ItemFlags PortModel::flags(const QModelIndex &index) const -{ - return QAbstractItemModel::flags(index); // FIXME: no need for this func -} -QVariant PortModel::data(const QModelIndex &index, int role) const -{ - - DBG0("Enter PortModel data\n"); - - // Check for a valid index - if (!index.isValid()) - return QVariant(); - - DBG1("PortModel::data(index).row = %d", index.row()); - DBG1("PortModel::data(index).column = %0d", index.column()); - DBG1("PortModel::data(index).internalId = %08llx", index.internalId()); - - QModelIndex parent = index.parent(); - - if (!parent.isValid()) - { - // Top Level Item - PortGroup - if ((role == Qt::DisplayRole)) - { - DBG0("Exit PortModel data 1\n"); - return QString("Port Group %1: %2 [%3:%4] (%5)"). - arg(pgl->mPortGroups.at(index.row())->id()). - arg(pgl->mPortGroups.at(index.row())->userAlias()). - arg(pgl->mPortGroups.at(index.row())->serverAddress().toString()). - arg(pgl->mPortGroups.at(index.row())->serverPort()). - arg(pgl->mPortGroups.value(index.row())->numPorts()); - } - else if ((role == Qt::DecorationRole)) - { - DBG0("Exit PortModel data 2\n"); - switch(pgl->mPortGroups.at(index.row())->state()) - { - case QAbstractSocket::UnconnectedState: - return QIcon(":/icons/bullet_red.png"); - - case QAbstractSocket::HostLookupState: - return QIcon(":/icons/bullet_yellow.png"); - - case QAbstractSocket::ConnectingState: - case QAbstractSocket::ClosingState: - return QIcon(":/icons/bullet_orange.png"); - - case QAbstractSocket::ConnectedState: - return QIcon(":/icons/bullet_green.png"); - - - case QAbstractSocket::BoundState: - case QAbstractSocket::ListeningState: - default: - return QIcon(":/icons/bullet_error.png"); - } - } - else - { - DBG0("Exit PortModel data 3\n"); - return QVariant(); - } - } - else - { - // Non Top Level - Port - if ((role == Qt::DisplayRole)) - { - DBG0("Exit PortModel data 4\n"); - if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) - return QVariant(); - - return QString("Port %1: %2 [%3] (%4)"). - arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()]->id()). - arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()]->name()). - arg(QHostAddress("0.0.0.0").toString()). // FIXME(LOW) - arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()]->description()); - } - else if ((role == Qt::DecorationRole)) - { - DBG0("Exit PortModel data 5\n"); - if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) - return QVariant(); - switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()]->linkState()) - { - case OstProto::LinkStateUnknown: - return QIcon(":/icons/bullet_white.png"); - case OstProto::LinkStateDown: - return QIcon(":/icons/bullet_red.png"); - case OstProto::LinkStateUp: - return QIcon(":/icons/bullet_green.png"); - default: - qFatal("unexpected/unimplemented port oper state"); - } - } - else - { - DBG0("Exit PortModel data 6\n"); - return QVariant(); - } - } - - return QVariant(); -} - -QVariant PortModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role != Qt::DisplayRole) - return QVariant(); - - if (orientation == Qt::Horizontal) - return QVariant(); - else - return QString("Name"); -} - -QModelIndex PortModel::index (int row, int col, - const QModelIndex & parent) const -{ - if (!hasIndex(row, col, parent)) - return QModelIndex(); - - //qDebug("index: R=%d, C=%d, PR=%d, PC=%d, PID=%llx\n", - // row, col, parent.row(), parent.column(), parent.internalId()); - - if (!parent.isValid()) - { - // Top Level Item - quint16 pg = pgl->mPortGroups.value(row)->id(), p = 0xFFFF; - quint32 id = (pg << 16) | p; - //qDebug("index (top) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); - - return createIndex(row, col, id); - } - else - { - quint16 pg = parent.internalId() >> 16; - quint16 p = pgl->mPortGroups.value(parent.row())->mPorts.value(row)->id(); - quint32 id = (pg << 16) | p; - //qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); - - return createIndex(row, col, id); - } -} - -QModelIndex PortModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - //qDebug("parent: R=%d, C=%d ID=%llx\n", - // index.row(), index.column(), index.internalId()); - - quint16 pg = index.internalId() >> 16; - quint16 p = index.internalId() & 0x0000FFFF; - - //qDebug("parent dbg: PG=%d, P=%d\n", pg, p); - - if (p == 0xFFFF) - { - //qDebug("parent ret: NULL\n"); - // Top Level Item - PG - return QModelIndex(); - } - - quint32 id = (pg << 16) | 0xFFFF; - //qDebug("parent ret: R=%d, C=%d, ID=%x\n", pg, 0, id); - - return createIndex(pgl->indexOfPortGroup(pg), 0, id); - -} - -bool PortModel::isPortGroup(const QModelIndex& index) -{ - if ((index.internalId() & 0xFFFF) == 0xFFFF) - return true; - else - return false; -} - -bool PortModel::isPort(const QModelIndex& index) -{ - if ((index.internalId() & 0xFFFF) != 0xFFFF) - return true; - else - return false; -} - -quint32 PortModel::portGroupId(const QModelIndex& index) -{ - return (index.internalId()) >> 16 & 0xFFFF; -} - -quint32 PortModel::portId(const QModelIndex& index) -{ - return (index.internalId()) & 0xFFFF; -} - - - -// ---------------------------------------------- -// Slots -// ---------------------------------------------- -void PortModel::when_portGroupDataChanged(int portGroupId, int portId) -{ - QModelIndex index; - int row; - - if (portId == 0xFFFF) - row = pgl->indexOfPortGroup(portGroupId); - else - row = portId; - - index = createIndex(row, 0, (portGroupId << 16) | portId); - - emit dataChanged(index, index); -} - -void PortModel::portGroupAboutToBeAppended() -{ - int row; - - row = pgl->mPortGroups.size(); - beginInsertRows(QModelIndex(), row, row); -} - -void PortModel::portGroupAppended() -{ - endInsertRows(); -} - -void PortModel::portGroupAboutToBeRemoved(PortGroup *portGroup) -{ - int row; - - row = pgl->mPortGroups.indexOf(portGroup); - beginRemoveRows(QModelIndex(), row, row); -} - -void PortModel::portGroupRemoved() -{ - endRemoveRows(); -} - -void PortModel::when_portListChanged() -{ - reset(); -} +#include "portmodel.h" +#include "portgrouplist.h" +#include + +#if 0 +#define DBG0(x) qDebug(x) +#define DBG1(x, p1) qDebug(x, (p1)) +#else +#define DBG0(x) {} +#define DBG1(x, p1) {} +#endif + +PortModel::PortModel(PortGroupList *p, QObject *parent) + : QAbstractItemModel(parent) +{ + pgl = p; +} + +int PortModel::rowCount(const QModelIndex &parent) const +{ + // qDebug("RowCount Enter\n"); + if (!parent.isValid()) + { + // Top Level Item + //qDebug("RowCount (Top) Exit: %d\n", pgl->mPortGroups.size()); + return pgl->mPortGroups.size(); + } + // qDebug("RowCount non top %d, %d, %llx\n", + // parent.row(), parent.column(), parent.internalId()); + + quint16 pg = (parent.internalId() >> 16) & 0xFFFF; + quint16 p = parent.internalId() & 0xFFFF; + if (p == 0xFFFF) + { +#if 0 // wrong code? + int count = 0; + foreach(PortGroup *pg, pgl->mPortGroups) + { + count += pg->numPorts(); + } + //qDebug("RowCount (Mid) Exit: %d\n", count); + return count; +#endif + if (parent.column() == 0) + return pgl->mPortGroups.value(pgl->indexOfPortGroup(pg))->numPorts(); + else + return 0; + } + else + { + // Leaf Item + return 0; + } +} + +int PortModel::columnCount(const QModelIndex &parent ) const +{ + return 1; // FIXME: hardcoding +} + +Qt::ItemFlags PortModel::flags(const QModelIndex &index) const +{ + return QAbstractItemModel::flags(index); // FIXME: no need for this func +} +QVariant PortModel::data(const QModelIndex &index, int role) const +{ + + DBG0("Enter PortModel data\n"); + + // Check for a valid index + if (!index.isValid()) + return QVariant(); + + DBG1("PortModel::data(index).row = %d", index.row()); + DBG1("PortModel::data(index).column = %0d", index.column()); + DBG1("PortModel::data(index).internalId = %08llx", index.internalId()); + + QModelIndex parent = index.parent(); + + if (!parent.isValid()) + { + // Top Level Item - PortGroup + if ((role == Qt::DisplayRole)) + { + DBG0("Exit PortModel data 1\n"); + return QString("Port Group %1: %2 [%3:%4] (%5)"). + arg(pgl->mPortGroups.at(index.row())->id()). + arg(pgl->mPortGroups.at(index.row())->userAlias()). + arg(pgl->mPortGroups.at(index.row())->serverAddress().toString()). + arg(pgl->mPortGroups.at(index.row())->serverPort()). + arg(pgl->mPortGroups.value(index.row())->numPorts()); + } + else if ((role == Qt::DecorationRole)) + { + DBG0("Exit PortModel data 2\n"); + switch(pgl->mPortGroups.at(index.row())->state()) + { + case QAbstractSocket::UnconnectedState: + return QIcon(":/icons/bullet_red.png"); + + case QAbstractSocket::HostLookupState: + return QIcon(":/icons/bullet_yellow.png"); + + case QAbstractSocket::ConnectingState: + case QAbstractSocket::ClosingState: + return QIcon(":/icons/bullet_orange.png"); + + case QAbstractSocket::ConnectedState: + return QIcon(":/icons/bullet_green.png"); + + + case QAbstractSocket::BoundState: + case QAbstractSocket::ListeningState: + default: + return QIcon(":/icons/bullet_error.png"); + } + } + else + { + DBG0("Exit PortModel data 3\n"); + return QVariant(); + } + } + else + { + // Non Top Level - Port + if ((role == Qt::DisplayRole)) + { + DBG0("Exit PortModel data 4\n"); + if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) + return QVariant(); + + return QString("Port %1: %2 [%3] (%4)"). + arg(pgl->mPortGroups.at( + parent.row())->mPorts[index.row()]->id()). + arg(pgl->mPortGroups.at( + parent.row())->mPorts[index.row()]->name()). + arg(QHostAddress("0.0.0.0").toString()). // FIXME(LOW) + arg(pgl->mPortGroups.at( + parent.row())->mPorts[index.row()]->description()); + } + else if ((role == Qt::DecorationRole)) + { + DBG0("Exit PortModel data 5\n"); + if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) + return QVariant(); + switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()]->linkState()) + { + case OstProto::LinkStateUnknown: + return QIcon(":/icons/bullet_white.png"); + case OstProto::LinkStateDown: + return QIcon(":/icons/bullet_red.png"); + case OstProto::LinkStateUp: + return QIcon(":/icons/bullet_green.png"); + default: + qFatal("unexpected/unimplemented port oper state"); + } + } + else + { + DBG0("Exit PortModel data 6\n"); + return QVariant(); + } + } + + return QVariant(); +} + +QVariant PortModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QVariant(); + else + return QString("Name"); +} + +QModelIndex PortModel::index (int row, int col, + const QModelIndex & parent) const +{ + if (!hasIndex(row, col, parent)) + return QModelIndex(); + + //qDebug("index: R=%d, C=%d, PR=%d, PC=%d, PID=%llx\n", + // row, col, parent.row(), parent.column(), parent.internalId()); + + if (!parent.isValid()) + { + // Top Level Item + quint16 pg = pgl->mPortGroups.value(row)->id(), p = 0xFFFF; + quint32 id = (pg << 16) | p; + //qDebug("index (top) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); + + return createIndex(row, col, id); + } + else + { + quint16 pg = parent.internalId() >> 16; + quint16 p = pgl->mPortGroups.value(parent.row())->mPorts.value(row)->id(); + quint32 id = (pg << 16) | p; + //qDebug("index (nontop) dbg: PG=%d, P=%d, ID=%x\n", pg, p, id); + + return createIndex(row, col, id); + } +} + +QModelIndex PortModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + //qDebug("parent: R=%d, C=%d ID=%llx\n", + // index.row(), index.column(), index.internalId()); + + quint16 pg = index.internalId() >> 16; + quint16 p = index.internalId() & 0x0000FFFF; + + //qDebug("parent dbg: PG=%d, P=%d\n", pg, p); + + if (p == 0xFFFF) + { + //qDebug("parent ret: NULL\n"); + // Top Level Item - PG + return QModelIndex(); + } + + quint32 id = (pg << 16) | 0xFFFF; + //qDebug("parent ret: R=%d, C=%d, ID=%x\n", pg, 0, id); + + return createIndex(pgl->indexOfPortGroup(pg), 0, id); + +} + +bool PortModel::isPortGroup(const QModelIndex& index) +{ + if ((index.internalId() & 0xFFFF) == 0xFFFF) + return true; + else + return false; +} + +bool PortModel::isPort(const QModelIndex& index) +{ + if ((index.internalId() & 0xFFFF) != 0xFFFF) + return true; + else + return false; +} + +quint32 PortModel::portGroupId(const QModelIndex& index) +{ + return (index.internalId()) >> 16 & 0xFFFF; +} + +quint32 PortModel::portId(const QModelIndex& index) +{ + return (index.internalId()) & 0xFFFF; +} + + + +// ---------------------------------------------- +// Slots +// ---------------------------------------------- +void PortModel::when_portGroupDataChanged(int portGroupId, int portId) +{ + QModelIndex index; + int row; + + if (portId == 0xFFFF) + row = pgl->indexOfPortGroup(portGroupId); + else + row = portId; + + index = createIndex(row, 0, (portGroupId << 16) | portId); + + emit dataChanged(index, index); +} + +void PortModel::portGroupAboutToBeAppended() +{ + int row; + + row = pgl->mPortGroups.size(); + beginInsertRows(QModelIndex(), row, row); +} + +void PortModel::portGroupAppended() +{ + endInsertRows(); +} + +void PortModel::portGroupAboutToBeRemoved(PortGroup *portGroup) +{ + int row; + + row = pgl->mPortGroups.indexOf(portGroup); + beginRemoveRows(QModelIndex(), row, row); +} + +void PortModel::portGroupRemoved() +{ + endRemoveRows(); +} + +void PortModel::when_portListChanged() +{ + reset(); +} diff --git a/client/portmodel.h b/client/portmodel.h index eea9763..7f3b821 100644 --- a/client/portmodel.h +++ b/client/portmodel.h @@ -1,51 +1,51 @@ -#ifndef _PORT_MODEL_H -#define _PORT_MODEL_H - -#include - -class PortGroupList; -class PortGroup; - -class PortModel : public QAbstractItemModel -{ - Q_OBJECT - - friend class PortGroupList; - - PortGroupList *pgl; - - public: - PortModel(PortGroupList *p, QObject *parent = 0); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; - QModelIndex parent(const QModelIndex &index) const; - - bool isPortGroup(const QModelIndex& index); - bool isPort(const QModelIndex& index); - quint32 portGroupId(const QModelIndex& index); - quint32 portId(const QModelIndex& index); - - -private slots: - void when_portGroupDataChanged(int portGroupId, int portId); - - void portGroupAboutToBeAppended(); - void portGroupAppended(); - void portGroupAboutToBeRemoved(PortGroup *portGroup); - void portGroupRemoved(); - - void when_portListChanged(); - -#if 0 - void triggerLayoutAboutToBeChanged(); - void triggerLayoutChanged(); -#endif - -}; - -#endif +#ifndef _PORT_MODEL_H +#define _PORT_MODEL_H + +#include + +class PortGroupList; +class PortGroup; + +class PortModel : public QAbstractItemModel +{ + Q_OBJECT + + friend class PortGroupList; + + PortGroupList *pgl; + + public: + PortModel(PortGroupList *p, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; + QModelIndex parent(const QModelIndex &index) const; + + bool isPortGroup(const QModelIndex& index); + bool isPort(const QModelIndex& index); + quint32 portGroupId(const QModelIndex& index); + quint32 portId(const QModelIndex& index); + + +private slots: + void when_portGroupDataChanged(int portGroupId, int portId); + + void portGroupAboutToBeAppended(); + void portGroupAppended(); + void portGroupAboutToBeRemoved(PortGroup *portGroup); + void portGroupRemoved(); + + void when_portListChanged(); + +#if 0 + void triggerLayoutAboutToBeChanged(); + void triggerLayoutChanged(); +#endif + +}; + +#endif diff --git a/client/portstatsfilterdialog.cpp b/client/portstatsfilterdialog.cpp index b21bd37..4291fea 100644 --- a/client/portstatsfilterdialog.cpp +++ b/client/portstatsfilterdialog.cpp @@ -1,111 +1,111 @@ -#include "portstatsfilterdialog.h" - -PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent) -{ - setupUi(this); - - mUnselected.setSortRole(PositionRole); - - lvUnselected->setModel(&mUnselected); - lvSelected->setModel(&mSelected); -} - -QList PortStatsFilterDialog::getItemList(bool* ok, - QAbstractItemModel *model, Qt::Orientation orientation, - QList initial) -{ - QList ret; - - uint count = (orientation == Qt::Vertical) ? - model->rowCount() : model->columnCount(); - - *ok = false; - - mUnselected.clear(); - mSelected.clear(); - - for (uint i = 0; i < count; i++) - { - QStandardItem *item; - - item = new QStandardItem(model->headerData(i, orientation).toString()); - item->setData(i, PositionRole); - item->setFlags(Qt::ItemIsSelectable - | Qt::ItemIsDragEnabled - //| Qt::ItemIsDropEnabled - | Qt::ItemIsEnabled); - - if (initial.contains(i)) - mSelected.appendRow(item); - else - mUnselected.appendRow(item); - } - - // No need to sort right now 'coz we have inserted items in order - - if (exec() == QDialog::Accepted) - { - uint count = mSelected.rowCount(); - for (uint i = 0; i < count; i++) - { - QModelIndex index = mSelected.index(i, 0, QModelIndex()); - QStandardItem *item = mSelected.itemFromIndex(index); - ret.append(item->data(PositionRole).toInt()); - } - *ok = true; - } - - return ret; -} - -void PortStatsFilterDialog::on_tbSelectIn_clicked() -{ - QStandardItem *item; - while (lvUnselected->selectionModel()->selectedIndexes().size()) - { - item = mUnselected.takeItem(lvUnselected->selectionModel()-> - selectedIndexes().at(0).row()); - if (mUnselected.removeRow(lvUnselected->selectionModel()-> - selectedIndexes().at(0).row())) - mSelected.appendRow(item); - } -} - -void PortStatsFilterDialog::on_tbSelectOut_clicked() -{ - QStandardItem *item; - - while (lvSelected->selectionModel()->selectedIndexes().size()) - { - item = mSelected.takeItem(lvSelected->selectionModel()-> - selectedIndexes().at(0).row()); - if (mSelected.removeRow(lvSelected->selectionModel()-> - selectedIndexes().at(0).row())) - { - mUnselected.appendRow(item); - mUnselected.sort(0); - } - } -} - -void PortStatsFilterDialog::on_lvUnselected_doubleClicked(const QModelIndex &index) -{ - QStandardItem *item; - - item = mUnselected.takeItem(lvUnselected->currentIndex().row()); - if (mUnselected.removeRow(lvUnselected->currentIndex().row())) - mSelected.appendRow(item); -} - -void PortStatsFilterDialog::on_lvSelected_doubleClicked(const QModelIndex &index) -{ - QStandardItem *item; - - item = mSelected.takeItem(lvSelected->currentIndex().row()); - if (mSelected.removeRow(lvSelected->currentIndex().row())) - { - mUnselected.appendRow(item); - mUnselected.sort(0); - } -} - +#include "portstatsfilterdialog.h" + +PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent) +{ + setupUi(this); + + mUnselected.setSortRole(PositionRole); + + lvUnselected->setModel(&mUnselected); + lvSelected->setModel(&mSelected); +} + +QList PortStatsFilterDialog::getItemList(bool* ok, + QAbstractItemModel *model, Qt::Orientation orientation, + QList initial) +{ + QList ret; + + uint count = (orientation == Qt::Vertical) ? + model->rowCount() : model->columnCount(); + + *ok = false; + + mUnselected.clear(); + mSelected.clear(); + + for (uint i = 0; i < count; i++) + { + QStandardItem *item; + + item = new QStandardItem(model->headerData(i, orientation).toString()); + item->setData(i, PositionRole); + item->setFlags(Qt::ItemIsSelectable + | Qt::ItemIsDragEnabled + //| Qt::ItemIsDropEnabled + | Qt::ItemIsEnabled); + + if (initial.contains(i)) + mSelected.appendRow(item); + else + mUnselected.appendRow(item); + } + + // No need to sort right now 'coz we have inserted items in order + + if (exec() == QDialog::Accepted) + { + uint count = mSelected.rowCount(); + for (uint i = 0; i < count; i++) + { + QModelIndex index = mSelected.index(i, 0, QModelIndex()); + QStandardItem *item = mSelected.itemFromIndex(index); + ret.append(item->data(PositionRole).toInt()); + } + *ok = true; + } + + return ret; +} + +void PortStatsFilterDialog::on_tbSelectIn_clicked() +{ + QStandardItem *item; + while (lvUnselected->selectionModel()->selectedIndexes().size()) + { + item = mUnselected.takeItem(lvUnselected->selectionModel()-> + selectedIndexes().at(0).row()); + if (mUnselected.removeRow(lvUnselected->selectionModel()-> + selectedIndexes().at(0).row())) + mSelected.appendRow(item); + } +} + +void PortStatsFilterDialog::on_tbSelectOut_clicked() +{ + QStandardItem *item; + + while (lvSelected->selectionModel()->selectedIndexes().size()) + { + item = mSelected.takeItem(lvSelected->selectionModel()-> + selectedIndexes().at(0).row()); + if (mSelected.removeRow(lvSelected->selectionModel()-> + selectedIndexes().at(0).row())) + { + mUnselected.appendRow(item); + mUnselected.sort(0); + } + } +} + +void PortStatsFilterDialog::on_lvUnselected_doubleClicked(const QModelIndex &index) +{ + QStandardItem *item; + + item = mUnselected.takeItem(lvUnselected->currentIndex().row()); + if (mUnselected.removeRow(lvUnselected->currentIndex().row())) + mSelected.appendRow(item); +} + +void PortStatsFilterDialog::on_lvSelected_doubleClicked(const QModelIndex &index) +{ + QStandardItem *item; + + item = mSelected.takeItem(lvSelected->currentIndex().row()); + if (mSelected.removeRow(lvSelected->currentIndex().row())) + { + mUnselected.appendRow(item); + mUnselected.sort(0); + } +} + diff --git a/client/portstatsfilterdialog.h b/client/portstatsfilterdialog.h index ce8016c..28d94ed 100644 --- a/client/portstatsfilterdialog.h +++ b/client/portstatsfilterdialog.h @@ -1,35 +1,35 @@ -#ifndef _PORT_STATS_FILTER_DIALOG_H -#define _PORT_STATS_FILTER_DIALOG_H - -#include -#include -#include -#include "ui_portstatsfilter.h" -#include "portgrouplist.h" - -class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog -{ - Q_OBJECT - -public: - PortStatsFilterDialog(QWidget *parent = 0); - QList getItemList(bool* ok, QAbstractItemModel *model, - Qt::Orientation orientation = Qt::Vertical, - QList initial = QList()); - -private: - enum ItemRole { - PositionRole = Qt::UserRole + 1 - }; - QStandardItemModel mUnselected; - QStandardItemModel mSelected; - -private slots: - void on_tbSelectIn_clicked(); - void on_tbSelectOut_clicked(); - void on_lvUnselected_doubleClicked(const QModelIndex &index); - void on_lvSelected_doubleClicked(const QModelIndex &index); -}; - -#endif - +#ifndef _PORT_STATS_FILTER_DIALOG_H +#define _PORT_STATS_FILTER_DIALOG_H + +#include +#include +#include +#include "ui_portstatsfilter.h" +#include "portgrouplist.h" + +class PortStatsFilterDialog : public QDialog, public Ui::PortStatsFilterDialog +{ + Q_OBJECT + +public: + PortStatsFilterDialog(QWidget *parent = 0); + QList getItemList(bool* ok, QAbstractItemModel *model, + Qt::Orientation orientation = Qt::Vertical, + QList initial = QList()); + +private: + enum ItemRole { + PositionRole = Qt::UserRole + 1 + }; + QStandardItemModel mUnselected; + QStandardItemModel mSelected; + +private slots: + void on_tbSelectIn_clicked(); + void on_tbSelectOut_clicked(); + void on_lvUnselected_doubleClicked(const QModelIndex &index); + void on_lvSelected_doubleClicked(const QModelIndex &index); +}; + +#endif + diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 5aec2b6..58993e4 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -1,288 +1,288 @@ -#include "portstatsmodel.h" -#include "portgrouplist.h" - -#include - -PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent) - : QAbstractTableModel(parent) -{ - QTimer *timer; - - pgl = p; - - timer = new QTimer(); - connect(timer, SIGNAL(timeout()), this, SLOT(updateStats())); - timer->start(1000); -} - -int PortStatsModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - if (numPorts.isEmpty()) - return 0; - - if (numPorts.last() == 0) - return 0; - - return (int) e_STAT_MAX; -} - -int PortStatsModel::columnCount(const QModelIndex &parent ) const -{ - if (parent.isValid()) - return 0; - else - if (numPorts.isEmpty()) - return 0; - else - return numPorts.last(); -} - -void PortStatsModel::getDomainIndexes(const QModelIndex &index, - uint &portGroupIdx, uint &portIdx) const -{ - int portNum; - - // TODO(LOW): Optimize using binary search: see qLowerBound() - portNum = index.column() + 1; - for (portGroupIdx = 0; portGroupIdx < (uint) numPorts.size(); portGroupIdx++) - if (portNum <= numPorts.at(portGroupIdx)) - break; - - if (portGroupIdx) - { - if (numPorts.at(portGroupIdx -1)) - portIdx = (portNum - 1) % numPorts.at(portGroupIdx - 1); - else - portIdx = portNum - 1; - } - else - portIdx = portNum - 1; - - //qDebug("PSM: %d - %d, %d", index.column(), portGroupIdx, portIdx); -} - -QVariant PortStatsModel::data(const QModelIndex &index, int role) const -{ - uint pgidx, pidx; - int row; - - // Check for a valid index - if (!index.isValid()) - return QVariant(); - - // Check for row/column limits - row = index.row(); - if (row >= e_STAT_MAX) - return QVariant(); - - if (numPorts.isEmpty()) - return QVariant(); - - if (index.column() >= (numPorts.last())) - return QVariant(); - - getDomainIndexes(index, pgidx, pidx); - - // Check role - if (role == Qt::DisplayRole) - { - OstProto::PortStats stats; - - stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx]->getStats(); - - switch(row) - { - // States - case e_LINK_STATE: - return LinkStateName.at(stats.state().link_state()); - - case e_TRANSMIT_STATE: - return BoolStateName.at(stats.state().is_transmit_on()); - - case e_CAPTURE_STATE: - return BoolStateName.at(stats.state().is_capture_on()); - - // Statistics - case e_STAT_FRAMES_RCVD: - return stats.rx_pkts(); - - case e_STAT_FRAMES_SENT: - return stats.tx_pkts(); - - case e_STAT_FRAME_SEND_RATE: - return stats.tx_pps(); - - case e_STAT_FRAME_RECV_RATE: - return stats.rx_pps(); - - case e_STAT_BYTES_RCVD: - return stats.rx_bytes(); - - case e_STAT_BYTES_SENT: - return stats.tx_bytes(); - - case e_STAT_BYTE_SEND_RATE: - return stats.tx_bps(); - - case e_STAT_BYTE_RECV_RATE: - return stats.rx_bps(); - -#if 0 - case e_STAT_FRAMES_RCVD_NIC: - return stats.rx_pkts_nic(); - - case e_STAT_FRAMES_SENT_NIC: - return stats.tx_pkts_nic(); - - case e_STAT_BYTES_RCVD_NIC: - return stats.rx_bytes_nic(); - - case e_STAT_BYTES_SENT_NIC: - return stats.tx_bytes_nic(); -#endif - default: - qWarning("%s: Unhandled stats id %d\n", __FUNCTION__, - index.row()); - return 0; - } - } - else if (role == Qt::TextAlignmentRole) - { - if (row >= e_STATE_START && row <= e_STATE_END) - return Qt::AlignHCenter; - else if (row >= e_STATISTICS_START && row <= e_STATISTICS_END) - return Qt::AlignRight; - else - return QVariant(); - } - else - return QVariant(); - -} - -QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, int role) const -{ -#ifdef Q_OS_WIN32 - // TODO(MED): The limitations should be the server's not the client's! - // Ideally we shd enhance the protocol to convey limitation(s), if any, - // from server to client - if (role == Qt::ToolTipRole) - { - if (orientation == Qt::Horizontal) - { - return QString("Limitation(s)" - "

Frames/Bytes Receieved: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
" - "Frames/Bytes Sent: Only Ostinato Tx pkts (Tx by others NOT included)

" - "

Rx/Tx Rates are derived from the above and hence subject to same limitations

" - ); - } - else - return QVariant(); - } -#endif - - if (role != Qt::DisplayRole) - return QVariant(); - - if (orientation == Qt::Horizontal) - { - uint portGroupIdx, portIdx; - - getDomainIndexes(index(0, section), portGroupIdx, portIdx); -#ifdef Q_OS_WIN32 - return QString("Port %1-%2 (*)").arg(portGroupIdx).arg(portIdx); -#else - return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx); -#endif - } - else - return PortStatName.at(section); -} - -void PortStatsModel::portListFromIndex(QModelIndexList indices, - QList &portList) -{ - int i, j; - QModelIndexList selectedCols(indices); - - portList.clear(); - - //selectedCols = indices.selectedColumns(); - for (i = 0; i < selectedCols.size(); i++) - { - uint portGroupIdx, portIdx; - - getDomainIndexes(selectedCols.at(i), portGroupIdx, portIdx); - for (j = 0; j < portList.size(); j++) - { - if (portList[j].portGroupId == portGroupIdx) - break; - } - - if (j >= portList.size()) - { - // PortGroup Not found - PortGroupAndPortList p; - - p.portGroupId = portGroupIdx; - p.portList.append(portIdx); - - portList.append(p); - } - else - { - // PortGroup found - - portList[j].portList.append(portIdx); - } - } -} - -// -// Slots -// -void PortStatsModel::when_portListChanged() -{ - int i, count = 0; - - // recalc numPorts - while (numPorts.size()) - numPorts.removeFirst(); - - for (i = 0; i < pgl->mPortGroups.size(); i++) - { - count += pgl->mPortGroups.at(i)->numPorts(); - numPorts.append(count); - } - - reset(); -} - -void PortStatsModel::on_portStatsUpdate(int port, void*stats) -{ - QModelIndex topLeft = index(port, 0, QModelIndex()); - QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex()); - - emit dataChanged(topLeft, bottomRight); -} - -void PortStatsModel::updateStats() -{ - // Request each portgroup to fetch updated stats - the port group - // raises a signal once updated stats are available - for (int i = 0; i < pgl->mPortGroups.size(); i++) - pgl->mPortGroups[i]->getPortStats(); -} - -void PortStatsModel::when_portGroup_stats_update(quint32 portGroupId) -{ - // FIXME(MED): update only the changed ports, not all - - QModelIndex topLeft = index(0, 0, QModelIndex()); - QModelIndex bottomRight = index(rowCount(), columnCount(), QModelIndex()); - - emit dataChanged(topLeft, bottomRight); -} +#include "portstatsmodel.h" +#include "portgrouplist.h" + +#include + +PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent) + : QAbstractTableModel(parent) +{ + QTimer *timer; + + pgl = p; + + timer = new QTimer(); + connect(timer, SIGNAL(timeout()), this, SLOT(updateStats())); + timer->start(1000); +} + +int PortStatsModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + if (numPorts.isEmpty()) + return 0; + + if (numPorts.last() == 0) + return 0; + + return (int) e_STAT_MAX; +} + +int PortStatsModel::columnCount(const QModelIndex &parent ) const +{ + if (parent.isValid()) + return 0; + else + if (numPorts.isEmpty()) + return 0; + else + return numPorts.last(); +} + +void PortStatsModel::getDomainIndexes(const QModelIndex &index, + uint &portGroupIdx, uint &portIdx) const +{ + int portNum; + + // TODO(LOW): Optimize using binary search: see qLowerBound() + portNum = index.column() + 1; + for (portGroupIdx = 0; portGroupIdx < (uint) numPorts.size(); portGroupIdx++) + if (portNum <= numPorts.at(portGroupIdx)) + break; + + if (portGroupIdx) + { + if (numPorts.at(portGroupIdx -1)) + portIdx = (portNum - 1) % numPorts.at(portGroupIdx - 1); + else + portIdx = portNum - 1; + } + else + portIdx = portNum - 1; + + //qDebug("PSM: %d - %d, %d", index.column(), portGroupIdx, portIdx); +} + +QVariant PortStatsModel::data(const QModelIndex &index, int role) const +{ + uint pgidx, pidx; + int row; + + // Check for a valid index + if (!index.isValid()) + return QVariant(); + + // Check for row/column limits + row = index.row(); + if (row >= e_STAT_MAX) + return QVariant(); + + if (numPorts.isEmpty()) + return QVariant(); + + if (index.column() >= (numPorts.last())) + return QVariant(); + + getDomainIndexes(index, pgidx, pidx); + + // Check role + if (role == Qt::DisplayRole) + { + OstProto::PortStats stats; + + stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx]->getStats(); + + switch(row) + { + // States + case e_LINK_STATE: + return LinkStateName.at(stats.state().link_state()); + + case e_TRANSMIT_STATE: + return BoolStateName.at(stats.state().is_transmit_on()); + + case e_CAPTURE_STATE: + return BoolStateName.at(stats.state().is_capture_on()); + + // Statistics + case e_STAT_FRAMES_RCVD: + return stats.rx_pkts(); + + case e_STAT_FRAMES_SENT: + return stats.tx_pkts(); + + case e_STAT_FRAME_SEND_RATE: + return stats.tx_pps(); + + case e_STAT_FRAME_RECV_RATE: + return stats.rx_pps(); + + case e_STAT_BYTES_RCVD: + return stats.rx_bytes(); + + case e_STAT_BYTES_SENT: + return stats.tx_bytes(); + + case e_STAT_BYTE_SEND_RATE: + return stats.tx_bps(); + + case e_STAT_BYTE_RECV_RATE: + return stats.rx_bps(); + +#if 0 + case e_STAT_FRAMES_RCVD_NIC: + return stats.rx_pkts_nic(); + + case e_STAT_FRAMES_SENT_NIC: + return stats.tx_pkts_nic(); + + case e_STAT_BYTES_RCVD_NIC: + return stats.rx_bytes_nic(); + + case e_STAT_BYTES_SENT_NIC: + return stats.tx_bytes_nic(); +#endif + default: + qWarning("%s: Unhandled stats id %d\n", __FUNCTION__, + index.row()); + return 0; + } + } + else if (role == Qt::TextAlignmentRole) + { + if (row >= e_STATE_START && row <= e_STATE_END) + return Qt::AlignHCenter; + else if (row >= e_STATISTICS_START && row <= e_STATISTICS_END) + return Qt::AlignRight; + else + return QVariant(); + } + else + return QVariant(); + +} + +QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ +#ifdef Q_OS_WIN32 + // TODO(MED): The limitations should be the server's not the client's! + // Ideally we shd enhance the protocol to convey limitation(s), if any, + // from server to client + if (role == Qt::ToolTipRole) + { + if (orientation == Qt::Horizontal) + { + return QString("Limitation(s)" + "

Frames/Bytes Receieved: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
" + "Frames/Bytes Sent: Only Ostinato Tx pkts (Tx by others NOT included)

" + "

Rx/Tx Rates are derived from the above and hence subject to same limitations

" + ); + } + else + return QVariant(); + } +#endif + + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + { + uint portGroupIdx, portIdx; + + getDomainIndexes(index(0, section), portGroupIdx, portIdx); +#ifdef Q_OS_WIN32 + return QString("Port %1-%2 (*)").arg(portGroupIdx).arg(portIdx); +#else + return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx); +#endif + } + else + return PortStatName.at(section); +} + +void PortStatsModel::portListFromIndex(QModelIndexList indices, + QList &portList) +{ + int i, j; + QModelIndexList selectedCols(indices); + + portList.clear(); + + //selectedCols = indices.selectedColumns(); + for (i = 0; i < selectedCols.size(); i++) + { + uint portGroupIdx, portIdx; + + getDomainIndexes(selectedCols.at(i), portGroupIdx, portIdx); + for (j = 0; j < portList.size(); j++) + { + if (portList[j].portGroupId == portGroupIdx) + break; + } + + if (j >= portList.size()) + { + // PortGroup Not found + PortGroupAndPortList p; + + p.portGroupId = portGroupIdx; + p.portList.append(portIdx); + + portList.append(p); + } + else + { + // PortGroup found + + portList[j].portList.append(portIdx); + } + } +} + +// +// Slots +// +void PortStatsModel::when_portListChanged() +{ + int i, count = 0; + + // recalc numPorts + while (numPorts.size()) + numPorts.removeFirst(); + + for (i = 0; i < pgl->mPortGroups.size(); i++) + { + count += pgl->mPortGroups.at(i)->numPorts(); + numPorts.append(count); + } + + reset(); +} + +void PortStatsModel::on_portStatsUpdate(int port, void*stats) +{ + QModelIndex topLeft = index(port, 0, QModelIndex()); + QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex()); + + emit dataChanged(topLeft, bottomRight); +} + +void PortStatsModel::updateStats() +{ + // Request each portgroup to fetch updated stats - the port group + // raises a signal once updated stats are available + for (int i = 0; i < pgl->mPortGroups.size(); i++) + pgl->mPortGroups[i]->getPortStats(); +} + +void PortStatsModel::when_portGroup_stats_update(quint32 portGroupId) +{ + // FIXME(MED): update only the changed ports, not all + + QModelIndex topLeft = index(0, 0, QModelIndex()); + QModelIndex bottomRight = index(rowCount(), columnCount(), QModelIndex()); + + emit dataChanged(topLeft, bottomRight); +} diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h index e253e22..3baa7c2 100644 --- a/client/portstatsmodel.h +++ b/client/portstatsmodel.h @@ -1,117 +1,117 @@ -#ifndef _PORT_STATS_MODEL_H -#define _PORT_STATS_MODEL_H - -#include -#include - -typedef enum { - // State - e_STATE_START = 0, - - e_LINK_STATE = e_STATE_START, - e_TRANSMIT_STATE, - e_CAPTURE_STATE, - - e_STATE_END = e_CAPTURE_STATE, - - // Statistics - e_STATISTICS_START, - - e_STAT_FRAMES_RCVD = e_STATISTICS_START, - e_STAT_FRAMES_SENT, - e_STAT_FRAME_SEND_RATE, - e_STAT_FRAME_RECV_RATE, - e_STAT_BYTES_RCVD, - e_STAT_BYTES_SENT, - e_STAT_BYTE_SEND_RATE, - e_STAT_BYTE_RECV_RATE, -#if 0 - e_STAT_FRAMES_RCVD_NIC, - e_STAT_FRAMES_SENT_NIC, - e_STAT_BYTES_RCVD_NIC, - e_STAT_BYTES_SENT_NIC, -#endif - - e_STATISTICS_END = e_STAT_BYTE_RECV_RATE, - - e_STAT_MAX -} PortStat; - -static QStringList PortStatName = (QStringList() - << "Link State" - << "Transmit State" - << "Capture State" - - << "Frames Received" - << "Frames Sent" - << "Frame Send Rate (fps)" - << "Frame Receive Rate (fps)" - << "Bytes Received" - << "Bytes Sent" - << "Byte Send Rate (Bps)" - << "Byte Receive Rate (Bps)" -#if 0 - << "Frames Received (NIC)" - << "Frames Sent (NIC)" - << "Bytes Received (NIC)" - << "Bytes Sent (NIC)" -#endif -); - -static QStringList LinkStateName = (QStringList() - << "Unknown" - << "Down" - << "Up" -); - -static QStringList BoolStateName = (QStringList() - << "Off" - << "On" -); - -class PortGroupList; - -class PortStatsModel : public QAbstractTableModel -{ - Q_OBJECT - - public: - - PortStatsModel(PortGroupList *p, QObject *parent = 0); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - - class PortGroupAndPortList { - public: - uint portGroupId; - QList portList; - }; - void portListFromIndex(QModelIndexList indices, - QList &portList); - - public slots: - void when_portListChanged(); - void on_portStatsUpdate(int port, void*stats); - void when_portGroup_stats_update(quint32 portGroupId); - - private slots: - void updateStats(); - - private: - PortGroupList *pgl; - - // numPorts stores the num of ports per portgroup - // in the same order as the portgroups are index in the pgl - // Also it stores them as cumulative totals - QList numPorts; - - void getDomainIndexes(const QModelIndex &index, - uint &portGroupIdx, uint &portIdx) const; - -}; - -#endif +#ifndef _PORT_STATS_MODEL_H +#define _PORT_STATS_MODEL_H + +#include +#include + +typedef enum { + // State + e_STATE_START = 0, + + e_LINK_STATE = e_STATE_START, + e_TRANSMIT_STATE, + e_CAPTURE_STATE, + + e_STATE_END = e_CAPTURE_STATE, + + // Statistics + e_STATISTICS_START, + + e_STAT_FRAMES_RCVD = e_STATISTICS_START, + e_STAT_FRAMES_SENT, + e_STAT_FRAME_SEND_RATE, + e_STAT_FRAME_RECV_RATE, + e_STAT_BYTES_RCVD, + e_STAT_BYTES_SENT, + e_STAT_BYTE_SEND_RATE, + e_STAT_BYTE_RECV_RATE, +#if 0 + e_STAT_FRAMES_RCVD_NIC, + e_STAT_FRAMES_SENT_NIC, + e_STAT_BYTES_RCVD_NIC, + e_STAT_BYTES_SENT_NIC, +#endif + + e_STATISTICS_END = e_STAT_BYTE_RECV_RATE, + + e_STAT_MAX +} PortStat; + +static QStringList PortStatName = (QStringList() + << "Link State" + << "Transmit State" + << "Capture State" + + << "Frames Received" + << "Frames Sent" + << "Frame Send Rate (fps)" + << "Frame Receive Rate (fps)" + << "Bytes Received" + << "Bytes Sent" + << "Byte Send Rate (Bps)" + << "Byte Receive Rate (Bps)" +#if 0 + << "Frames Received (NIC)" + << "Frames Sent (NIC)" + << "Bytes Received (NIC)" + << "Bytes Sent (NIC)" +#endif +); + +static QStringList LinkStateName = (QStringList() + << "Unknown" + << "Down" + << "Up" +); + +static QStringList BoolStateName = (QStringList() + << "Off" + << "On" +); + +class PortGroupList; + +class PortStatsModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + + PortStatsModel(PortGroupList *p, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + class PortGroupAndPortList { + public: + uint portGroupId; + QList portList; + }; + void portListFromIndex(QModelIndexList indices, + QList &portList); + + public slots: + void when_portListChanged(); + void on_portStatsUpdate(int port, void*stats); + void when_portGroup_stats_update(quint32 portGroupId); + + private slots: + void updateStats(); + + private: + PortGroupList *pgl; + + // numPorts stores the num of ports per portgroup + // in the same order as the portgroups are index in the pgl + // Also it stores them as cumulative totals + QList numPorts; + + void getDomainIndexes(const QModelIndex &index, + uint &portGroupIdx, uint &portIdx) const; + +}; + +#endif diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index c10834d..9b8b224 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -1,161 +1,161 @@ - -#include "portstatswindow.h" -#include "portstatsmodel.h" -#include "portstatsfilterdialog.h" - -#include "QHeaderView" - -PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent) - : QWidget(parent) -{ - setupUi(this); - - this->pgl = pgl; - model = pgl->getPortStatsModel(); - tvPortStats->setModel(model); - - tvPortStats->verticalHeader()->setHighlightSections(false); - tvPortStats->verticalHeader()->setDefaultSectionSize( - tvPortStats->verticalHeader()->minimumSectionSize()); - -} - -PortStatsWindow::~PortStatsWindow() -{ -} - -/* ------------- SLOTS -------------- */ - -void PortStatsWindow::on_tbStartTransmit_clicked() -{ - QList pgpl; - - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); - - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - startTx(&pgpl[i].portList); - } -} - -void PortStatsWindow::on_tbStopTransmit_clicked() -{ - QList pgpl; - - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); - - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - stopTx(&pgpl[i].portList); - } -} - -void PortStatsWindow::on_tbStartCapture_clicked() -{ - // TODO(MED) - QList pgpl; - - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); - - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - startCapture(&pgpl[i].portList); - } -} - -void PortStatsWindow::on_tbStopCapture_clicked() -{ - // TODO(MED) - QList pgpl; - - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); - - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - stopCapture(&pgpl[i].portList); - } -} - -void PortStatsWindow::on_tbViewCapture_clicked() -{ - // TODO(MED) - QList pgpl; - - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - pgpl); - - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < pgpl.size(); i++) - { - pgl->portGroupByIndex(pgpl.at(i).portGroupId). - viewCapture(&pgpl[i].portList); - } -} - -void PortStatsWindow::on_tbClear_clicked() -{ - QList portList; - - // Get selected ports - model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), - portList); - - // Clear selected ports, portgroup by portgroup - for (int i = 0; i < portList.size(); i++) - { - pgl->portGroupByIndex(portList.at(i).portGroupId). - clearPortStats(&portList[i].portList); - } -} - -void PortStatsWindow::on_tbClearAll_clicked() -{ - for (int i = 0; i < pgl->numPortGroups(); i++) - { - pgl->portGroupByIndex(0).clearPortStats(); - } -} - -void PortStatsWindow::on_tbFilter_clicked() -{ - bool ok; - QList currentColumns, newColumns; - PortStatsFilterDialog dialog; - - for(int i = 0; i < model->columnCount(); i++) - if (!tvPortStats->isColumnHidden(i)) - currentColumns.append(i); - - newColumns = dialog.getItemList(&ok, model, Qt::Horizontal, currentColumns); - - if (ok) - { - // hide/show sections first ... - for(int i = 0; i < model->columnCount(); i++) - tvPortStats->setColumnHidden(i, !newColumns.contains(i)); - - // ... then for the 'shown' columns, set the visual index - for(int i = 0; i < newColumns.size(); i++) - { - tvPortStats->horizontalHeader()->moveSection(tvPortStats-> - horizontalHeader()->visualIndex(newColumns.at(i)), i); - } - } -} + +#include "portstatswindow.h" +#include "portstatsmodel.h" +#include "portstatsfilterdialog.h" + +#include "QHeaderView" + +PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + this->pgl = pgl; + model = pgl->getPortStatsModel(); + tvPortStats->setModel(model); + + tvPortStats->verticalHeader()->setHighlightSections(false); + tvPortStats->verticalHeader()->setDefaultSectionSize( + tvPortStats->verticalHeader()->minimumSectionSize()); + +} + +PortStatsWindow::~PortStatsWindow() +{ +} + +/* ------------- SLOTS -------------- */ + +void PortStatsWindow::on_tbStartTransmit_clicked() +{ + QList pgpl; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + startTx(&pgpl[i].portList); + } +} + +void PortStatsWindow::on_tbStopTransmit_clicked() +{ + QList pgpl; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + stopTx(&pgpl[i].portList); + } +} + +void PortStatsWindow::on_tbStartCapture_clicked() +{ + // TODO(MED) + QList pgpl; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + startCapture(&pgpl[i].portList); + } +} + +void PortStatsWindow::on_tbStopCapture_clicked() +{ + // TODO(MED) + QList pgpl; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + stopCapture(&pgpl[i].portList); + } +} + +void PortStatsWindow::on_tbViewCapture_clicked() +{ + // TODO(MED) + QList pgpl; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + pgpl); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < pgpl.size(); i++) + { + pgl->portGroupByIndex(pgpl.at(i).portGroupId). + viewCapture(&pgpl[i].portList); + } +} + +void PortStatsWindow::on_tbClear_clicked() +{ + QList portList; + + // Get selected ports + model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(), + portList); + + // Clear selected ports, portgroup by portgroup + for (int i = 0; i < portList.size(); i++) + { + pgl->portGroupByIndex(portList.at(i).portGroupId). + clearPortStats(&portList[i].portList); + } +} + +void PortStatsWindow::on_tbClearAll_clicked() +{ + for (int i = 0; i < pgl->numPortGroups(); i++) + { + pgl->portGroupByIndex(0).clearPortStats(); + } +} + +void PortStatsWindow::on_tbFilter_clicked() +{ + bool ok; + QList currentColumns, newColumns; + PortStatsFilterDialog dialog; + + for(int i = 0; i < model->columnCount(); i++) + if (!tvPortStats->isColumnHidden(i)) + currentColumns.append(i); + + newColumns = dialog.getItemList(&ok, model, Qt::Horizontal, currentColumns); + + if (ok) + { + // hide/show sections first ... + for(int i = 0; i < model->columnCount(); i++) + tvPortStats->setColumnHidden(i, !newColumns.contains(i)); + + // ... then for the 'shown' columns, set the visual index + for(int i = 0; i < newColumns.size(); i++) + { + tvPortStats->horizontalHeader()->moveSection(tvPortStats-> + horizontalHeader()->visualIndex(newColumns.at(i)), i); + } + } +} diff --git a/client/portstatswindow.h b/client/portstatswindow.h index a390446..b2ad6f2 100644 --- a/client/portstatswindow.h +++ b/client/portstatswindow.h @@ -1,37 +1,37 @@ -#ifndef _PORT_STATS_WINDOW_H -#define _PORT_STATS_WINDOW_H - -#include -#include -#include "ui_portstatswindow.h" -#include "portgrouplist.h" -#include "portstatsmodel.h" - -class PortStatsWindow : public QWidget, public Ui::PortStatsWindow -{ - Q_OBJECT - -public: - PortStatsWindow(PortGroupList *pgl, QWidget *parent = 0); - ~PortStatsWindow(); - -private: - PortGroupList *pgl; - PortStatsModel *model; - -private slots: - void on_tbStartTransmit_clicked(); - void on_tbStopTransmit_clicked(); - - void on_tbStartCapture_clicked(); - void on_tbStopCapture_clicked(); - void on_tbViewCapture_clicked(); - - void on_tbClear_clicked(); - void on_tbClearAll_clicked(); - - void on_tbFilter_clicked(); -}; - -#endif - +#ifndef _PORT_STATS_WINDOW_H +#define _PORT_STATS_WINDOW_H + +#include +#include +#include "ui_portstatswindow.h" +#include "portgrouplist.h" +#include "portstatsmodel.h" + +class PortStatsWindow : public QWidget, public Ui::PortStatsWindow +{ + Q_OBJECT + +public: + PortStatsWindow(PortGroupList *pgl, QWidget *parent = 0); + ~PortStatsWindow(); + +private: + PortGroupList *pgl; + PortStatsModel *model; + +private slots: + void on_tbStartTransmit_clicked(); + void on_tbStopTransmit_clicked(); + + void on_tbStartCapture_clicked(); + void on_tbStopCapture_clicked(); + void on_tbViewCapture_clicked(); + + void on_tbClear_clicked(); + void on_tbClearAll_clicked(); + + void on_tbFilter_clicked(); +}; + +#endif + diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 23684db..c8dd179 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -1,416 +1,416 @@ -#include "portswindow.h" -#include "streamlistdelegate.h" -#include "streamconfigdialog.h" -#include -#include - -PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) -{ - StreamListDelegate *delegate = new StreamListDelegate; - //slm = new StreamListModel(); - //plm = new PortGroupList(); - plm = pgl; - - setupUi(this); - - tvStreamList->setItemDelegate(delegate); - - tvStreamList->verticalHeader()->setDefaultSectionSize( - tvStreamList->verticalHeader()->minimumSectionSize()); - - // Populate Context Menu Actions - tvPortList->addAction(actionNew_Port_Group); - tvPortList->addAction(actionDelete_Port_Group); - tvPortList->addAction(actionConnect_Port_Group); - tvPortList->addAction(actionDisconnect_Port_Group); - - tvStreamList->addAction(actionNew_Stream); - tvStreamList->addAction(actionEdit_Stream); - tvStreamList->addAction(actionDelete_Stream); - - tvStreamList->setModel(plm->getStreamModel()); - tvPortList->setModel(plm->getPortModel()); - - connect( plm->getPortModel(), - SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(when_portModel_dataChanged(const QModelIndex&, - const QModelIndex&))); - - connect(plm->getPortModel(), SIGNAL(modelReset()), - SLOT(when_portModel_reset())); - - connect( tvPortList->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(when_portView_currentChanged(const QModelIndex&, - const QModelIndex&))); - - connect( tvStreamList->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(when_streamView_currentChanged(const QModelIndex&, - const QModelIndex&))); - connect( tvStreamList->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, SLOT(when_streamView_selectionChanged())); - -#if 0 - connect( tvPortList->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&))); -#endif - - tvStreamList->resizeColumnToContents(StreamModel::StreamIcon); - tvStreamList->resizeColumnToContents(StreamModel::StreamStatus); - - // Initially we don't have any ports/streams - so send signal triggers - when_portView_currentChanged(QModelIndex(), QModelIndex()); - when_streamView_currentChanged(QModelIndex(), QModelIndex()); - - //! \todo Hide the Aggregate Box till we add support - frAggregate->setHidden(true); -} - -PortsWindow::~PortsWindow() -{ -} - -void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) -{ - StreamConfigDialog *scd; - - if (!index.isValid()) - { - qDebug("%s: invalid index", __FUNCTION__); - return; - } - scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()), - index.row(), this); - qDebug("stream list activated\n"); - scd->exec(); // TODO: chk retval - delete scd; -} - -void PortsWindow::when_portView_currentChanged(const QModelIndex& current, - const QModelIndex& previous) -{ - plm->getStreamModel()->setCurrentPortIndex(current); - updatePortViewActions(current); - updateStreamViewActions(); - - if (!current.isValid()) - { - qDebug("setting stacked widget to blank page"); - swDetail->setCurrentIndex(2); // blank page - } - else - { - if (plm->isPortGroup(current)) - { - swDetail->setCurrentIndex(1); // portGroup detail page - } - else if (plm->isPort(current)) - { - swDetail->setCurrentIndex(0); // port detail page - } - } -} - -void PortsWindow::when_streamView_currentChanged(const QModelIndex& current, - const QModelIndex& previous) -{ - qDebug("stream view current changed"); - updateStreamViewActions(); -} - -void PortsWindow::when_streamView_selectionChanged() -{ - qDebug("stream view selection changed"); - updateStreamViewActions(); -} - -void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft, - const QModelIndex& bottomRight) -{ -#if 0 // not sure why the >= <= operators are not overloaded in QModelIndex - if ((tvPortList->currentIndex() >= topLeft) && - (tvPortList->currentIndex() <= bottomRight)) -#endif - if ((topLeft < tvPortList->currentIndex()) || - (topLeft == tvPortList->currentIndex()) && - ((tvPortList->currentIndex() < bottomRight)) || - (tvPortList->currentIndex() == bottomRight)) - { - updatePortViewActions(tvPortList->currentIndex()); - } -} - -void PortsWindow::when_portModel_reset() -{ - when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex()); -} - -#if 0 -void PortsWindow::updateStreamViewActions(const QModelIndex& current) -{ - if (current.isValid()) - actionDelete_Stream->setEnabled(true); - else - actionDelete_Stream->setDisabled(true); -} -#endif - -void PortsWindow::updateStreamViewActions() -{ - // For some reason hasSelection() returns true even if selection size is 0 - // so additional check for size introduced - if (tvStreamList->selectionModel()->hasSelection() && - (tvStreamList->selectionModel()->selection().size() > 0)) - { - qDebug("Has selection %d", - tvStreamList->selectionModel()->selection().size()); - - // If more than one non-contiguous ranges selected, - // disable "New" and "Edit" - if (tvStreamList->selectionModel()->selection().size() > 1) - { - actionNew_Stream->setDisabled(true); - actionEdit_Stream->setDisabled(true); - } - else - { - actionNew_Stream->setEnabled(true); - - // Enable "Edit" only if the single range has a single row - if (tvStreamList->selectionModel()->selection().at(0).height() > 1) - actionEdit_Stream->setDisabled(true); - else - actionEdit_Stream->setEnabled(true); - } - - // Delete is always enabled as long as we have a selection - actionDelete_Stream->setEnabled(true); - } - else - { - qDebug("No selection"); - actionNew_Stream->setEnabled(true); - actionEdit_Stream->setDisabled(true); - actionDelete_Stream->setDisabled(true); - } -} - -void PortsWindow::updatePortViewActions(const QModelIndex& current) -{ - if (!current.isValid()) - { - qDebug("current is now invalid"); - actionDelete_Port_Group->setDisabled(true); - actionConnect_Port_Group->setDisabled(true); - actionDisconnect_Port_Group->setDisabled(true); - - goto _EXIT; - } - - qDebug("currentChanged %llx", current.internalId()); - - if (plm->isPortGroup(current)) - { - actionDelete_Port_Group->setEnabled(true); - switch(plm->portGroup(current).state()) - { - case QAbstractSocket::UnconnectedState: - case QAbstractSocket::ClosingState: - qDebug("state = unconnected|closing"); - actionConnect_Port_Group->setEnabled(true); - actionDisconnect_Port_Group->setDisabled(true); - break; - - case QAbstractSocket::HostLookupState: - case QAbstractSocket::ConnectingState: - case QAbstractSocket::ConnectedState: - qDebug("state = lookup|connecting|connected"); - actionConnect_Port_Group->setDisabled(true); - actionDisconnect_Port_Group->setEnabled(true); - break; - - - case QAbstractSocket::BoundState: - case QAbstractSocket::ListeningState: - default: - // FIXME(LOW): indicate error - qDebug("unexpected state"); - break; - } - } - else if (plm->isPort(current)) - { - actionDelete_Port_Group->setEnabled(false); - actionConnect_Port_Group->setEnabled(false); - actionDisconnect_Port_Group->setEnabled(false); - } - -_EXIT: - return; -} - -void PortsWindow::on_pbApply_clicked() -{ - QModelIndex curPort; - QModelIndex curPortGroup; - - curPort = tvPortList->selectionModel()->currentIndex(); - if (!curPort.isValid()) - { - qDebug("%s: curPort is invalid", __FUNCTION__); - goto _exit; - } - - if (!plm->isPort(curPort)) - { - qDebug("%s: curPort is not a port", __FUNCTION__); - goto _exit; - } - - curPortGroup = plm->getPortModel()->parent(curPort); - if (!curPortGroup.isValid()) - { - qDebug("%s: curPortGroup is invalid", __FUNCTION__); - goto _exit; - } - if (!plm->isPortGroup(curPortGroup)) - { - qDebug("%s: curPortGroup is not a portGroup", __FUNCTION__); - goto _exit; - } - - // FIXME(HI): shd this be a signal? - //portGroup.when_configApply(port); - // FIXME(MED): mixing port id and index!!! - plm->portGroup(curPortGroup).when_configApply(plm->port(curPort).id()); - -_exit: - return; - -#if 0 - // TODO (LOW): This block is for testing only - QModelIndex current = tvPortList->selectionModel()->currentIndex(); - - if (current.isValid()) - qDebug("current = %llx", current.internalId()); - else - qDebug("current is invalid"); -#endif -} - -void PortsWindow::on_actionNew_Port_Group_triggered() -{ - bool ok; - QString text = QInputDialog::getText(this, - "Add Port Group", "Port Group Address (IP[:Port])", - QLineEdit::Normal, lastNewPortGroup, &ok); - - if (ok) - { - QStringList addr = text.split(":"); - if (addr.size() == 1) // Port unspecified - addr.append(QString().setNum(DEFAULT_SERVER_PORT)); - PortGroup *pg = new PortGroup(QHostAddress(addr[0]),addr[1].toUShort()); - plm->addPortGroup(*pg); - lastNewPortGroup = text; - } -} - -void PortsWindow::on_actionDelete_Port_Group_triggered() -{ - QModelIndex current = tvPortList->selectionModel()->currentIndex(); - - if (current.isValid()) - plm->removePortGroup(plm->portGroup(current)); -} - -void PortsWindow::on_actionConnect_Port_Group_triggered() -{ - QModelIndex current = tvPortList->selectionModel()->currentIndex(); - - if (current.isValid()) - plm->portGroup(current).connectToHost(); -} - -void PortsWindow::on_actionDisconnect_Port_Group_triggered() -{ - QModelIndex current = tvPortList->selectionModel()->currentIndex(); - - if (current.isValid()) - plm->portGroup(current).disconnectFromHost(); -} -#if 0 -void PortsWindow::on_actionNew_Stream_triggered() -{ - qDebug("New Stream Action"); - - int row = 0; - - if (tvStreamList->currentIndex().isValid()) - row = tvStreamList->currentIndex().row(); - plm->getStreamModel()->insertRows(row, 1); -} - -void PortsWindow::on_actionDelete_Stream_triggered() -{ - qDebug("Delete Stream Action"); - if (tvStreamList->currentIndex().isValid()) - plm->getStreamModel()->removeRows(tvStreamList->currentIndex().row(), 1); -} -#endif - -void PortsWindow::on_actionNew_Stream_triggered() -{ - qDebug("New Stream Action"); - - // In case nothing is selected, insert 1 row at the top - int row = 0, count = 1; - - // In case we have a single range selected; insert as many rows as - // in the singe selected range before the top of the selected range - if (tvStreamList->selectionModel()->selection().size() == 1) - { - row = tvStreamList->selectionModel()->selection().at(0).top(); - count = tvStreamList->selectionModel()->selection().at(0).height(); - } - - plm->getStreamModel()->insertRows(row, count); -} - -void PortsWindow::on_actionEdit_Stream_triggered() -{ - qDebug("Edit Stream Action"); - - // Ensure we have only one range selected which contains only one row - if ((tvStreamList->selectionModel()->selection().size() == 1) && - (tvStreamList->selectionModel()->selection().at(0).height() == 1)) - { - on_tvStreamList_activated(tvStreamList->selectionModel()-> - selection().at(0).topLeft()); - } -} - -void PortsWindow::on_actionDelete_Stream_triggered() -{ - qDebug("Delete Stream Action"); - - QModelIndex index; - - if (tvStreamList->selectionModel()->hasSelection()) - { - qDebug("SelectedIndexes %d", - tvStreamList->selectionModel()->selectedRows().size()); - while(tvStreamList->selectionModel()->selectedRows().size()) - { - index = tvStreamList->selectionModel()->selectedRows().at(0); - plm->getStreamModel()->removeRows(index.row(), 1); - } - } - else - qDebug("No selection"); -} - - +#include "portswindow.h" +#include "streamlistdelegate.h" +#include "streamconfigdialog.h" +#include +#include + +PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) +{ + StreamListDelegate *delegate = new StreamListDelegate; + //slm = new StreamListModel(); + //plm = new PortGroupList(); + plm = pgl; + + setupUi(this); + + tvStreamList->setItemDelegate(delegate); + + tvStreamList->verticalHeader()->setDefaultSectionSize( + tvStreamList->verticalHeader()->minimumSectionSize()); + + // Populate Context Menu Actions + tvPortList->addAction(actionNew_Port_Group); + tvPortList->addAction(actionDelete_Port_Group); + tvPortList->addAction(actionConnect_Port_Group); + tvPortList->addAction(actionDisconnect_Port_Group); + + tvStreamList->addAction(actionNew_Stream); + tvStreamList->addAction(actionEdit_Stream); + tvStreamList->addAction(actionDelete_Stream); + + tvStreamList->setModel(plm->getStreamModel()); + tvPortList->setModel(plm->getPortModel()); + + connect( plm->getPortModel(), + SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_portModel_dataChanged(const QModelIndex&, + const QModelIndex&))); + + connect(plm->getPortModel(), SIGNAL(modelReset()), + SLOT(when_portModel_reset())); + + connect( tvPortList->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_portView_currentChanged(const QModelIndex&, + const QModelIndex&))); + + connect( tvStreamList->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_streamView_currentChanged(const QModelIndex&, + const QModelIndex&))); + connect( tvStreamList->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, SLOT(when_streamView_selectionChanged())); + +#if 0 + connect( tvPortList->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&))); +#endif + + tvStreamList->resizeColumnToContents(StreamModel::StreamIcon); + tvStreamList->resizeColumnToContents(StreamModel::StreamStatus); + + // Initially we don't have any ports/streams - so send signal triggers + when_portView_currentChanged(QModelIndex(), QModelIndex()); + when_streamView_currentChanged(QModelIndex(), QModelIndex()); + + //! \todo Hide the Aggregate Box till we add support + frAggregate->setHidden(true); +} + +PortsWindow::~PortsWindow() +{ +} + +void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) +{ + StreamConfigDialog *scd; + + if (!index.isValid()) + { + qDebug("%s: invalid index", __FUNCTION__); + return; + } + scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()), + index.row(), this); + qDebug("stream list activated\n"); + scd->exec(); // TODO: chk retval + delete scd; +} + +void PortsWindow::when_portView_currentChanged(const QModelIndex& current, + const QModelIndex& previous) +{ + plm->getStreamModel()->setCurrentPortIndex(current); + updatePortViewActions(current); + updateStreamViewActions(); + + if (!current.isValid()) + { + qDebug("setting stacked widget to blank page"); + swDetail->setCurrentIndex(2); // blank page + } + else + { + if (plm->isPortGroup(current)) + { + swDetail->setCurrentIndex(1); // portGroup detail page + } + else if (plm->isPort(current)) + { + swDetail->setCurrentIndex(0); // port detail page + } + } +} + +void PortsWindow::when_streamView_currentChanged(const QModelIndex& current, + const QModelIndex& previous) +{ + qDebug("stream view current changed"); + updateStreamViewActions(); +} + +void PortsWindow::when_streamView_selectionChanged() +{ + qDebug("stream view selection changed"); + updateStreamViewActions(); +} + +void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ +#if 0 // not sure why the >= <= operators are not overloaded in QModelIndex + if ((tvPortList->currentIndex() >= topLeft) && + (tvPortList->currentIndex() <= bottomRight)) +#endif + if ((topLeft < tvPortList->currentIndex()) || + (topLeft == tvPortList->currentIndex()) && + ((tvPortList->currentIndex() < bottomRight)) || + (tvPortList->currentIndex() == bottomRight)) + { + updatePortViewActions(tvPortList->currentIndex()); + } +} + +void PortsWindow::when_portModel_reset() +{ + when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex()); +} + +#if 0 +void PortsWindow::updateStreamViewActions(const QModelIndex& current) +{ + if (current.isValid()) + actionDelete_Stream->setEnabled(true); + else + actionDelete_Stream->setDisabled(true); +} +#endif + +void PortsWindow::updateStreamViewActions() +{ + // For some reason hasSelection() returns true even if selection size is 0 + // so additional check for size introduced + if (tvStreamList->selectionModel()->hasSelection() && + (tvStreamList->selectionModel()->selection().size() > 0)) + { + qDebug("Has selection %d", + tvStreamList->selectionModel()->selection().size()); + + // If more than one non-contiguous ranges selected, + // disable "New" and "Edit" + if (tvStreamList->selectionModel()->selection().size() > 1) + { + actionNew_Stream->setDisabled(true); + actionEdit_Stream->setDisabled(true); + } + else + { + actionNew_Stream->setEnabled(true); + + // Enable "Edit" only if the single range has a single row + if (tvStreamList->selectionModel()->selection().at(0).height() > 1) + actionEdit_Stream->setDisabled(true); + else + actionEdit_Stream->setEnabled(true); + } + + // Delete is always enabled as long as we have a selection + actionDelete_Stream->setEnabled(true); + } + else + { + qDebug("No selection"); + actionNew_Stream->setEnabled(true); + actionEdit_Stream->setDisabled(true); + actionDelete_Stream->setDisabled(true); + } +} + +void PortsWindow::updatePortViewActions(const QModelIndex& current) +{ + if (!current.isValid()) + { + qDebug("current is now invalid"); + actionDelete_Port_Group->setDisabled(true); + actionConnect_Port_Group->setDisabled(true); + actionDisconnect_Port_Group->setDisabled(true); + + goto _EXIT; + } + + qDebug("currentChanged %llx", current.internalId()); + + if (plm->isPortGroup(current)) + { + actionDelete_Port_Group->setEnabled(true); + switch(plm->portGroup(current).state()) + { + case QAbstractSocket::UnconnectedState: + case QAbstractSocket::ClosingState: + qDebug("state = unconnected|closing"); + actionConnect_Port_Group->setEnabled(true); + actionDisconnect_Port_Group->setDisabled(true); + break; + + case QAbstractSocket::HostLookupState: + case QAbstractSocket::ConnectingState: + case QAbstractSocket::ConnectedState: + qDebug("state = lookup|connecting|connected"); + actionConnect_Port_Group->setDisabled(true); + actionDisconnect_Port_Group->setEnabled(true); + break; + + + case QAbstractSocket::BoundState: + case QAbstractSocket::ListeningState: + default: + // FIXME(LOW): indicate error + qDebug("unexpected state"); + break; + } + } + else if (plm->isPort(current)) + { + actionDelete_Port_Group->setEnabled(false); + actionConnect_Port_Group->setEnabled(false); + actionDisconnect_Port_Group->setEnabled(false); + } + +_EXIT: + return; +} + +void PortsWindow::on_pbApply_clicked() +{ + QModelIndex curPort; + QModelIndex curPortGroup; + + curPort = tvPortList->selectionModel()->currentIndex(); + if (!curPort.isValid()) + { + qDebug("%s: curPort is invalid", __FUNCTION__); + goto _exit; + } + + if (!plm->isPort(curPort)) + { + qDebug("%s: curPort is not a port", __FUNCTION__); + goto _exit; + } + + curPortGroup = plm->getPortModel()->parent(curPort); + if (!curPortGroup.isValid()) + { + qDebug("%s: curPortGroup is invalid", __FUNCTION__); + goto _exit; + } + if (!plm->isPortGroup(curPortGroup)) + { + qDebug("%s: curPortGroup is not a portGroup", __FUNCTION__); + goto _exit; + } + + // FIXME(HI): shd this be a signal? + //portGroup.when_configApply(port); + // FIXME(MED): mixing port id and index!!! + plm->portGroup(curPortGroup).when_configApply(plm->port(curPort).id()); + +_exit: + return; + +#if 0 + // TODO (LOW): This block is for testing only + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + + if (current.isValid()) + qDebug("current = %llx", current.internalId()); + else + qDebug("current is invalid"); +#endif +} + +void PortsWindow::on_actionNew_Port_Group_triggered() +{ + bool ok; + QString text = QInputDialog::getText(this, + "Add Port Group", "Port Group Address (IP[:Port])", + QLineEdit::Normal, lastNewPortGroup, &ok); + + if (ok) + { + QStringList addr = text.split(":"); + if (addr.size() == 1) // Port unspecified + addr.append(QString().setNum(DEFAULT_SERVER_PORT)); + PortGroup *pg = new PortGroup(QHostAddress(addr[0]),addr[1].toUShort()); + plm->addPortGroup(*pg); + lastNewPortGroup = text; + } +} + +void PortsWindow::on_actionDelete_Port_Group_triggered() +{ + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + + if (current.isValid()) + plm->removePortGroup(plm->portGroup(current)); +} + +void PortsWindow::on_actionConnect_Port_Group_triggered() +{ + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + + if (current.isValid()) + plm->portGroup(current).connectToHost(); +} + +void PortsWindow::on_actionDisconnect_Port_Group_triggered() +{ + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + + if (current.isValid()) + plm->portGroup(current).disconnectFromHost(); +} +#if 0 +void PortsWindow::on_actionNew_Stream_triggered() +{ + qDebug("New Stream Action"); + + int row = 0; + + if (tvStreamList->currentIndex().isValid()) + row = tvStreamList->currentIndex().row(); + plm->getStreamModel()->insertRows(row, 1); +} + +void PortsWindow::on_actionDelete_Stream_triggered() +{ + qDebug("Delete Stream Action"); + if (tvStreamList->currentIndex().isValid()) + plm->getStreamModel()->removeRows(tvStreamList->currentIndex().row(), 1); +} +#endif + +void PortsWindow::on_actionNew_Stream_triggered() +{ + qDebug("New Stream Action"); + + // In case nothing is selected, insert 1 row at the top + int row = 0, count = 1; + + // In case we have a single range selected; insert as many rows as + // in the singe selected range before the top of the selected range + if (tvStreamList->selectionModel()->selection().size() == 1) + { + row = tvStreamList->selectionModel()->selection().at(0).top(); + count = tvStreamList->selectionModel()->selection().at(0).height(); + } + + plm->getStreamModel()->insertRows(row, count); +} + +void PortsWindow::on_actionEdit_Stream_triggered() +{ + qDebug("Edit Stream Action"); + + // Ensure we have only one range selected which contains only one row + if ((tvStreamList->selectionModel()->selection().size() == 1) && + (tvStreamList->selectionModel()->selection().at(0).height() == 1)) + { + on_tvStreamList_activated(tvStreamList->selectionModel()-> + selection().at(0).topLeft()); + } +} + +void PortsWindow::on_actionDelete_Stream_triggered() +{ + qDebug("Delete Stream Action"); + + QModelIndex index; + + if (tvStreamList->selectionModel()->hasSelection()) + { + qDebug("SelectedIndexes %d", + tvStreamList->selectionModel()->selectedRows().size()); + while(tvStreamList->selectionModel()->selectedRows().size()) + { + index = tvStreamList->selectionModel()->selectedRows().at(0); + plm->getStreamModel()->removeRows(index.row(), 1); + } + } + else + qDebug("No selection"); +} + + diff --git a/client/portswindow.h b/client/portswindow.h index aec7216..c6db222 100644 --- a/client/portswindow.h +++ b/client/portswindow.h @@ -1,58 +1,58 @@ -#ifndef _PORTS_WINDOW_H -#define _PORTS_WINDOW_H - -#include -#include -#include "ui_portswindow.h" -#include "portgrouplist.h" - -/* TODO -HIGH -MED -LOW -*/ - - -class PortsWindow : public QWidget, private Ui::PortsWindow -{ - Q_OBJECT - - //QAbstractItemModel *slm; // stream list model - PortGroupList *plm; - -public: - PortsWindow(PortGroupList *pgl, QWidget *parent = 0); - ~PortsWindow(); - -private: - QString lastNewPortGroup; - - void updatePortViewActions(const QModelIndex& current); - //void updateStreamViewActions(const QModelIndex& current); - void updateStreamViewActions(); - -private slots: - void on_tvStreamList_activated(const QModelIndex & index); - void when_portView_currentChanged(const QModelIndex& current, - const QModelIndex& previous); - void when_streamView_currentChanged(const QModelIndex& current, - const QModelIndex& previous); - void when_streamView_selectionChanged(); - void when_portModel_dataChanged(const QModelIndex& topLeft, - const QModelIndex& bottomRight); - void when_portModel_reset(); - - void on_pbApply_clicked(); - - void on_actionNew_Port_Group_triggered(); - void on_actionDelete_Port_Group_triggered(); - void on_actionConnect_Port_Group_triggered(); - void on_actionDisconnect_Port_Group_triggered(); - - void on_actionNew_Stream_triggered(); - void on_actionEdit_Stream_triggered(); - void on_actionDelete_Stream_triggered(); -}; - -#endif - +#ifndef _PORTS_WINDOW_H +#define _PORTS_WINDOW_H + +#include +#include +#include "ui_portswindow.h" +#include "portgrouplist.h" + +/* TODO +HIGH +MED +LOW +*/ + + +class PortsWindow : public QWidget, private Ui::PortsWindow +{ + Q_OBJECT + + //QAbstractItemModel *slm; // stream list model + PortGroupList *plm; + +public: + PortsWindow(PortGroupList *pgl, QWidget *parent = 0); + ~PortsWindow(); + +private: + QString lastNewPortGroup; + + void updatePortViewActions(const QModelIndex& current); + //void updateStreamViewActions(const QModelIndex& current); + void updateStreamViewActions(); + +private slots: + void on_tvStreamList_activated(const QModelIndex & index); + void when_portView_currentChanged(const QModelIndex& current, + const QModelIndex& previous); + void when_streamView_currentChanged(const QModelIndex& current, + const QModelIndex& previous); + void when_streamView_selectionChanged(); + void when_portModel_dataChanged(const QModelIndex& topLeft, + const QModelIndex& bottomRight); + void when_portModel_reset(); + + void on_pbApply_clicked(); + + void on_actionNew_Port_Group_triggered(); + void on_actionDelete_Port_Group_triggered(); + void on_actionConnect_Port_Group_triggered(); + void on_actionDisconnect_Port_Group_triggered(); + + void on_actionNew_Stream_triggered(); + void on_actionEdit_Stream_triggered(); + void on_actionDelete_Stream_triggered(); +}; + +#endif + diff --git a/client/stream.cpp b/client/stream.cpp index 049d554..7d21b14 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -1,60 +1,60 @@ -#include -#include - -#include "stream.h" -//#include "../common/protocollist.h" -#include "../common/protocollistiterator.h" -#include "../common/abstractprotocol.h" - -Stream::Stream() -{ - //mId = 0xFFFFFFFF; - setEnabled(true); -} - -Stream::~Stream() -{ -} - -void Stream::loadProtocolWidgets() -{ -#if 0 - //protocols.loadConfigWidgets(); - foreach(AbstractProtocol* proto, *currentFrameProtocols) - { - proto->loadConfigWidget(); - } -#else - ProtocolListIterator *iter; - - iter = createProtocolListIterator(); - while (iter->hasNext()) - { - AbstractProtocol* p = iter->next(); - p->loadConfigWidget(); - } - delete iter; -#endif -} - -void Stream::storeProtocolWidgets() -{ -#if 0 - //protocols.storeConfigWidgets(); - foreach(const AbstractProtocol* proto, frameProtocol()) - { - proto->storeConfigWidget(); - _iter->toFront(); - } -#else - ProtocolListIterator *iter; - - iter = createProtocolListIterator(); - while (iter->hasNext()) - { - AbstractProtocol* p = iter->next(); - p->storeConfigWidget(); - } - delete iter; -#endif -} +#include +#include + +#include "stream.h" +//#include "../common/protocollist.h" +#include "../common/protocollistiterator.h" +#include "../common/abstractprotocol.h" + +Stream::Stream() +{ + //mId = 0xFFFFFFFF; + setEnabled(true); +} + +Stream::~Stream() +{ +} + +void Stream::loadProtocolWidgets() +{ +#if 0 + //protocols.loadConfigWidgets(); + foreach(AbstractProtocol* proto, *currentFrameProtocols) + { + proto->loadConfigWidget(); + } +#else + ProtocolListIterator *iter; + + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol* p = iter->next(); + p->loadConfigWidget(); + } + delete iter; +#endif +} + +void Stream::storeProtocolWidgets() +{ +#if 0 + //protocols.storeConfigWidgets(); + foreach(const AbstractProtocol* proto, frameProtocol()) + { + proto->storeConfigWidget(); + _iter->toFront(); + } +#else + ProtocolListIterator *iter; + + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol* p = iter->next(); + p->storeConfigWidget(); + } + delete iter; +#endif +} diff --git a/client/stream.h b/client/stream.h index 1b4e756..de7508d 100644 --- a/client/stream.h +++ b/client/stream.h @@ -1,23 +1,23 @@ -#ifndef _STREAM_H -#define _STREAM_H - -#include -#include -#include - -#include "../common/protocol.pb.h" -#include "../common/streambase.h" - -class Stream : public StreamBase { - - //quint32 mId; - -public: - Stream(); - ~Stream(); - - void loadProtocolWidgets(); - void storeProtocolWidgets(); -}; - -#endif +#ifndef _STREAM_H +#define _STREAM_H + +#include +#include +#include + +#include "../common/protocol.pb.h" +#include "../common/streambase.h" + +class Stream : public StreamBase { + + //quint32 mId; + +public: + Stream(); + ~Stream(); + + void loadProtocolWidgets(); + void storeProtocolWidgets(); +}; + +#endif diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index c6a950d..eb3da50 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -1,925 +1,925 @@ -#include - -#include "streamconfigdialog.h" -#include "stream.h" -#include "abstractprotocol.h" -#include "protocollistiterator.h" - -#include "modeltest.h" - -// FIXME(HI) - remove -#include "../common/protocolmanager.h" -extern ProtocolManager OstProtocolManager; - -int StreamConfigDialog::lastTopLevelTabIndex = 0; - -StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, - QWidget *parent) : QDialog (parent), mPort(port) -{ - OstProto::Stream s; - mCurrentStreamIndex = streamIndex; - mpStream = new Stream; - mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyInto(s); - mpStream->protoDataCopyFrom(s); - _iter = mpStream->createProtocolListIterator(); - isUpdateInProgress = false; - - setupUi(this); - setupUiExtra(); - - for (int i = ProtoMin; i < ProtoMax; i++) - { - bgProto[i]->setProperty("ProtocolLevel", i); - bgProto[i]->setProperty("ProtocolId", ButtonIdNone); - connect(bgProto[i], SIGNAL(buttonClicked(int)), - this, SLOT(updateProtocol(int))); - } - - //! \todo causes a crash! -#if 0 - connect(lePktLen, SIGNAL(textEdited(QString)), - this, SLOT(updateContents())); -#endif - - // Time to play match the signals and slots! - - // If L1/L2(FT)/L3 = None, force subsequent protocol level(s) also to None - connect(rbL1None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); - connect(rbFtNone, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); - connect(rbL3None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); - - // If L1/L2(FT)/L3/L4 = Other, force subsequent protocol to Other and - // disable the subsequent protocol group as well - connect(rbL1Other, SIGNAL(toggled(bool)), rbFtOther, SLOT(setChecked(bool))); - connect(rbL1Other, SIGNAL(toggled(bool)), gbFrameType, SLOT(setDisabled(bool))); - connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool))); - connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool))); - connect(rbL3Other, SIGNAL(toggled(bool)), rbL4Other, SLOT(setChecked(bool))); - connect(rbL3Other, SIGNAL(toggled(bool)), gbL4Proto, SLOT(setDisabled(bool))); - connect(rbL4Other, SIGNAL(toggled(bool)), rbPayloadOther, SLOT(setChecked(bool))); - connect(rbL4Other, SIGNAL(toggled(bool)), gbPayloadProto, SLOT(setDisabled(bool))); - - // Setup valid subsequent protocols for L2 and L3 protocols - for (int i = ProtoL2; i <= ProtoL3; i++) - { - foreach(QAbstractButton *btn1, bgProto[i]->buttons()) - { - int id1 = bgProto[i]->id(btn1); - - if (id1 != ButtonIdNone && id1 != ButtonIdOther) - { - int validProtocolCount = 0; - - foreach(QAbstractButton *btn2, bgProto[i+1]->buttons()) - { - int id2 = bgProto[i+1]->id(btn2); - - if (id2 != ButtonIdNone && id2 != ButtonIdOther) - { - if (OstProtocolManager.isValidNeighbour(id1, id2)) - { - connect(btn1, SIGNAL(toggled(bool)), - btn2, SLOT(setEnabled(bool))); - validProtocolCount++; - } - else - connect(btn1, SIGNAL(toggled(bool)), - btn2, SLOT(setDisabled(bool))); - } - } - - // If btn1 has no subsequent valid protocols, - // force subsequent Protocol to 'None' - if (validProtocolCount == 0) - connect(btn1, SIGNAL(clicked(bool)), - bgProto[i+1]->button(ButtonIdNone), SLOT(click())); - } - } - } - - mpAvailableProtocolsModel = new QStringListModel( - OstProtocolManager.protocolDatabase(), this); - lvAllProtocols->setModel(mpAvailableProtocolsModel); - mpSelectedProtocolsModel = new QStringListModel(this); - lvSelectedProtocols->setModel(mpSelectedProtocolsModel); - - - connect(lvAllProtocols->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, SLOT(when_lvAllProtocols_selectionChanged( - const QItemSelection&, const QItemSelection&))); - connect(lvSelectedProtocols->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(when_lvSelectedProtocols_currentChanged(const QModelIndex&, - const QModelIndex&))); - - LoadCurrentStream(); - mpPacketModel = new PacketModel(this); - tvPacketTree->setModel(mpPacketModel); - mpPacketModelTester = new ModelTest(mpPacketModel); - tvPacketTree->header()->hide(); - vwPacketDump->setModel(mpPacketModel); - vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); - - // TODO(MED): - - //! \todo Implement then enable these protocols - ARP, IPv6, ICMP, IGMP - rbL3Arp->setHidden(true); - rbL3Ipv6->setHidden(true); - rbL4Icmp->setHidden(true); - rbL4Igmp->setHidden(true); - //! \todo Enable navigation of streams - pbPrev->setDisabled(true); - pbNext->setDisabled(true); - //! \todo Support Goto Stream Id - leStreamId->setDisabled(true); - disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool))); - //! \todo Support Continuous Mode - rbModeContinuous->setDisabled(true); - - // Finally, restore the saved last selected tab for the various tab widgets - twTopLevel->setCurrentIndex(lastTopLevelTabIndex); -} - -void StreamConfigDialog::setupUiExtra() -{ - QRegExp reHex2B("[0-9,a-f,A-F]{1,4}"); - QRegExp reHex4B("[0-9,a-f,A-F]{1,8}"); - QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); - - // ---- Setup default stuff that cannot be done in designer ---- - bgProto[ProtoL1] = new QButtonGroup(); - bgProto[ProtoL1]->addButton(rbL1None, ButtonIdNone); - bgProto[ProtoL1]->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber); - bgProto[ProtoL1]->addButton(rbL1Other, ButtonIdOther); - - bgProto[ProtoL2] = new QButtonGroup(); -#if 0 - foreach(QRadioButton *btn, gbFrameType->findChildren()) - bgL2Proto->addButton(btn); -#else - bgProto[ProtoL2]->addButton(rbFtNone, ButtonIdNone); - bgProto[ProtoL2]->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); - bgProto[ProtoL2]->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); - bgProto[ProtoL2]->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); - bgProto[ProtoL2]->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); - bgProto[ProtoL2]->addButton(rbFtOther, ButtonIdOther); -#endif - - bgProto[ProtoVlan] = new QButtonGroup(); - bgProto[ProtoVlan]->addButton(rbVlanNone, ButtonIdNone); - bgProto[ProtoVlan]->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); - bgProto[ProtoVlan]->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); - - bgProto[ProtoL3] = new QButtonGroup(); -#if 0 - foreach(QRadioButton *btn, gbL3Proto->findChildren()) - bgProto[ProtoL3]->addButton(btn); -#else - bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone); - bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); - bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF); - bgProto[ProtoL3]->addButton(rbL3Arp, 0xFFFF); - bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther); -#endif - - bgProto[ProtoL4] = new QButtonGroup(); -#if 0 - foreach(QRadioButton *btn, gbL4Proto->findChildren()) - bgProto[ProtoL4]->addButton(btn); -#else - bgProto[ProtoL4]->addButton(rbL4None, 0); - bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); - bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); - bgProto[ProtoL4]->addButton(rbL4Icmp, 0xFFFF); - bgProto[ProtoL4]->addButton(rbL4Igmp, 0xFFFF); - bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther); -#endif - - bgProto[ProtoPayload] = new QButtonGroup(); -#if 0 - foreach(QRadioButton *btn, gbPayloadProto->findChildren()) - bgProto[ProtoPayload]->addButton(btn); -#else - bgProto[ProtoPayload]->addButton(rbPayloadNone, ButtonIdNone); - bgProto[ProtoPayload]->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); - bgProto[ProtoPayload]->addButton(rbPayloadOther, ButtonIdOther); -#endif - /* - ** Setup Validators - */ - // Meta Data - //! \todo - doesn't seem to work - range validator needs a spinbox? - //lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); - - /* - ** Setup Connections - */ - connect(rbSendPackets, SIGNAL(toggled(bool)), - this, SLOT(update_NumPacketsAndNumBursts())); - connect(rbSendBursts, SIGNAL(toggled(bool)), - this, SLOT(update_NumPacketsAndNumBursts())); - connect(rbModeFixed, SIGNAL(toggled(bool)), - this, SLOT(update_NumPacketsAndNumBursts())); - connect(rbModeContinuous, SIGNAL(toggled(bool)), - this, SLOT(update_NumPacketsAndNumBursts())); - -} - -StreamConfigDialog::~StreamConfigDialog() -{ - delete mpPacketModelTester; - delete mpPacketModel; - - for (int i = ProtoMin; i < ProtoMax; i++) - delete bgProto[i]; - - delete _iter; - delete mpStream; -} - -void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode) -{ - if (mode == "Fixed") - { - lePktLen->setEnabled(true); - lePktLenMin->setDisabled(true); - lePktLenMax->setDisabled(true); - } - else if (mode == "Increment") - { - lePktLen->setDisabled(true); - lePktLenMin->setEnabled(true); - lePktLenMax->setEnabled(true); - } - else if (mode == "Decrement") - { - lePktLen->setDisabled(true); - lePktLenMin->setEnabled(true); - lePktLenMax->setEnabled(true); - } - else if (mode == "Random") - { - lePktLen->setDisabled(true); - lePktLenMin->setEnabled(true); - lePktLenMax->setEnabled(true); - } - else - { - qWarning("Unhandled/Unknown PktLenMode = %s", mode.toAscii().data()); - } -} - -void StreamConfigDialog::on_pbPrev_clicked() -{ -#if 0 - StoreCurrentStream(currStreamIdx); - currStreamIdx--; - LoadCurrentStream(currStreamIdx); - - pbPrev->setDisabled((currStreamIdx == 0)); - pbNext->setDisabled((currStreamIdx == 2)); -#endif -} - -void StreamConfigDialog::on_pbNext_clicked() -{ -#if 0 - StoreCurrentStream(currStreamIdx); - currStreamIdx++; - LoadCurrentStream(currStreamIdx); - - pbPrev->setDisabled((currStreamIdx == 0)); - pbNext->setDisabled((currStreamIdx == 2)); -#endif -} - -void StreamConfigDialog::on_tbSelectProtocols_currentChanged(int index) -{ - qDebug("%s, index = %d", __FUNCTION__, index); - switch (index) - { - case 0: - updateSelectProtocolsSimpleWidget(); - break; - case 1: - updateSelectProtocolsAdvancedWidget(); - break; - default: - qFatal("%s: unexpected index = %d", __FUNCTION__, index); - } -} - -void StreamConfigDialog::when_lvAllProtocols_selectionChanged( - const QItemSelection &selected, const QItemSelection &deselected) -{ - int size = lvAllProtocols->selectionModel()->selectedIndexes().size(); - - qDebug("%s: selected.indexes().size = %d\n", __FUNCTION__, size); - - tbAdd->setEnabled(size > 0); -} - -void StreamConfigDialog::when_lvSelectedProtocols_currentChanged( - const QModelIndex ¤t, const QModelIndex &previous) -{ - qDebug("%s: currentRow = %d\n", __FUNCTION__, current.row()); - - tbDelete->setEnabled(current.isValid()); - tbUp->setEnabled(current.isValid() && (current.row() != 0)); - tbDown->setEnabled(current.isValid() && - (current.row() != (current.model()->rowCount() - 1))); -} - -void StreamConfigDialog::on_tbAdd_clicked() -{ - int n = 0; - QModelIndex idx2; - AbstractProtocol *p; - QModelIndexList selection; - - selection = lvAllProtocols->selectionModel()->selectedIndexes(); - - // Validation - if (selection.size() == 0) - return; - - idx2 = lvSelectedProtocols->currentIndex(); - if (idx2.isValid()) - n = idx2.row(); - - _iter->toFront(); - while (n--) - { - if (!_iter->hasNext()) - return; - - p = _iter->next(); - } - - foreach(QModelIndex idx, selection) - _iter->insert(OstProtocolManager.createProtocol( - mpAvailableProtocolsModel->stringList().at(idx.row()), mpStream)); - - updateSelectProtocolsAdvancedWidget(); - lvSelectedProtocols->setCurrentIndex(idx2); -} - -void StreamConfigDialog::on_tbDelete_clicked() -{ - int n; - QModelIndex idx; - AbstractProtocol *p; - - idx = lvSelectedProtocols->currentIndex(); - - // Validation - if (!idx.isValid()) - return; - - n = idx.row() + 1; - - _iter->toFront(); - while (n--) - { - if (!_iter->hasNext()) - return; - - p = _iter->next(); - } - - _iter->remove(); - delete p; - - updateSelectProtocolsAdvancedWidget(); - lvSelectedProtocols->setCurrentIndex(idx); -} - -void StreamConfigDialog::on_tbUp_clicked() -{ - int m, n; - QModelIndex idx; - AbstractProtocol *p; - - idx = lvSelectedProtocols->currentIndex(); - - // Validation - if (!idx.isValid() || idx.row() == 0) - return; - - m = n = idx.row() + 1; - - _iter->toFront(); - while (n--) - { - if (!_iter->hasNext()) - return; - - p = _iter->next(); - } - - _iter->remove(); - _iter->previous(); - _iter->insert(p); - - updateSelectProtocolsAdvancedWidget(); - lvSelectedProtocols->setCurrentIndex(idx.sibling(m-2, 0)); -} - -void StreamConfigDialog::on_tbDown_clicked() -{ - int m, n; - QModelIndex idx; - AbstractProtocol *p; - - idx = lvSelectedProtocols->currentIndex(); - - // Validation - if (!idx.isValid() || idx.row() == idx.model()->rowCount()) - return; - - m = n = idx.row() + 1; - - _iter->toFront(); - while (n--) - { - if (!_iter->hasNext()) - return; - - p = _iter->next(); - } - - _iter->remove(); - _iter->next(); - _iter->insert(p); - - updateSelectProtocolsAdvancedWidget(); - lvSelectedProtocols->setCurrentIndex(idx.sibling(m,0)); -} - -void StreamConfigDialog::updateSelectProtocolsAdvancedWidget() -{ - QStringList selProtoList; - - qDebug("%s", __FUNCTION__); - - _iter->toFront(); - while(_iter->hasNext()) - { - AbstractProtocol* p = _iter->next(); - qDebug("%p -- %d", p, p->protocolNumber()); - selProtoList.append(p->shortName()); - } - mpSelectedProtocolsModel->setStringList(selProtoList); -} - -void StreamConfigDialog::on_twTopLevel_currentChanged(int index) -{ - switch (index) - { - // Protocol Data - case 1: - { - QWidget *selWidget; - - // Hide the ToolBox before modifying it - else we have a crash !!! - tbProtocolData->hide(); - - selWidget = tbProtocolData->currentWidget(); - - // Remove all existing protocol widgets - while (tbProtocolData->count() > 0) - { - QWidget* w = tbProtocolData->widget(0); - tbProtocolData->removeItem(0); - w->setParent(0); - } - - // Repopulate the widgets - _iter->toFront(); - while (_iter->hasNext()) - { - AbstractProtocol* p = _iter->next(); - tbProtocolData->addItem(p->configWidget(), p->name()); - } - - tbProtocolData->setCurrentWidget(selWidget); - - tbProtocolData->show(); - break; - } - - // Packet View - case 3: - { - StoreCurrentStream(); - mpPacketModel->setSelectedProtocols(*_iter); - break; - } - - default: - break; - } -} - -void StreamConfigDialog::update_NumPacketsAndNumBursts() -{ - if (rbSendPackets->isChecked() && rbModeFixed->isChecked()) - leNumPackets->setEnabled(true); - else - leNumPackets->setEnabled(false); - - if (rbSendBursts->isChecked() && rbModeFixed->isChecked()) - leNumBursts->setEnabled(true); - else - leNumBursts->setEnabled(false); -} - -#if 0 -void StreamConfigDialog::on_lePattern_editingFinished() -{ - ulong num = 0; - bool isOk; - QString str; - - num = lePattern->text().remove(QChar(' ')).toULong(&isOk, 16); - qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); - lePattern->setText(uintToHexStr(num, str, 4)); - qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); -} -#endif - -/*! -Skip protocols upto and including the layer specified. -*/ -bool StreamConfigDialog::skipProtocols(int layer) -{ - _iter->toFront(); - - for (int i = ProtoMin; i <= layer; i++) - { - if(_iter->hasNext()) - { - int id; - QAbstractButton *btn; - - id = _iter->peekNext()->protocolNumber(); - btn = bgProto[i]->button(id); - if (btn) - _iter->next(); - } - } - - return true; -} - -/*! -Protocol choices (except "None" and "Other") for a protocol button group are disabled if checked is true, else they are enabled -*/ -void StreamConfigDialog::disableProtocols(QButtonGroup *protocolGroup, bool checked) -{ - qDebug("%s: btnGrp = %p, chk? = %d", __FUNCTION__, protocolGroup, checked); - foreach(QAbstractButton *btn, protocolGroup->buttons()) - { - int id = protocolGroup->id(btn); - - if ((id != ButtonIdNone) && (id != ButtonIdOther)) - btn->setDisabled(checked); - } -} - -void StreamConfigDialog::forceProtocolNone(bool checked) -{ - QObject *btn; - - btn = sender(); - Q_ASSERT(btn != NULL); - - qDebug("%s: chk? = %d, btn = %p, L1 = %p, L2 = %p, L3 = %p", __FUNCTION__, - checked, btn, rbL1None, rbFtNone, rbL3None); - - if (btn == rbL1None) - { - if (checked) - { - bgProto[ProtoVlan]->button(ButtonIdNone)->click(); - bgProto[ProtoL2]->button(ButtonIdNone)->click(); - bgProto[ProtoPayload]->button(ButtonIdNone)->click(); - } - - disableProtocols(bgProto[ProtoVlan], checked); - disableProtocols(bgProto[ProtoL2], checked); - disableProtocols(bgProto[ProtoPayload], checked); - } - else if (btn == rbFtNone) - { - if (checked) - bgProto[ProtoL3]->button(ButtonIdNone)->click(); - disableProtocols(bgProto[ProtoL3], checked); - } - else if (btn == rbL3None) - { - if (checked) - bgProto[ProtoL4]->button(ButtonIdNone)->click(); - disableProtocols(bgProto[ProtoL4], checked); - } - else - { - Q_ASSERT(1 == 0); // Unreachable code! - } -} - -void StreamConfigDialog::updateProtocol(int newId) -{ - int level; - QButtonGroup *btnGrp; - - btnGrp = static_cast(sender()); - Q_ASSERT(btnGrp != NULL); - - level = btnGrp->property("ProtocolLevel").toInt(); - Q_ASSERT(btnGrp == bgProto[level]); - - __updateProtocol(level, newId); -} - -void StreamConfigDialog::__updateProtocol(int level, int newId) -{ - int oldId; - QButtonGroup *btnGrp; - - Q_ASSERT((level >= ProtoMin) && (level <= ProtoMax)); - btnGrp = bgProto[level]; - oldId = btnGrp->property("ProtocolId").toInt(); - - qDebug("%s: level = %d old id = %d new id = %d upd? = %d", __FUNCTION__, - level, oldId, newId, isUpdateInProgress); - - if (newId == oldId) - return; - - if (!isUpdateInProgress) - { - int ret; - AbstractProtocol *p; - - ret = skipProtocols(level-1); - Q_ASSERT(ret == true); - - Q_ASSERT(oldId != newId); - Q_ASSERT(newId != ButtonIdOther); - - switch (oldId) - { - case ButtonIdNone: - _iter->insert(OstProtocolManager.createProtocol( - newId, mpStream)); - break; - - case ButtonIdOther: - default: - Q_ASSERT(_iter->hasNext()); - p =_iter->next(); - - if (newId) - _iter->setValue(OstProtocolManager.createProtocol( - newId, mpStream)); - else - _iter->remove(); - delete p; - if (level == ProtoPayload) - { - while (_iter->hasNext()) - { - p = _iter->next(); - _iter->remove(); - delete p; - } - } - break; - } - } - - btnGrp->setProperty("ProtocolId", newId); - return; -} - -void StreamConfigDialog::updateSelectProtocolsSimpleWidget() -{ - int i; - quint32 id; - QAbstractButton *btn; - - qDebug("%s", __FUNCTION__); - - isUpdateInProgress = true; - - // Reset to default state ... - for (i = ProtoMin; i < ProtoMax; i++) - bgProto[i]->button(ButtonIdNone)->click(); - - // ... now iterate and update - _iter->toFront(); - - for (i = ProtoMin; i < ProtoMax; i++) - { - if (!_iter->hasNext()) - goto _done; - - id = _iter->next()->protocolNumber(); - btn = bgProto[i]->button(id); - - if (btn) - { - if (btn->isEnabled()) - btn->click(); - else - { - btn->setChecked(true); - __updateProtocol(i, id); - } - } - else - { - switch (i) - { - case ProtoVlan: - _iter->previous(); - break; - - case ProtoPayload: - goto _other; - - default: - btn = bgProto[ProtoPayload]->button(id); - if (btn && btn->isEnabled()) - { - btn->click(); - break; - } - else - goto _other; - } - } - } - - // If more protocol(s) beyond payload ... - if (_iter->hasNext()) - { - i = ProtoPayload; - goto _other; - } - - goto _done; - -_other: - for (int j = i; j < ProtoMax; j++) - { - // VLAN doesn't have a "Other" button - if (j == ProtoVlan) - continue; - - bgProto[j]->button(ButtonIdOther)->setChecked(true); - __updateProtocol(j, ButtonIdOther); - } - -_done: - isUpdateInProgress = false; -} - -void StreamConfigDialog::LoadCurrentStream() -{ - QString str; - - qDebug("loading mpStream %p", mpStream); - - // Meta Data - { - cmbPktLenMode->setCurrentIndex(mpStream->lenMode()); - lePktLen->setText(str.setNum(mpStream->frameLen())); - lePktLenMin->setText(str.setNum(mpStream->frameLenMin())); - lePktLenMax->setText(str.setNum(mpStream->frameLenMax())); - } - - // Protocols - { - updateSelectProtocolsSimpleWidget(); - updateSelectProtocolsAdvancedWidget(); - - mpStream->loadProtocolWidgets(); - } - - // Stream Control - { - switch (mpStream->sendUnit()) - { - case Stream::e_su_packets: - rbSendPackets->setChecked(true); - break; - case Stream::e_su_bursts: - rbSendBursts->setChecked(true); - break; - default: - qWarning("Unhandled sendUnit = %d\n", mpStream->sendUnit()); - } - - switch (mpStream->sendMode()) - { - case Stream::e_sm_fixed: - rbModeFixed->setChecked(true); - break; - case Stream::e_sm_continuous: - rbModeContinuous->setChecked(true); - break; - default: - qWarning("Unhandled sendMode = %d\n", mpStream->sendMode()); - } - - switch(mpStream->nextWhat()) - { - case Stream::e_nw_stop: - rbActionStop->setChecked(true); - break; - case Stream::e_nw_goto_next: - rbActionGotoNext->setChecked(true); - break; - case Stream::e_nw_goto_id: - rbActionGotoStream->setChecked(true); - break; - default: - qWarning("Unhandled nextAction = %d\n", mpStream->nextWhat()); - } - - leNumPackets->setText(QString().setNum(mpStream->numPackets())); - leNumBursts->setText(QString().setNum(mpStream->numBursts())); - lePacketsPerBurst->setText(QString().setNum(mpStream->burstSize())); - lePacketsPerSec->setText(QString().setNum(mpStream->packetRate())); - leBurstsPerSec->setText(QString().setNum(mpStream->burstRate())); - // TODO(MED): Change this when we support goto to specific stream - leStreamId->setText(QString("0")); - } - qDebug("loading stream done"); -} - -void StreamConfigDialog::StoreCurrentStream() -{ - QString str; - bool isOk; - Stream *pStream = mpStream; - - qDebug("storing pStream %p", pStream); - - // Meta Data - pStream->setLenMode((Stream::FrameLengthMode) cmbPktLenMode->currentIndex()); - pStream->setFrameLen(lePktLen->text().toULong(&isOk)); - pStream->setFrameLenMin(lePktLenMin->text().toULong(&isOk)); - pStream->setFrameLenMax(lePktLenMax->text().toULong(&isOk)); - - // Protocols - { - pStream->storeProtocolWidgets(); - } - - // Stream Control - { - if (rbSendPackets->isChecked()) - pStream->setSendUnit(Stream::e_su_packets); - if (rbSendBursts->isChecked()) - pStream->setSendUnit(Stream::e_su_bursts); - - if (rbModeFixed->isChecked()) - pStream->setSendMode(Stream::e_sm_fixed); - if (rbModeContinuous->isChecked()) - pStream->setSendMode(Stream::e_sm_continuous); - - if (rbActionStop->isChecked()) - pStream->setNextWhat(Stream::e_nw_stop); - if (rbActionGotoNext->isChecked()) - pStream->setNextWhat(Stream::e_nw_goto_next); - if (rbActionGotoStream->isChecked()) - pStream->setNextWhat(Stream::e_nw_goto_id); - - pStream->setNumPackets(leNumPackets->text().toULong(&isOk)); - pStream->setNumBursts(leNumBursts->text().toULong(&isOk)); - pStream->setBurstSize(lePacketsPerBurst->text().toULong(&isOk)); - pStream->setPacketRate(lePacketsPerSec->text().toULong(&isOk)); - pStream->setBurstRate(leBurstsPerSec->text().toULong(&isOk)); - } -} - -void StreamConfigDialog::on_pbOk_clicked() -{ - OstProto::Stream s; - - // Store dialog contents into stream - StoreCurrentStream(); - - // Copy the data from the "local working copy of stream" to "actual stream" - mpStream->protoDataCopyInto(s); - mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyFrom(s); - - qDebug("stream stored"); - - lastTopLevelTabIndex = twTopLevel->currentIndex(); -} - +#include + +#include "streamconfigdialog.h" +#include "stream.h" +#include "abstractprotocol.h" +#include "protocollistiterator.h" + +#include "modeltest.h" + +// FIXME(HI) - remove +#include "../common/protocolmanager.h" +extern ProtocolManager OstProtocolManager; + +int StreamConfigDialog::lastTopLevelTabIndex = 0; + +StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, + QWidget *parent) : QDialog (parent), mPort(port) +{ + OstProto::Stream s; + mCurrentStreamIndex = streamIndex; + mpStream = new Stream; + mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyInto(s); + mpStream->protoDataCopyFrom(s); + _iter = mpStream->createProtocolListIterator(); + isUpdateInProgress = false; + + setupUi(this); + setupUiExtra(); + + for (int i = ProtoMin; i < ProtoMax; i++) + { + bgProto[i]->setProperty("ProtocolLevel", i); + bgProto[i]->setProperty("ProtocolId", ButtonIdNone); + connect(bgProto[i], SIGNAL(buttonClicked(int)), + this, SLOT(updateProtocol(int))); + } + + //! \todo causes a crash! +#if 0 + connect(lePktLen, SIGNAL(textEdited(QString)), + this, SLOT(updateContents())); +#endif + + // Time to play match the signals and slots! + + // If L1/L2(FT)/L3 = None, force subsequent protocol level(s) also to None + connect(rbL1None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); + connect(rbL3None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); + + // If L1/L2(FT)/L3/L4 = Other, force subsequent protocol to Other and + // disable the subsequent protocol group as well + connect(rbL1Other, SIGNAL(toggled(bool)), rbFtOther, SLOT(setChecked(bool))); + connect(rbL1Other, SIGNAL(toggled(bool)), gbFrameType, SLOT(setDisabled(bool))); + connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool))); + connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool))); + connect(rbL3Other, SIGNAL(toggled(bool)), rbL4Other, SLOT(setChecked(bool))); + connect(rbL3Other, SIGNAL(toggled(bool)), gbL4Proto, SLOT(setDisabled(bool))); + connect(rbL4Other, SIGNAL(toggled(bool)), rbPayloadOther, SLOT(setChecked(bool))); + connect(rbL4Other, SIGNAL(toggled(bool)), gbPayloadProto, SLOT(setDisabled(bool))); + + // Setup valid subsequent protocols for L2 and L3 protocols + for (int i = ProtoL2; i <= ProtoL3; i++) + { + foreach(QAbstractButton *btn1, bgProto[i]->buttons()) + { + int id1 = bgProto[i]->id(btn1); + + if (id1 != ButtonIdNone && id1 != ButtonIdOther) + { + int validProtocolCount = 0; + + foreach(QAbstractButton *btn2, bgProto[i+1]->buttons()) + { + int id2 = bgProto[i+1]->id(btn2); + + if (id2 != ButtonIdNone && id2 != ButtonIdOther) + { + if (OstProtocolManager.isValidNeighbour(id1, id2)) + { + connect(btn1, SIGNAL(toggled(bool)), + btn2, SLOT(setEnabled(bool))); + validProtocolCount++; + } + else + connect(btn1, SIGNAL(toggled(bool)), + btn2, SLOT(setDisabled(bool))); + } + } + + // If btn1 has no subsequent valid protocols, + // force subsequent Protocol to 'None' + if (validProtocolCount == 0) + connect(btn1, SIGNAL(clicked(bool)), + bgProto[i+1]->button(ButtonIdNone), SLOT(click())); + } + } + } + + mpAvailableProtocolsModel = new QStringListModel( + OstProtocolManager.protocolDatabase(), this); + lvAllProtocols->setModel(mpAvailableProtocolsModel); + mpSelectedProtocolsModel = new QStringListModel(this); + lvSelectedProtocols->setModel(mpSelectedProtocolsModel); + + + connect(lvAllProtocols->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, SLOT(when_lvAllProtocols_selectionChanged( + const QItemSelection&, const QItemSelection&))); + connect(lvSelectedProtocols->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(when_lvSelectedProtocols_currentChanged(const QModelIndex&, + const QModelIndex&))); + + LoadCurrentStream(); + mpPacketModel = new PacketModel(this); + tvPacketTree->setModel(mpPacketModel); + mpPacketModelTester = new ModelTest(mpPacketModel); + tvPacketTree->header()->hide(); + vwPacketDump->setModel(mpPacketModel); + vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); + + // TODO(MED): + + //! \todo Implement then enable these protocols - ARP, IPv6, ICMP, IGMP + rbL3Arp->setHidden(true); + rbL3Ipv6->setHidden(true); + rbL4Icmp->setHidden(true); + rbL4Igmp->setHidden(true); + //! \todo Enable navigation of streams + pbPrev->setDisabled(true); + pbNext->setDisabled(true); + //! \todo Support Goto Stream Id + leStreamId->setDisabled(true); + disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool))); + //! \todo Support Continuous Mode + rbModeContinuous->setDisabled(true); + + // Finally, restore the saved last selected tab for the various tab widgets + twTopLevel->setCurrentIndex(lastTopLevelTabIndex); +} + +void StreamConfigDialog::setupUiExtra() +{ + QRegExp reHex2B("[0-9,a-f,A-F]{1,4}"); + QRegExp reHex4B("[0-9,a-f,A-F]{1,8}"); + QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); + + // ---- Setup default stuff that cannot be done in designer ---- + bgProto[ProtoL1] = new QButtonGroup(); + bgProto[ProtoL1]->addButton(rbL1None, ButtonIdNone); + bgProto[ProtoL1]->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber); + bgProto[ProtoL1]->addButton(rbL1Other, ButtonIdOther); + + bgProto[ProtoL2] = new QButtonGroup(); +#if 0 + foreach(QRadioButton *btn, gbFrameType->findChildren()) + bgL2Proto->addButton(btn); +#else + bgProto[ProtoL2]->addButton(rbFtNone, ButtonIdNone); + bgProto[ProtoL2]->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); + bgProto[ProtoL2]->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); + bgProto[ProtoL2]->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); + bgProto[ProtoL2]->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); + bgProto[ProtoL2]->addButton(rbFtOther, ButtonIdOther); +#endif + + bgProto[ProtoVlan] = new QButtonGroup(); + bgProto[ProtoVlan]->addButton(rbVlanNone, ButtonIdNone); + bgProto[ProtoVlan]->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); + bgProto[ProtoVlan]->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); + + bgProto[ProtoL3] = new QButtonGroup(); +#if 0 + foreach(QRadioButton *btn, gbL3Proto->findChildren()) + bgProto[ProtoL3]->addButton(btn); +#else + bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone); + bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); + bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Arp, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther); +#endif + + bgProto[ProtoL4] = new QButtonGroup(); +#if 0 + foreach(QRadioButton *btn, gbL4Proto->findChildren()) + bgProto[ProtoL4]->addButton(btn); +#else + bgProto[ProtoL4]->addButton(rbL4None, 0); + bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); + bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); + bgProto[ProtoL4]->addButton(rbL4Icmp, 0xFFFF); + bgProto[ProtoL4]->addButton(rbL4Igmp, 0xFFFF); + bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther); +#endif + + bgProto[ProtoPayload] = new QButtonGroup(); +#if 0 + foreach(QRadioButton *btn, gbPayloadProto->findChildren()) + bgProto[ProtoPayload]->addButton(btn); +#else + bgProto[ProtoPayload]->addButton(rbPayloadNone, ButtonIdNone); + bgProto[ProtoPayload]->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); + bgProto[ProtoPayload]->addButton(rbPayloadOther, ButtonIdOther); +#endif + /* + ** Setup Validators + */ + // Meta Data + //! \todo - doesn't seem to work - range validator needs a spinbox? + //lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); + + /* + ** Setup Connections + */ + connect(rbSendPackets, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + connect(rbSendBursts, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + connect(rbModeFixed, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + connect(rbModeContinuous, SIGNAL(toggled(bool)), + this, SLOT(update_NumPacketsAndNumBursts())); + +} + +StreamConfigDialog::~StreamConfigDialog() +{ + delete mpPacketModelTester; + delete mpPacketModel; + + for (int i = ProtoMin; i < ProtoMax; i++) + delete bgProto[i]; + + delete _iter; + delete mpStream; +} + +void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode) +{ + if (mode == "Fixed") + { + lePktLen->setEnabled(true); + lePktLenMin->setDisabled(true); + lePktLenMax->setDisabled(true); + } + else if (mode == "Increment") + { + lePktLen->setDisabled(true); + lePktLenMin->setEnabled(true); + lePktLenMax->setEnabled(true); + } + else if (mode == "Decrement") + { + lePktLen->setDisabled(true); + lePktLenMin->setEnabled(true); + lePktLenMax->setEnabled(true); + } + else if (mode == "Random") + { + lePktLen->setDisabled(true); + lePktLenMin->setEnabled(true); + lePktLenMax->setEnabled(true); + } + else + { + qWarning("Unhandled/Unknown PktLenMode = %s", mode.toAscii().data()); + } +} + +void StreamConfigDialog::on_pbPrev_clicked() +{ +#if 0 + StoreCurrentStream(currStreamIdx); + currStreamIdx--; + LoadCurrentStream(currStreamIdx); + + pbPrev->setDisabled((currStreamIdx == 0)); + pbNext->setDisabled((currStreamIdx == 2)); +#endif +} + +void StreamConfigDialog::on_pbNext_clicked() +{ +#if 0 + StoreCurrentStream(currStreamIdx); + currStreamIdx++; + LoadCurrentStream(currStreamIdx); + + pbPrev->setDisabled((currStreamIdx == 0)); + pbNext->setDisabled((currStreamIdx == 2)); +#endif +} + +void StreamConfigDialog::on_tbSelectProtocols_currentChanged(int index) +{ + qDebug("%s, index = %d", __FUNCTION__, index); + switch (index) + { + case 0: + updateSelectProtocolsSimpleWidget(); + break; + case 1: + updateSelectProtocolsAdvancedWidget(); + break; + default: + qFatal("%s: unexpected index = %d", __FUNCTION__, index); + } +} + +void StreamConfigDialog::when_lvAllProtocols_selectionChanged( + const QItemSelection &selected, const QItemSelection &deselected) +{ + int size = lvAllProtocols->selectionModel()->selectedIndexes().size(); + + qDebug("%s: selected.indexes().size = %d\n", __FUNCTION__, size); + + tbAdd->setEnabled(size > 0); +} + +void StreamConfigDialog::when_lvSelectedProtocols_currentChanged( + const QModelIndex ¤t, const QModelIndex &previous) +{ + qDebug("%s: currentRow = %d\n", __FUNCTION__, current.row()); + + tbDelete->setEnabled(current.isValid()); + tbUp->setEnabled(current.isValid() && (current.row() != 0)); + tbDown->setEnabled(current.isValid() && + (current.row() != (current.model()->rowCount() - 1))); +} + +void StreamConfigDialog::on_tbAdd_clicked() +{ + int n = 0; + QModelIndex idx2; + AbstractProtocol *p; + QModelIndexList selection; + + selection = lvAllProtocols->selectionModel()->selectedIndexes(); + + // Validation + if (selection.size() == 0) + return; + + idx2 = lvSelectedProtocols->currentIndex(); + if (idx2.isValid()) + n = idx2.row(); + + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; + + p = _iter->next(); + } + + foreach(QModelIndex idx, selection) + _iter->insert(OstProtocolManager.createProtocol( + mpAvailableProtocolsModel->stringList().at(idx.row()), mpStream)); + + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx2); +} + +void StreamConfigDialog::on_tbDelete_clicked() +{ + int n; + QModelIndex idx; + AbstractProtocol *p; + + idx = lvSelectedProtocols->currentIndex(); + + // Validation + if (!idx.isValid()) + return; + + n = idx.row() + 1; + + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; + + p = _iter->next(); + } + + _iter->remove(); + delete p; + + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx); +} + +void StreamConfigDialog::on_tbUp_clicked() +{ + int m, n; + QModelIndex idx; + AbstractProtocol *p; + + idx = lvSelectedProtocols->currentIndex(); + + // Validation + if (!idx.isValid() || idx.row() == 0) + return; + + m = n = idx.row() + 1; + + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; + + p = _iter->next(); + } + + _iter->remove(); + _iter->previous(); + _iter->insert(p); + + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx.sibling(m-2, 0)); +} + +void StreamConfigDialog::on_tbDown_clicked() +{ + int m, n; + QModelIndex idx; + AbstractProtocol *p; + + idx = lvSelectedProtocols->currentIndex(); + + // Validation + if (!idx.isValid() || idx.row() == idx.model()->rowCount()) + return; + + m = n = idx.row() + 1; + + _iter->toFront(); + while (n--) + { + if (!_iter->hasNext()) + return; + + p = _iter->next(); + } + + _iter->remove(); + _iter->next(); + _iter->insert(p); + + updateSelectProtocolsAdvancedWidget(); + lvSelectedProtocols->setCurrentIndex(idx.sibling(m,0)); +} + +void StreamConfigDialog::updateSelectProtocolsAdvancedWidget() +{ + QStringList selProtoList; + + qDebug("%s", __FUNCTION__); + + _iter->toFront(); + while(_iter->hasNext()) + { + AbstractProtocol* p = _iter->next(); + qDebug("%p -- %d", p, p->protocolNumber()); + selProtoList.append(p->shortName()); + } + mpSelectedProtocolsModel->setStringList(selProtoList); +} + +void StreamConfigDialog::on_twTopLevel_currentChanged(int index) +{ + switch (index) + { + // Protocol Data + case 1: + { + QWidget *selWidget; + + // Hide the ToolBox before modifying it - else we have a crash !!! + tbProtocolData->hide(); + + selWidget = tbProtocolData->currentWidget(); + + // Remove all existing protocol widgets + while (tbProtocolData->count() > 0) + { + QWidget* w = tbProtocolData->widget(0); + tbProtocolData->removeItem(0); + w->setParent(0); + } + + // Repopulate the widgets + _iter->toFront(); + while (_iter->hasNext()) + { + AbstractProtocol* p = _iter->next(); + tbProtocolData->addItem(p->configWidget(), p->name()); + } + + tbProtocolData->setCurrentWidget(selWidget); + + tbProtocolData->show(); + break; + } + + // Packet View + case 3: + { + StoreCurrentStream(); + mpPacketModel->setSelectedProtocols(*_iter); + break; + } + + default: + break; + } +} + +void StreamConfigDialog::update_NumPacketsAndNumBursts() +{ + if (rbSendPackets->isChecked() && rbModeFixed->isChecked()) + leNumPackets->setEnabled(true); + else + leNumPackets->setEnabled(false); + + if (rbSendBursts->isChecked() && rbModeFixed->isChecked()) + leNumBursts->setEnabled(true); + else + leNumBursts->setEnabled(false); +} + +#if 0 +void StreamConfigDialog::on_lePattern_editingFinished() +{ + ulong num = 0; + bool isOk; + QString str; + + num = lePattern->text().remove(QChar(' ')).toULong(&isOk, 16); + qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); + lePattern->setText(uintToHexStr(num, str, 4)); + qDebug("editfinished (%s | %x)\n", lePattern->text().toAscii().data(), num); +} +#endif + +/*! +Skip protocols upto and including the layer specified. +*/ +bool StreamConfigDialog::skipProtocols(int layer) +{ + _iter->toFront(); + + for (int i = ProtoMin; i <= layer; i++) + { + if(_iter->hasNext()) + { + int id; + QAbstractButton *btn; + + id = _iter->peekNext()->protocolNumber(); + btn = bgProto[i]->button(id); + if (btn) + _iter->next(); + } + } + + return true; +} + +/*! +Protocol choices (except "None" and "Other") for a protocol button group are disabled if checked is true, else they are enabled +*/ +void StreamConfigDialog::disableProtocols(QButtonGroup *protocolGroup, bool checked) +{ + qDebug("%s: btnGrp = %p, chk? = %d", __FUNCTION__, protocolGroup, checked); + foreach(QAbstractButton *btn, protocolGroup->buttons()) + { + int id = protocolGroup->id(btn); + + if ((id != ButtonIdNone) && (id != ButtonIdOther)) + btn->setDisabled(checked); + } +} + +void StreamConfigDialog::forceProtocolNone(bool checked) +{ + QObject *btn; + + btn = sender(); + Q_ASSERT(btn != NULL); + + qDebug("%s: chk? = %d, btn = %p, L1 = %p, L2 = %p, L3 = %p", __FUNCTION__, + checked, btn, rbL1None, rbFtNone, rbL3None); + + if (btn == rbL1None) + { + if (checked) + { + bgProto[ProtoVlan]->button(ButtonIdNone)->click(); + bgProto[ProtoL2]->button(ButtonIdNone)->click(); + bgProto[ProtoPayload]->button(ButtonIdNone)->click(); + } + + disableProtocols(bgProto[ProtoVlan], checked); + disableProtocols(bgProto[ProtoL2], checked); + disableProtocols(bgProto[ProtoPayload], checked); + } + else if (btn == rbFtNone) + { + if (checked) + bgProto[ProtoL3]->button(ButtonIdNone)->click(); + disableProtocols(bgProto[ProtoL3], checked); + } + else if (btn == rbL3None) + { + if (checked) + bgProto[ProtoL4]->button(ButtonIdNone)->click(); + disableProtocols(bgProto[ProtoL4], checked); + } + else + { + Q_ASSERT(1 == 0); // Unreachable code! + } +} + +void StreamConfigDialog::updateProtocol(int newId) +{ + int level; + QButtonGroup *btnGrp; + + btnGrp = static_cast(sender()); + Q_ASSERT(btnGrp != NULL); + + level = btnGrp->property("ProtocolLevel").toInt(); + Q_ASSERT(btnGrp == bgProto[level]); + + __updateProtocol(level, newId); +} + +void StreamConfigDialog::__updateProtocol(int level, int newId) +{ + int oldId; + QButtonGroup *btnGrp; + + Q_ASSERT((level >= ProtoMin) && (level <= ProtoMax)); + btnGrp = bgProto[level]; + oldId = btnGrp->property("ProtocolId").toInt(); + + qDebug("%s: level = %d old id = %d new id = %d upd? = %d", __FUNCTION__, + level, oldId, newId, isUpdateInProgress); + + if (newId == oldId) + return; + + if (!isUpdateInProgress) + { + int ret; + AbstractProtocol *p; + + ret = skipProtocols(level-1); + Q_ASSERT(ret == true); + + Q_ASSERT(oldId != newId); + Q_ASSERT(newId != ButtonIdOther); + + switch (oldId) + { + case ButtonIdNone: + _iter->insert(OstProtocolManager.createProtocol( + newId, mpStream)); + break; + + case ButtonIdOther: + default: + Q_ASSERT(_iter->hasNext()); + p =_iter->next(); + + if (newId) + _iter->setValue(OstProtocolManager.createProtocol( + newId, mpStream)); + else + _iter->remove(); + delete p; + if (level == ProtoPayload) + { + while (_iter->hasNext()) + { + p = _iter->next(); + _iter->remove(); + delete p; + } + } + break; + } + } + + btnGrp->setProperty("ProtocolId", newId); + return; +} + +void StreamConfigDialog::updateSelectProtocolsSimpleWidget() +{ + int i; + quint32 id; + QAbstractButton *btn; + + qDebug("%s", __FUNCTION__); + + isUpdateInProgress = true; + + // Reset to default state ... + for (i = ProtoMin; i < ProtoMax; i++) + bgProto[i]->button(ButtonIdNone)->click(); + + // ... now iterate and update + _iter->toFront(); + + for (i = ProtoMin; i < ProtoMax; i++) + { + if (!_iter->hasNext()) + goto _done; + + id = _iter->next()->protocolNumber(); + btn = bgProto[i]->button(id); + + if (btn) + { + if (btn->isEnabled()) + btn->click(); + else + { + btn->setChecked(true); + __updateProtocol(i, id); + } + } + else + { + switch (i) + { + case ProtoVlan: + _iter->previous(); + break; + + case ProtoPayload: + goto _other; + + default: + btn = bgProto[ProtoPayload]->button(id); + if (btn && btn->isEnabled()) + { + btn->click(); + break; + } + else + goto _other; + } + } + } + + // If more protocol(s) beyond payload ... + if (_iter->hasNext()) + { + i = ProtoPayload; + goto _other; + } + + goto _done; + +_other: + for (int j = i; j < ProtoMax; j++) + { + // VLAN doesn't have a "Other" button + if (j == ProtoVlan) + continue; + + bgProto[j]->button(ButtonIdOther)->setChecked(true); + __updateProtocol(j, ButtonIdOther); + } + +_done: + isUpdateInProgress = false; +} + +void StreamConfigDialog::LoadCurrentStream() +{ + QString str; + + qDebug("loading mpStream %p", mpStream); + + // Meta Data + { + cmbPktLenMode->setCurrentIndex(mpStream->lenMode()); + lePktLen->setText(str.setNum(mpStream->frameLen())); + lePktLenMin->setText(str.setNum(mpStream->frameLenMin())); + lePktLenMax->setText(str.setNum(mpStream->frameLenMax())); + } + + // Protocols + { + updateSelectProtocolsSimpleWidget(); + updateSelectProtocolsAdvancedWidget(); + + mpStream->loadProtocolWidgets(); + } + + // Stream Control + { + switch (mpStream->sendUnit()) + { + case Stream::e_su_packets: + rbSendPackets->setChecked(true); + break; + case Stream::e_su_bursts: + rbSendBursts->setChecked(true); + break; + default: + qWarning("Unhandled sendUnit = %d\n", mpStream->sendUnit()); + } + + switch (mpStream->sendMode()) + { + case Stream::e_sm_fixed: + rbModeFixed->setChecked(true); + break; + case Stream::e_sm_continuous: + rbModeContinuous->setChecked(true); + break; + default: + qWarning("Unhandled sendMode = %d\n", mpStream->sendMode()); + } + + switch(mpStream->nextWhat()) + { + case Stream::e_nw_stop: + rbActionStop->setChecked(true); + break; + case Stream::e_nw_goto_next: + rbActionGotoNext->setChecked(true); + break; + case Stream::e_nw_goto_id: + rbActionGotoStream->setChecked(true); + break; + default: + qWarning("Unhandled nextAction = %d\n", mpStream->nextWhat()); + } + + leNumPackets->setText(QString().setNum(mpStream->numPackets())); + leNumBursts->setText(QString().setNum(mpStream->numBursts())); + lePacketsPerBurst->setText(QString().setNum(mpStream->burstSize())); + lePacketsPerSec->setText(QString().setNum(mpStream->packetRate())); + leBurstsPerSec->setText(QString().setNum(mpStream->burstRate())); + // TODO(MED): Change this when we support goto to specific stream + leStreamId->setText(QString("0")); + } + qDebug("loading stream done"); +} + +void StreamConfigDialog::StoreCurrentStream() +{ + QString str; + bool isOk; + Stream *pStream = mpStream; + + qDebug("storing pStream %p", pStream); + + // Meta Data + pStream->setLenMode((Stream::FrameLengthMode) cmbPktLenMode->currentIndex()); + pStream->setFrameLen(lePktLen->text().toULong(&isOk)); + pStream->setFrameLenMin(lePktLenMin->text().toULong(&isOk)); + pStream->setFrameLenMax(lePktLenMax->text().toULong(&isOk)); + + // Protocols + { + pStream->storeProtocolWidgets(); + } + + // Stream Control + { + if (rbSendPackets->isChecked()) + pStream->setSendUnit(Stream::e_su_packets); + if (rbSendBursts->isChecked()) + pStream->setSendUnit(Stream::e_su_bursts); + + if (rbModeFixed->isChecked()) + pStream->setSendMode(Stream::e_sm_fixed); + if (rbModeContinuous->isChecked()) + pStream->setSendMode(Stream::e_sm_continuous); + + if (rbActionStop->isChecked()) + pStream->setNextWhat(Stream::e_nw_stop); + if (rbActionGotoNext->isChecked()) + pStream->setNextWhat(Stream::e_nw_goto_next); + if (rbActionGotoStream->isChecked()) + pStream->setNextWhat(Stream::e_nw_goto_id); + + pStream->setNumPackets(leNumPackets->text().toULong(&isOk)); + pStream->setNumBursts(leNumBursts->text().toULong(&isOk)); + pStream->setBurstSize(lePacketsPerBurst->text().toULong(&isOk)); + pStream->setPacketRate(lePacketsPerSec->text().toULong(&isOk)); + pStream->setBurstRate(leBurstsPerSec->text().toULong(&isOk)); + } +} + +void StreamConfigDialog::on_pbOk_clicked() +{ + OstProto::Stream s; + + // Store dialog contents into stream + StoreCurrentStream(); + + // Copy the data from the "local working copy of stream" to "actual stream" + mpStream->protoDataCopyInto(s); + mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyFrom(s); + + qDebug("stream stored"); + + lastTopLevelTabIndex = twTopLevel->currentIndex(); +} + diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index fcc3f40..0961767 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -1,113 +1,113 @@ -#ifndef _STREAM_CONFIG_DIALOG_H -#define _STREAM_CONFIG_DIALOG_H - -#include -#include "ui_streamconfigdialog.h" -#include "port.h" -#include "stream.h" -#include "packetmodel.h" -#include "modeltest.h" - -#define MAX_MAC_ITER_COUNT 256 -#define MIN_PKT_LEN 64 -#define MAX_PKT_LEN 1522 - -/* -** TODO -** \todo Improve HexStr handling -** -*/ - - -class StreamConfigDialog : public QDialog, public Ui::StreamConfigDialog -{ - Q_OBJECT -public: - StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent = 0); - ~StreamConfigDialog(); - -private: - - enum ButtonId - { - ButtonIdNone = 0, - ButtonIdOther = -2 - }; - - enum ProtoButtonGroup - { - ProtoMin, - ProtoL1 = 0, - ProtoVlan = 1, - ProtoL2 = 2, - ProtoL3 = 3, - ProtoL4 = 4, - ProtoPayload = 5, - ProtoMax - }; - - QButtonGroup *bgProto[ProtoMax]; - - QStringListModel *mpAvailableProtocolsModel; - QStringListModel *mpSelectedProtocolsModel; - - Port& mPort; - uint mCurrentStreamIndex; - - Stream *mpStream; - ProtocolListIterator *_iter; - - bool isUpdateInProgress; - - PacketModel *mpPacketModel; - ModelTest *mpPacketModelTester; - - // The following static variables are used to track the "selected" tab - // for the various tab widgets so that it can be restored when the dialog - // is opened the next time - static int lastTopLevelTabIndex; - - void setupUiExtra(); - void updateSelectedProtocols(); - void LoadCurrentStream(); - void StoreCurrentStream(); - -private slots: - void on_cmbPktLenMode_currentIndexChanged(QString mode); - void update_NumPacketsAndNumBursts(); - - void on_twTopLevel_currentChanged(int index); - void on_tbSelectProtocols_currentChanged(int index); - - // "Simple" Protocol Selection related - bool skipProtocols(int layer); - - void disableProtocols(QButtonGroup *protocolGroup, bool checked); - void forceProtocolNone(bool checked); - - void updateProtocol(int newId); - void __updateProtocol(int level, int newId); - - void updateSelectProtocolsSimpleWidget(); - - // "Advanced" Protocol Selection related - void when_lvAllProtocols_selectionChanged( - const QItemSelection &selected, const QItemSelection &deselected); - void when_lvSelectedProtocols_currentChanged( - const QModelIndex ¤t, const QModelIndex &previous); - - void on_tbAdd_clicked(); - void on_tbDelete_clicked(); - void on_tbUp_clicked(); - void on_tbDown_clicked(); - - void updateSelectProtocolsAdvancedWidget(); - - void on_pbPrev_clicked(); - void on_pbNext_clicked(); - - void on_pbOk_clicked(); -}; - -#endif - +#ifndef _STREAM_CONFIG_DIALOG_H +#define _STREAM_CONFIG_DIALOG_H + +#include +#include "ui_streamconfigdialog.h" +#include "port.h" +#include "stream.h" +#include "packetmodel.h" +#include "modeltest.h" + +#define MAX_MAC_ITER_COUNT 256 +#define MIN_PKT_LEN 64 +#define MAX_PKT_LEN 1522 + +/* +** TODO +** \todo Improve HexStr handling +** +*/ + + +class StreamConfigDialog : public QDialog, public Ui::StreamConfigDialog +{ + Q_OBJECT +public: + StreamConfigDialog(Port &port, uint streamIndex, QWidget *parent = 0); + ~StreamConfigDialog(); + +private: + + enum ButtonId + { + ButtonIdNone = 0, + ButtonIdOther = -2 + }; + + enum ProtoButtonGroup + { + ProtoMin, + ProtoL1 = 0, + ProtoVlan = 1, + ProtoL2 = 2, + ProtoL3 = 3, + ProtoL4 = 4, + ProtoPayload = 5, + ProtoMax + }; + + QButtonGroup *bgProto[ProtoMax]; + + QStringListModel *mpAvailableProtocolsModel; + QStringListModel *mpSelectedProtocolsModel; + + Port& mPort; + uint mCurrentStreamIndex; + + Stream *mpStream; + ProtocolListIterator *_iter; + + bool isUpdateInProgress; + + PacketModel *mpPacketModel; + ModelTest *mpPacketModelTester; + + // The following static variables are used to track the "selected" tab + // for the various tab widgets so that it can be restored when the dialog + // is opened the next time + static int lastTopLevelTabIndex; + + void setupUiExtra(); + void updateSelectedProtocols(); + void LoadCurrentStream(); + void StoreCurrentStream(); + +private slots: + void on_cmbPktLenMode_currentIndexChanged(QString mode); + void update_NumPacketsAndNumBursts(); + + void on_twTopLevel_currentChanged(int index); + void on_tbSelectProtocols_currentChanged(int index); + + // "Simple" Protocol Selection related + bool skipProtocols(int layer); + + void disableProtocols(QButtonGroup *protocolGroup, bool checked); + void forceProtocolNone(bool checked); + + void updateProtocol(int newId); + void __updateProtocol(int level, int newId); + + void updateSelectProtocolsSimpleWidget(); + + // "Advanced" Protocol Selection related + void when_lvAllProtocols_selectionChanged( + const QItemSelection &selected, const QItemSelection &deselected); + void when_lvSelectedProtocols_currentChanged( + const QModelIndex ¤t, const QModelIndex &previous); + + void on_tbAdd_clicked(); + void on_tbDelete_clicked(); + void on_tbUp_clicked(); + void on_tbDown_clicked(); + + void updateSelectProtocolsAdvancedWidget(); + + void on_pbPrev_clicked(); + void on_pbNext_clicked(); + + void on_pbOk_clicked(); +}; + +#endif + diff --git a/client/streammodel.cpp b/client/streammodel.cpp index 925be4b..c58d25b 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -1,242 +1,242 @@ -#include "stream.h" -#include "streammodel.h" -#include "portgrouplist.h" -#include "qicon.h" - -StreamModel::StreamModel(PortGroupList *p, QObject *parent) - : QAbstractTableModel(parent) -{ - pgl = p; - mCurrentPort = NULL; -} - -int StreamModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - if (mCurrentPort) - return mCurrentPort->numStreams(); - else - return 0; -} - -int StreamModel::columnCount(const QModelIndex &parent ) const -{ - return (int) StreamMaxFields; -} - -Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags flags = QAbstractTableModel::flags(index); - - - switch (index.column()) - { - case StreamIcon: - break; - case StreamName: - flags |= Qt::ItemIsEditable; - break; - case StreamStatus: - flags |= Qt::ItemIsUserCheckable; - break; - case StreamNextWhat: - flags |= Qt::ItemIsEditable; - break; - default: - //qFatal("Missed case in switch!"); - break; - } - - return flags; -} - -QVariant StreamModel::data(const QModelIndex &index, int role) const -{ - // Check for a valid index - if (!index.isValid()) - return QVariant(); - - // Check for row/column limits - if (index.row() >= mCurrentPort->numStreams()) - return QVariant(); - - if (index.column() >= StreamMaxFields) - return QVariant(); - - if (mCurrentPort == NULL) - return QVariant(); - - // Return data based on field and role - switch(index.column()) - { - case StreamIcon: - { - if (role == Qt::DecorationRole) - return QIcon(":/icons/stream_edit.png"); - else - return QVariant(); - break; - } - case StreamName: - { - if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) - return mCurrentPort->streamByIndex(index.row())->name(); - else - return QVariant(); - break; - } - case StreamStatus: - { - if ((role == Qt::CheckStateRole)) - { - if (mCurrentPort->streamByIndex(index.row())->isEnabled()) - return Qt::Checked; - else - return Qt::Unchecked; - } - else - return QVariant(); - break; - } - case StreamNextWhat: - { - int val = mCurrentPort->streamByIndex(index.row())->nextWhat(); - - if (role == Qt::DisplayRole) - return nextWhatOptionList().at(val); - else if (role == Qt::EditRole) - return val; - else - return QVariant(); - - break; - } - default: - qFatal("-------------UNHANDLED STREAM FIELD----------------"); - } - - return QVariant(); -} - -bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (mCurrentPort == NULL) - return false; - - if (index.isValid()) - { - switch (index.column()) - { - // Edit Supported Fields - case StreamName: - mCurrentPort->streamByIndex(index.row())->setName(value.toString()); - emit(dataChanged(index, index)); - return true; - - case StreamStatus: - mCurrentPort->streamByIndex(index.row())->setEnabled(value.toBool()); - emit(dataChanged(index, index)); - return true; - - case StreamNextWhat: - if (role == Qt::EditRole) - { - mCurrentPort->streamByIndex(index.row())->setNextWhat( - (Stream::NextWhat)value.toInt()); - emit(dataChanged(index, index)); - return true; - } - else - return false; - - // Edit Not Supported Fields - case StreamIcon: - return false; - - // Unhandled Stream Field - default: - qDebug("-------------UNHANDLED STREAM FIELD----------------"); - break; - } - } - - return false; -} - -QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role != Qt::DisplayRole) - return QVariant(); - - if (orientation == Qt::Horizontal) - { - switch(section) - { - case StreamIcon: - return QString(""); - break; - case StreamName: - return QString("Name"); - break; - case StreamStatus: - return QString(""); - break; - case StreamNextWhat: - return QString("Goto"); - break; - default: - qDebug("-------------UNHANDLED STREAM FIELD----------------"); - break; - } - } - else - return QString("%1").arg(section+1); - - return QVariant(); -} - -bool StreamModel::insertRows(int row, int count, const QModelIndex &parent) -{ - qDebug("insertRows() row = %d", row); - qDebug("insertRows() count = %d", count); - beginInsertRows(QModelIndex(), row, row+count-1); - for (int i = 0; i < count; i++) - mCurrentPort->newStreamAt(row); - endInsertRows(); - - return true; -} - -bool StreamModel::removeRows(int row, int count, const QModelIndex &parent) -{ - qDebug("removeRows() row = %d", row); - qDebug("removeRows() count = %d", count); - beginRemoveRows(QModelIndex(), row, row+count-1); - for (int i = 0; i < count; i++) - { - mCurrentPort->deleteStreamAt(row); - } - endRemoveRows(); - - return true; -} - -// --------------------- SLOTS ------------------------ - -void StreamModel::setCurrentPortIndex(const QModelIndex ¤t) -{ - if (!current.isValid() || !pgl->isPort(current)) - { - qDebug("current is either invalid or not a port"); - mCurrentPort = NULL; - } - else - { - qDebug("change to valid port"); - quint16 pg = current.internalId() >> 16; - mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()]; - } - reset(); -} +#include "stream.h" +#include "streammodel.h" +#include "portgrouplist.h" +#include "qicon.h" + +StreamModel::StreamModel(PortGroupList *p, QObject *parent) + : QAbstractTableModel(parent) +{ + pgl = p; + mCurrentPort = NULL; +} + +int StreamModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + if (mCurrentPort) + return mCurrentPort->numStreams(); + else + return 0; +} + +int StreamModel::columnCount(const QModelIndex &parent ) const +{ + return (int) StreamMaxFields; +} + +Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + + + switch (index.column()) + { + case StreamIcon: + break; + case StreamName: + flags |= Qt::ItemIsEditable; + break; + case StreamStatus: + flags |= Qt::ItemIsUserCheckable; + break; + case StreamNextWhat: + flags |= Qt::ItemIsEditable; + break; + default: + //qFatal("Missed case in switch!"); + break; + } + + return flags; +} + +QVariant StreamModel::data(const QModelIndex &index, int role) const +{ + // Check for a valid index + if (!index.isValid()) + return QVariant(); + + // Check for row/column limits + if (index.row() >= mCurrentPort->numStreams()) + return QVariant(); + + if (index.column() >= StreamMaxFields) + return QVariant(); + + if (mCurrentPort == NULL) + return QVariant(); + + // Return data based on field and role + switch(index.column()) + { + case StreamIcon: + { + if (role == Qt::DecorationRole) + return QIcon(":/icons/stream_edit.png"); + else + return QVariant(); + break; + } + case StreamName: + { + if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) + return mCurrentPort->streamByIndex(index.row())->name(); + else + return QVariant(); + break; + } + case StreamStatus: + { + if ((role == Qt::CheckStateRole)) + { + if (mCurrentPort->streamByIndex(index.row())->isEnabled()) + return Qt::Checked; + else + return Qt::Unchecked; + } + else + return QVariant(); + break; + } + case StreamNextWhat: + { + int val = mCurrentPort->streamByIndex(index.row())->nextWhat(); + + if (role == Qt::DisplayRole) + return nextWhatOptionList().at(val); + else if (role == Qt::EditRole) + return val; + else + return QVariant(); + + break; + } + default: + qFatal("-------------UNHANDLED STREAM FIELD----------------"); + } + + return QVariant(); +} + +bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (mCurrentPort == NULL) + return false; + + if (index.isValid()) + { + switch (index.column()) + { + // Edit Supported Fields + case StreamName: + mCurrentPort->streamByIndex(index.row())->setName(value.toString()); + emit(dataChanged(index, index)); + return true; + + case StreamStatus: + mCurrentPort->streamByIndex(index.row())->setEnabled(value.toBool()); + emit(dataChanged(index, index)); + return true; + + case StreamNextWhat: + if (role == Qt::EditRole) + { + mCurrentPort->streamByIndex(index.row())->setNextWhat( + (Stream::NextWhat)value.toInt()); + emit(dataChanged(index, index)); + return true; + } + else + return false; + + // Edit Not Supported Fields + case StreamIcon: + return false; + + // Unhandled Stream Field + default: + qDebug("-------------UNHANDLED STREAM FIELD----------------"); + break; + } + } + + return false; +} + +QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + { + switch(section) + { + case StreamIcon: + return QString(""); + break; + case StreamName: + return QString("Name"); + break; + case StreamStatus: + return QString(""); + break; + case StreamNextWhat: + return QString("Goto"); + break; + default: + qDebug("-------------UNHANDLED STREAM FIELD----------------"); + break; + } + } + else + return QString("%1").arg(section+1); + + return QVariant(); +} + +bool StreamModel::insertRows(int row, int count, const QModelIndex &parent) +{ + qDebug("insertRows() row = %d", row); + qDebug("insertRows() count = %d", count); + beginInsertRows(QModelIndex(), row, row+count-1); + for (int i = 0; i < count; i++) + mCurrentPort->newStreamAt(row); + endInsertRows(); + + return true; +} + +bool StreamModel::removeRows(int row, int count, const QModelIndex &parent) +{ + qDebug("removeRows() row = %d", row); + qDebug("removeRows() count = %d", count); + beginRemoveRows(QModelIndex(), row, row+count-1); + for (int i = 0; i < count; i++) + { + mCurrentPort->deleteStreamAt(row); + } + endRemoveRows(); + + return true; +} + +// --------------------- SLOTS ------------------------ + +void StreamModel::setCurrentPortIndex(const QModelIndex ¤t) +{ + if (!current.isValid() || !pgl->isPort(current)) + { + qDebug("current is either invalid or not a port"); + mCurrentPort = NULL; + } + else + { + qDebug("change to valid port"); + quint16 pg = current.internalId() >> 16; + mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()]; + } + reset(); +} diff --git a/client/streammodel.h b/client/streammodel.h index c65b4d9..e73bb18 100644 --- a/client/streammodel.h +++ b/client/streammodel.h @@ -1,57 +1,57 @@ -#ifndef _STREAM_MODEL_H -#define _STREAM_MODEL_H - -#include -#include -#include "port.h" - -class PortGroupList; - -class StreamModel : public QAbstractTableModel -{ - Q_OBJECT - - Port *mCurrentPort; - PortGroupList *pgl; - - public: - StreamModel(PortGroupList *p, QObject *parent = 0); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role) const; - bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole); - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - bool insertRows (int row, int count, - const QModelIndex & parent = QModelIndex()); - bool removeRows (int row, int count, - const QModelIndex & parent = QModelIndex()); - -#if 0 // CleanedUp! - // FIXME(HIGH): This *is* like a kludge - QList* currentPortStreamList() - { return &mCurrentPort->mStreams; } -#endif - - public: - enum StreamFields { - StreamIcon = 0, - StreamName, - StreamStatus, - StreamNextWhat, - - StreamMaxFields - }; - - static QStringList nextWhatOptionList() - { return QStringList() << "Stop" << "Next" << "Goto first"; } - - public slots: - void setCurrentPortIndex(const QModelIndex ¤t); - -}; - -#endif +#ifndef _STREAM_MODEL_H +#define _STREAM_MODEL_H + +#include +#include +#include "port.h" + +class PortGroupList; + +class StreamModel : public QAbstractTableModel +{ + Q_OBJECT + + Port *mCurrentPort; + PortGroupList *pgl; + + public: + StreamModel(PortGroupList *p, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + bool insertRows (int row, int count, + const QModelIndex & parent = QModelIndex()); + bool removeRows (int row, int count, + const QModelIndex & parent = QModelIndex()); + +#if 0 // CleanedUp! + // FIXME(HIGH): This *is* like a kludge + QList* currentPortStreamList() + { return &mCurrentPort->mStreams; } +#endif + + public: + enum StreamFields { + StreamIcon = 0, + StreamName, + StreamStatus, + StreamNextWhat, + + StreamMaxFields + }; + + static QStringList nextWhatOptionList() + { return QStringList() << "Stop" << "Next" << "Goto first"; } + + public slots: + void setCurrentPortIndex(const QModelIndex ¤t); + +}; + +#endif diff --git a/common/protocol.proto b/common/protocol.proto index c8bdc05..42caff1 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -1,210 +1,210 @@ -// stream.proto - -package OstProto; - -message StreamId { - required uint32 id = 1; -} - -message StreamCore { - enum FrameLengthMode { - e_fl_fixed = 0; - e_fl_inc = 1; - e_fl_dec = 2; - e_fl_random = 3; - } - - // Basics - optional string name = 1; - optional bool is_enabled = 2; - optional uint32 ordinal = 3; - - // Frame Length (includes CRC) - optional FrameLengthMode len_mode = 14 [default = e_fl_fixed]; - optional uint32 frame_len = 15 [default = 64]; - optional uint32 frame_len_min = 16 [default = 64]; - optional uint32 frame_len_max = 17 [default = 1518]; - - // Currently Selected Protocols - //repeated uint32 frame_proto = 20; -} - -message StreamControl { - enum SendUnit { - e_su_packets = 0; - e_su_bursts = 1; - } - - enum SendMode { - e_sm_fixed = 0; - e_sm_continuous = 1; - } - - enum NextWhat { - e_nw_stop = 0; - e_nw_goto_next = 1; - e_nw_goto_id = 2; - } - - optional SendUnit unit = 1 [default = e_su_packets]; - optional SendMode mode = 2 [default = e_sm_fixed]; - optional uint32 num_packets = 3 [default = 1]; - optional uint32 num_bursts = 4 [default = 1]; - optional uint32 packets_per_burst = 5 [default = 10]; - optional NextWhat next = 6 [default = e_nw_goto_next]; - optional uint32 packets_per_sec = 7 [default = 1]; - optional uint32 bursts_per_sec = 8 [default = 1]; -} - -message ProtocolId { - required uint32 id = 1; -} - -message Protocol { - - required ProtocolId protocol_id = 1; - - extensions 51 to 100; // Reserved for Ostinato Use - extensions 101 to 200; // Available for use by protocols - - enum k { - kMacFieldNumber = 51; - kPayloadFieldNumber = 52; - kSampleFieldNumber = 53; - kUserScriptFieldNumber = 54; - - kEth2FieldNumber = 121; - kDot3FieldNumber = 122; - kLlcFieldNumber = 123; - kSnapFieldNumber = 124; - - kSvlanFieldNumber = 125; - kVlanFieldNumber = 126; - - kDot2LlcFieldNumber = 127; - kDot2SnapFieldNumber = 128; - kVlanStackFieldNumber = 129; - - kIp4FieldNumber = 130; - kArpFieldNumber = 131; - - kTcpFieldNumber = 140; - kUdpFieldNumber = 141; - kIcmpFieldNumber = 142; - kIgmpFieldNumber = 143; - } -} - -message Stream { - - required StreamId stream_id = 1; - optional StreamCore core = 2; - optional StreamControl control = 3; - - repeated Protocol protocol = 4; -} - -message Void { - // nothing! -} - -message Ack { - //! \todo (LOW) do we need any fields in 'Ack' -} - -message PortId { - required uint32 id = 1; -} - -message PortIdList { - repeated PortId port_id = 1; -} - -message StreamIdList { - required PortId port_id = 1; - repeated StreamId stream_id = 2; -} - -message Port { - required PortId port_id = 1; - optional string name = 2; - optional string description = 3; - optional bool is_enabled = 4; - optional bool is_exclusive_control = 6; -} - -message PortConfigList { - repeated Port port = 1; -} - -message StreamConfigList { - required PortId port_id = 1; - repeated Stream stream = 2; -} - -message CaptureBuffer { - //! \todo (HIGH) define CaptureBuffer -} - -message CaptureBufferList { - repeated CaptureBuffer list = 1; -} - -enum LinkState { - LinkStateUnknown = 0; - LinkStateDown = 1; - LinkStateUp = 2; -} - -message PortState { - optional LinkState link_state = 1 [default = LinkStateUnknown]; - optional bool is_transmit_on = 2 [default = false]; - optional bool is_capture_on = 3 [default = false]; -} - -message PortStats { - - required PortId port_id = 1; - - optional PortState state = 2; - - optional uint64 rx_pkts = 11; - optional uint64 rx_bytes = 12; - optional uint64 rx_pkts_nic = 13; - optional uint64 rx_bytes_nic = 14; - optional uint64 rx_pps = 15; - optional uint64 rx_bps = 16; - - optional uint64 tx_pkts = 21; - optional uint64 tx_bytes = 22; - optional uint64 tx_pkts_nic = 23; - optional uint64 tx_bytes_nic = 24; - optional uint64 tx_pps = 25; - optional uint64 tx_bps = 26; -} - -message PortStatsList { - repeated PortStats port_stats = 1; -} - -service OstService { - rpc getPortIdList(Void) returns (PortIdList); - rpc getPortConfig(PortIdList) returns (PortConfigList); - - rpc getStreamIdList(PortId) returns (StreamIdList); - rpc getStreamConfig(StreamIdList) returns (StreamConfigList); - rpc addStream(StreamIdList) returns (Ack); - rpc deleteStream(StreamIdList) returns (Ack); - rpc modifyStream(StreamConfigList) returns (Ack); - - rpc startTx(PortIdList) returns (Ack); - rpc stopTx(PortIdList) returns (Ack); - - rpc startCapture(PortIdList) returns (Ack); - rpc stopCapture(PortIdList) returns (Ack); - rpc getCaptureBuffer(PortId) returns (CaptureBuffer); - - rpc getStats(PortIdList) returns (PortStatsList); - rpc clearStats(PortIdList) returns (Ack); -} - +// stream.proto + +package OstProto; + +message StreamId { + required uint32 id = 1; +} + +message StreamCore { + enum FrameLengthMode { + e_fl_fixed = 0; + e_fl_inc = 1; + e_fl_dec = 2; + e_fl_random = 3; + } + + // Basics + optional string name = 1; + optional bool is_enabled = 2; + optional uint32 ordinal = 3; + + // Frame Length (includes CRC) + optional FrameLengthMode len_mode = 14 [default = e_fl_fixed]; + optional uint32 frame_len = 15 [default = 64]; + optional uint32 frame_len_min = 16 [default = 64]; + optional uint32 frame_len_max = 17 [default = 1518]; + + // Currently Selected Protocols + //repeated uint32 frame_proto = 20; +} + +message StreamControl { + enum SendUnit { + e_su_packets = 0; + e_su_bursts = 1; + } + + enum SendMode { + e_sm_fixed = 0; + e_sm_continuous = 1; + } + + enum NextWhat { + e_nw_stop = 0; + e_nw_goto_next = 1; + e_nw_goto_id = 2; + } + + optional SendUnit unit = 1 [default = e_su_packets]; + optional SendMode mode = 2 [default = e_sm_fixed]; + optional uint32 num_packets = 3 [default = 1]; + optional uint32 num_bursts = 4 [default = 1]; + optional uint32 packets_per_burst = 5 [default = 10]; + optional NextWhat next = 6 [default = e_nw_goto_next]; + optional uint32 packets_per_sec = 7 [default = 1]; + optional uint32 bursts_per_sec = 8 [default = 1]; +} + +message ProtocolId { + required uint32 id = 1; +} + +message Protocol { + + required ProtocolId protocol_id = 1; + + extensions 51 to 100; // Reserved for Ostinato Use + extensions 101 to 200; // Available for use by protocols + + enum k { + kMacFieldNumber = 51; + kPayloadFieldNumber = 52; + kSampleFieldNumber = 53; + kUserScriptFieldNumber = 54; + + kEth2FieldNumber = 121; + kDot3FieldNumber = 122; + kLlcFieldNumber = 123; + kSnapFieldNumber = 124; + + kSvlanFieldNumber = 125; + kVlanFieldNumber = 126; + + kDot2LlcFieldNumber = 127; + kDot2SnapFieldNumber = 128; + kVlanStackFieldNumber = 129; + + kIp4FieldNumber = 130; + kArpFieldNumber = 131; + + kTcpFieldNumber = 140; + kUdpFieldNumber = 141; + kIcmpFieldNumber = 142; + kIgmpFieldNumber = 143; + } +} + +message Stream { + + required StreamId stream_id = 1; + optional StreamCore core = 2; + optional StreamControl control = 3; + + repeated Protocol protocol = 4; +} + +message Void { + // nothing! +} + +message Ack { + //! \todo (LOW) do we need any fields in 'Ack' +} + +message PortId { + required uint32 id = 1; +} + +message PortIdList { + repeated PortId port_id = 1; +} + +message StreamIdList { + required PortId port_id = 1; + repeated StreamId stream_id = 2; +} + +message Port { + required PortId port_id = 1; + optional string name = 2; + optional string description = 3; + optional bool is_enabled = 4; + optional bool is_exclusive_control = 6; +} + +message PortConfigList { + repeated Port port = 1; +} + +message StreamConfigList { + required PortId port_id = 1; + repeated Stream stream = 2; +} + +message CaptureBuffer { + //! \todo (HIGH) define CaptureBuffer +} + +message CaptureBufferList { + repeated CaptureBuffer list = 1; +} + +enum LinkState { + LinkStateUnknown = 0; + LinkStateDown = 1; + LinkStateUp = 2; +} + +message PortState { + optional LinkState link_state = 1 [default = LinkStateUnknown]; + optional bool is_transmit_on = 2 [default = false]; + optional bool is_capture_on = 3 [default = false]; +} + +message PortStats { + + required PortId port_id = 1; + + optional PortState state = 2; + + optional uint64 rx_pkts = 11; + optional uint64 rx_bytes = 12; + optional uint64 rx_pkts_nic = 13; + optional uint64 rx_bytes_nic = 14; + optional uint64 rx_pps = 15; + optional uint64 rx_bps = 16; + + optional uint64 tx_pkts = 21; + optional uint64 tx_bytes = 22; + optional uint64 tx_pkts_nic = 23; + optional uint64 tx_bytes_nic = 24; + optional uint64 tx_pps = 25; + optional uint64 tx_bps = 26; +} + +message PortStatsList { + repeated PortStats port_stats = 1; +} + +service OstService { + rpc getPortIdList(Void) returns (PortIdList); + rpc getPortConfig(PortIdList) returns (PortConfigList); + + rpc getStreamIdList(PortId) returns (StreamIdList); + rpc getStreamConfig(StreamIdList) returns (StreamConfigList); + rpc addStream(StreamIdList) returns (Ack); + rpc deleteStream(StreamIdList) returns (Ack); + rpc modifyStream(StreamConfigList) returns (Ack); + + rpc startTx(PortIdList) returns (Ack); + rpc stopTx(PortIdList) returns (Ack); + + rpc startCapture(PortIdList) returns (Ack); + rpc stopCapture(PortIdList) returns (Ack); + rpc getCaptureBuffer(PortId) returns (CaptureBuffer); + + rpc getStats(PortIdList) returns (PortStatsList); + rpc clearStats(PortIdList) returns (Ack); +} + diff --git a/rpc/pbhelper.h b/rpc/pbhelper.h index ba2b5fe..e87d4ca 100644 --- a/rpc/pbhelper.h +++ b/rpc/pbhelper.h @@ -1,151 +1,151 @@ -#ifndef _PB_HELPER_H -#define _PB_HELPER_H - -#include -#include - -#include - -#if 0 // not reqd. any longer? -class PbHelper -{ -public: - - // FIXME: Change msg from * to & - void ForceSetSingularDefault(::google::protobuf::Message *msg) - { - const ::google::protobuf::Descriptor *desc; - ::google::protobuf::Message::Reflection *refl; - - qDebug("In %s", __FUNCTION__); - - desc = msg->GetDescriptor(); - refl = msg->GetReflection(); - - for (int i=0; i < desc->field_count(); i++) - { - const ::google::protobuf::FieldDescriptor *f; - - f = desc->field(i); - - // Ensure field is singular and not already set - if (f->label() == - ::google::protobuf::FieldDescriptor::LABEL_REPEATED) - continue; - if (refl->HasField(f)) - continue; - - switch(f->type()) - { - case ::google::protobuf::FieldDescriptor::TYPE_DOUBLE: - refl->SetDouble(f, refl->GetDouble(f)); - break; - - case ::google::protobuf::FieldDescriptor::TYPE_FLOAT: - refl->SetFloat(f, refl->GetFloat(f)); - break; - - case ::google::protobuf::FieldDescriptor::TYPE_INT32: - case ::google::protobuf::FieldDescriptor::TYPE_SINT32: - case ::google::protobuf::FieldDescriptor::TYPE_SFIXED32: - refl->SetInt32(f, refl->GetInt32(f)); - break; - - case ::google::protobuf::FieldDescriptor::TYPE_INT64: - case ::google::protobuf::FieldDescriptor::TYPE_SINT64: - case ::google::protobuf::FieldDescriptor::TYPE_SFIXED64: - refl->SetInt64(f, refl->GetInt64(f)); - break; - - case ::google::protobuf::FieldDescriptor::TYPE_UINT32: - case ::google::protobuf::FieldDescriptor::TYPE_FIXED32: - refl->SetUInt32(f, refl->GetUInt32(f)); - break; - - case ::google::protobuf::FieldDescriptor::TYPE_UINT64: - case ::google::protobuf::FieldDescriptor::TYPE_FIXED64: - refl->SetUInt64(f, refl->GetUInt64(f)); - break; - - case ::google::protobuf::FieldDescriptor::TYPE_BOOL: - refl->SetBool(f, refl->GetBool(f)); - break; - - case ::google::protobuf::FieldDescriptor::TYPE_ENUM: - refl->SetEnum(f, refl->GetEnum(f)); - break; - - case ::google::protobuf::FieldDescriptor::TYPE_STRING: - case ::google::protobuf::FieldDescriptor::TYPE_BYTES: - refl->SetString(f, refl->GetString(f)); - break; - - case ::google::protobuf::FieldDescriptor::TYPE_MESSAGE: - case ::google::protobuf::FieldDescriptor::TYPE_GROUP: - ForceSetSingularDefault(refl->MutableMessage(f)); // recursion! - break; - - default: - qDebug("unhandled Field Type"); - break; - } - } - } - - bool update( - ::google::protobuf::Message *target, - ::google::protobuf::Message *source) - { - // FIXME(HI): Depracate: use MergeFrom() directly - qDebug("In %s", __FUNCTION__); - target->MergeFrom(*source); - return true; -#if 0 - ::google::protobuf::Message::Reflection *sourceRef; - ::google::protobuf::Message::Reflection *targetRef; - std::vector srcFieldList; - - - if (source->GetDescriptor()->full_name() != - target->GetDescriptor()->full_name()) - goto _error_exit; - - sourceRef = source->GetReflection(); - targetRef = target->GetReflection(); - - sourceRef->ListFields(&srcFieldList); - for (uint i=0; i < srcFieldList.size(); i++) - { - const ::google::protobuf::FieldDescriptor *srcField, *targetField; - - srcField = srcFieldList[i]; - targetField = target->GetDescriptor()->FindFieldByName( - srcField->name()); - - switch(targetField->type()) - { - case ::google::protobuf::FieldDescriptor::TYPE_UINT32: - targetRef->SetUInt32(targetField, - sourceRef->GetUInt32(srcField)); - break; - case ::google::protobuf::FieldDescriptor::TYPE_BOOL: - targetRef->SetBool(targetField, - sourceRef->GetBool(srcField)); - break; - case ::google::protobuf::FieldDescriptor::TYPE_STRING: - targetRef->SetString(targetField, - sourceRef->GetString(srcField)); - break; - default: - qDebug("unhandled Field Type"); - break; - } - } - _error_exit: - qDebug("%s: error!", __FUNCTION__); - return false; -#endif - } -}; -#endif -#endif +#ifndef _PB_HELPER_H +#define _PB_HELPER_H + +#include +#include + +#include + +#if 0 // not reqd. any longer? +class PbHelper +{ +public: + + // FIXME: Change msg from * to & + void ForceSetSingularDefault(::google::protobuf::Message *msg) + { + const ::google::protobuf::Descriptor *desc; + ::google::protobuf::Message::Reflection *refl; + + qDebug("In %s", __FUNCTION__); + + desc = msg->GetDescriptor(); + refl = msg->GetReflection(); + + for (int i=0; i < desc->field_count(); i++) + { + const ::google::protobuf::FieldDescriptor *f; + + f = desc->field(i); + + // Ensure field is singular and not already set + if (f->label() == + ::google::protobuf::FieldDescriptor::LABEL_REPEATED) + continue; + if (refl->HasField(f)) + continue; + + switch(f->type()) + { + case ::google::protobuf::FieldDescriptor::TYPE_DOUBLE: + refl->SetDouble(f, refl->GetDouble(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_FLOAT: + refl->SetFloat(f, refl->GetFloat(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_INT32: + case ::google::protobuf::FieldDescriptor::TYPE_SINT32: + case ::google::protobuf::FieldDescriptor::TYPE_SFIXED32: + refl->SetInt32(f, refl->GetInt32(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_INT64: + case ::google::protobuf::FieldDescriptor::TYPE_SINT64: + case ::google::protobuf::FieldDescriptor::TYPE_SFIXED64: + refl->SetInt64(f, refl->GetInt64(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_UINT32: + case ::google::protobuf::FieldDescriptor::TYPE_FIXED32: + refl->SetUInt32(f, refl->GetUInt32(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_UINT64: + case ::google::protobuf::FieldDescriptor::TYPE_FIXED64: + refl->SetUInt64(f, refl->GetUInt64(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_BOOL: + refl->SetBool(f, refl->GetBool(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_ENUM: + refl->SetEnum(f, refl->GetEnum(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_STRING: + case ::google::protobuf::FieldDescriptor::TYPE_BYTES: + refl->SetString(f, refl->GetString(f)); + break; + + case ::google::protobuf::FieldDescriptor::TYPE_MESSAGE: + case ::google::protobuf::FieldDescriptor::TYPE_GROUP: + ForceSetSingularDefault(refl->MutableMessage(f)); // recursion! + break; + + default: + qDebug("unhandled Field Type"); + break; + } + } + } + + bool update( + ::google::protobuf::Message *target, + ::google::protobuf::Message *source) + { + // FIXME(HI): Depracate: use MergeFrom() directly + qDebug("In %s", __FUNCTION__); + target->MergeFrom(*source); + return true; +#if 0 + ::google::protobuf::Message::Reflection *sourceRef; + ::google::protobuf::Message::Reflection *targetRef; + std::vector srcFieldList; + + + if (source->GetDescriptor()->full_name() != + target->GetDescriptor()->full_name()) + goto _error_exit; + + sourceRef = source->GetReflection(); + targetRef = target->GetReflection(); + + sourceRef->ListFields(&srcFieldList); + for (uint i=0; i < srcFieldList.size(); i++) + { + const ::google::protobuf::FieldDescriptor *srcField, *targetField; + + srcField = srcFieldList[i]; + targetField = target->GetDescriptor()->FindFieldByName( + srcField->name()); + + switch(targetField->type()) + { + case ::google::protobuf::FieldDescriptor::TYPE_UINT32: + targetRef->SetUInt32(targetField, + sourceRef->GetUInt32(srcField)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_BOOL: + targetRef->SetBool(targetField, + sourceRef->GetBool(srcField)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_STRING: + targetRef->SetString(targetField, + sourceRef->GetString(srcField)); + break; + default: + qDebug("unhandled Field Type"); + break; + } + } + _error_exit: + qDebug("%s: error!", __FUNCTION__); + return false; +#endif + } +}; +#endif +#endif diff --git a/rpc/pbrpc.pro b/rpc/pbrpc.pro index 3465da3..bcd5b8d 100644 --- a/rpc/pbrpc.pro +++ b/rpc/pbrpc.pro @@ -1,8 +1,8 @@ -TEMPLATE = lib -CONFIG += qt staticlib -QT += network -DEFINES += HAVE_REMOTE -INCLUDEPATH += "c:\msys\1.0\local\include" -LIBS += -L"C:\msys\1.0\local\lib" -lprotobuf -HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h -SOURCES += rpcserver.cpp pbrpcchannel.cpp +TEMPLATE = lib +CONFIG += qt staticlib +QT += network +DEFINES += HAVE_REMOTE +INCLUDEPATH += "c:\msys\1.0\local\include" +LIBS += -L"C:\msys\1.0\local\lib" -lprotobuf +HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h +SOURCES += rpcserver.cpp pbrpcchannel.cpp diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index 5c3626e..a06d14e 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -1,310 +1,310 @@ -#include "pbrpcchannel.h" - -PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) -{ - isPending = false; - pendingMethodId = -1; // don't care as long as isPending is false - - controller = NULL; - done = NULL; - response = NULL; - - mServerAddress = ip; - mServerPort = port; - mpSocket = new QTcpSocket(this); - - // FIXME: Not quite sure why this ain't working! - // QMetaObject::connectSlotsByName(this); - - connect(mpSocket, SIGNAL(connected()), - this, SLOT(on_mpSocket_connected())); - connect(mpSocket, SIGNAL(disconnected()), - this, SLOT(on_mpSocket_disconnected())); - connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), - this, SLOT(on_mpSocket_stateChanged(QAbstractSocket::SocketState))); - connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(on_mpSocket_error(QAbstractSocket::SocketError))); - - connect(mpSocket, SIGNAL(readyRead()), - this, SLOT(on_mpSocket_readyRead())); - -} - -PbRpcChannel::~PbRpcChannel() -{ - delete mpSocket; -} - -void PbRpcChannel::establish() -{ - qDebug("In %s", __FUNCTION__); - - mpSocket->connectToHost(mServerAddress, mServerPort); -} - -void PbRpcChannel::establish(QHostAddress ip, quint16 port) -{ - mServerAddress = ip; - mServerPort = port; - establish(); -} - -void PbRpcChannel::tearDown() -{ - qDebug("In %s", __FUNCTION__); - - mpSocket->disconnectFromHost(); -} - -void PbRpcChannel::CallMethod( - const ::google::protobuf::MethodDescriptor *method, - ::google::protobuf::RpcController *controller, - const ::google::protobuf::Message *req, - ::google::protobuf::Message *response, - ::google::protobuf::Closure* done) -{ - char msg[MSGBUF_SIZE]; - int len; - bool ret; - - if (isPending) - { - RpcCall call; - qDebug("RpcChannel: queueing method %d since %d is pending", - method->index(), pendingMethodId); - - call.method = method; - call.controller = controller; - call.request = req; - call.response = response; - call.done = done; - - pendingCallList.append(call); - - Q_ASSERT(pendingCallList.size() < 100); - - return; - } - - if (!req->IsInitialized()) - { - qWarning("RpcChannel: missing required fields in request"); - qDebug(req->InitializationErrorString().c_str()); - - qFatal("exiting"); - - controller->SetFailed("Required fields missing"); - done->Run(); - return; - } - - pendingMethodId = method->index(); - this->controller=controller; - this->done=done; - this->response=response; - isPending = true; - - ret = req->SerializeToArray((void*) (&msg[PB_HDR_SIZE]), sizeof(msg)); - Q_ASSERT(ret == true); - - len = req->ByteSize(); - *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_REQUEST); // type - *((quint16*)(&msg[2])) = HTONS(method->index()); // method id - *((quint32*)(&msg[4])) = HTONL(len); // len - - // Avoid printing stats since it happens every couple of seconds - if (pendingMethodId != 12) - { - qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, - PB_HDR_SIZE + len, req->DebugString().c_str()); - BUFDUMP(msg, PB_HDR_SIZE + len); - } - - mpSocket->write(msg, PB_HDR_SIZE + len); -} - -void PbRpcChannel::on_mpSocket_readyRead() -{ - char msg[MSGBUF_SIZE]; - char *p = (char*)&msg; - int msgLen; - static bool parsing = false; - static quint16 type, method; - static quint32 len; - - //qDebug("%s: bytesAvail = %d", __FUNCTION__, mpSocket->bytesAvailable()); - - if (!parsing) - { - // Do we have an entire header? If not, we'll wait ... - if (mpSocket->bytesAvailable() < PB_HDR_SIZE) - { - qDebug("client: not enough data available for a complete header"); - return; - } - - msgLen = mpSocket->read(msg, PB_HDR_SIZE); - - Q_ASSERT(msgLen == PB_HDR_SIZE); - - type = NTOHS(GET16(p+0)); - method = NTOHS(GET16(p+2)); - len = NTOHL(GET32(p+4)); - - //BUFDUMP(msg, PB_HDR_SIZE); - //qDebug("type = %hu, method = %hu, len = %u", type, method, len); - - parsing = true; - } - - switch (type) - { - case PB_MSG_TYPE_BINBLOB: - { - static quint32 cumLen = 0; - QIODevice *blob; - - blob = static_cast(controller)->binaryBlob(); - Q_ASSERT(blob != NULL); - - while ((cumLen < len) && mpSocket->bytesAvailable()) - { - int l; - - l = mpSocket->read(msg, sizeof(msg)); - blob->write(msg, l); - cumLen += l; - } - - qDebug("%s: bin blob rcvd %d/%d", __PRETTY_FUNCTION__, cumLen, len); - - if (cumLen < len) - return; - - cumLen = 0; - - if (!isPending) - { - qDebug("not waiting for response"); - goto _error_exit; - } - - if (pendingMethodId != method) - { - qDebug("invalid method id %d (expected = %d)", method, - pendingMethodId); - goto _error_exit; - } - - break; - } - - case PB_MSG_TYPE_RESPONSE: - // Wait till we have the entire message - if (mpSocket->bytesAvailable() < len) - { - qDebug("client: not enough data available for a complete msg"); - return; - } - - msgLen = mpSocket->read(msg, sizeof(msg)); - - Q_ASSERT((unsigned) msgLen == len); - - //qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); - //BUFDUMP(msg, msgLen); - - if (!isPending) - { - qDebug("not waiting for response"); - goto _error_exit; - } - - if (pendingMethodId != method) - { - qDebug("invalid method id %d (expected = %d)", method, - pendingMethodId); - goto _error_exit; - } - - response->ParseFromArray((void*) msg, len); - - // Avoid printing stats - if (method != 12) - { - qDebug("client(%s): Parsed as %s", __FUNCTION__, - response->DebugString().c_str()); - } - - if (!response->IsInitialized()) - { - qWarning("RpcChannel: missing required fields in response"); - qDebug(response->InitializationErrorString().c_str()); - - controller->SetFailed("Required fields missing"); - } - break; - - default: - qFatal("%s: unexpected type %d", __PRETTY_FUNCTION__, type); - goto _error_exit; - - } - - pendingMethodId = -1; - controller = NULL; - response = NULL; - isPending = false; - parsing = false; - - done->Run(); - - if (pendingCallList.size()) - { - RpcCall call = pendingCallList.takeFirst(); - CallMethod(call.method, call.controller, call.request, call.response, - call.done); - } - - return; - -_error_exit: - parsing = false; - qDebug("client(%s) discarding received msg", __FUNCTION__); - return; -} - -void PbRpcChannel::on_mpSocket_stateChanged( - QAbstractSocket::SocketState socketState) -{ - qDebug("In %s", __FUNCTION__); - emit stateChanged(socketState); -} - -void PbRpcChannel::on_mpSocket_connected() -{ - qDebug("In %s", __FUNCTION__); - emit connected(); -} - -void PbRpcChannel::on_mpSocket_disconnected() -{ - qDebug("In %s", __FUNCTION__); - - pendingMethodId = -1; - controller = NULL; - response = NULL; - isPending = false; - // \todo convert parsing from static to data member - //parsing = false - pendingCallList.clear(); - - emit disconnected(); -} - -void PbRpcChannel::on_mpSocket_error(QAbstractSocket::SocketError socketError) -{ - qDebug("In %s", __FUNCTION__); - emit error(socketError); -} - +#include "pbrpcchannel.h" + +PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) +{ + isPending = false; + pendingMethodId = -1; // don't care as long as isPending is false + + controller = NULL; + done = NULL; + response = NULL; + + mServerAddress = ip; + mServerPort = port; + mpSocket = new QTcpSocket(this); + + // FIXME: Not quite sure why this ain't working! + // QMetaObject::connectSlotsByName(this); + + connect(mpSocket, SIGNAL(connected()), + this, SLOT(on_mpSocket_connected())); + connect(mpSocket, SIGNAL(disconnected()), + this, SLOT(on_mpSocket_disconnected())); + connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(on_mpSocket_stateChanged(QAbstractSocket::SocketState))); + connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_mpSocket_error(QAbstractSocket::SocketError))); + + connect(mpSocket, SIGNAL(readyRead()), + this, SLOT(on_mpSocket_readyRead())); + +} + +PbRpcChannel::~PbRpcChannel() +{ + delete mpSocket; +} + +void PbRpcChannel::establish() +{ + qDebug("In %s", __FUNCTION__); + + mpSocket->connectToHost(mServerAddress, mServerPort); +} + +void PbRpcChannel::establish(QHostAddress ip, quint16 port) +{ + mServerAddress = ip; + mServerPort = port; + establish(); +} + +void PbRpcChannel::tearDown() +{ + qDebug("In %s", __FUNCTION__); + + mpSocket->disconnectFromHost(); +} + +void PbRpcChannel::CallMethod( + const ::google::protobuf::MethodDescriptor *method, + ::google::protobuf::RpcController *controller, + const ::google::protobuf::Message *req, + ::google::protobuf::Message *response, + ::google::protobuf::Closure* done) +{ + char msg[MSGBUF_SIZE]; + int len; + bool ret; + + if (isPending) + { + RpcCall call; + qDebug("RpcChannel: queueing method %d since %d is pending", + method->index(), pendingMethodId); + + call.method = method; + call.controller = controller; + call.request = req; + call.response = response; + call.done = done; + + pendingCallList.append(call); + + Q_ASSERT(pendingCallList.size() < 100); + + return; + } + + if (!req->IsInitialized()) + { + qWarning("RpcChannel: missing required fields in request"); + qDebug(req->InitializationErrorString().c_str()); + + qFatal("exiting"); + + controller->SetFailed("Required fields missing"); + done->Run(); + return; + } + + pendingMethodId = method->index(); + this->controller=controller; + this->done=done; + this->response=response; + isPending = true; + + ret = req->SerializeToArray((void*) (&msg[PB_HDR_SIZE]), sizeof(msg)); + Q_ASSERT(ret == true); + + len = req->ByteSize(); + *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_REQUEST); // type + *((quint16*)(&msg[2])) = HTONS(method->index()); // method id + *((quint32*)(&msg[4])) = HTONL(len); // len + + // Avoid printing stats since it happens every couple of seconds + if (pendingMethodId != 12) + { + qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, + PB_HDR_SIZE + len, req->DebugString().c_str()); + BUFDUMP(msg, PB_HDR_SIZE + len); + } + + mpSocket->write(msg, PB_HDR_SIZE + len); +} + +void PbRpcChannel::on_mpSocket_readyRead() +{ + char msg[MSGBUF_SIZE]; + char *p = (char*)&msg; + int msgLen; + static bool parsing = false; + static quint16 type, method; + static quint32 len; + + //qDebug("%s: bytesAvail = %d", __FUNCTION__, mpSocket->bytesAvailable()); + + if (!parsing) + { + // Do we have an entire header? If not, we'll wait ... + if (mpSocket->bytesAvailable() < PB_HDR_SIZE) + { + qDebug("client: not enough data available for a complete header"); + return; + } + + msgLen = mpSocket->read(msg, PB_HDR_SIZE); + + Q_ASSERT(msgLen == PB_HDR_SIZE); + + type = NTOHS(GET16(p+0)); + method = NTOHS(GET16(p+2)); + len = NTOHL(GET32(p+4)); + + //BUFDUMP(msg, PB_HDR_SIZE); + //qDebug("type = %hu, method = %hu, len = %u", type, method, len); + + parsing = true; + } + + switch (type) + { + case PB_MSG_TYPE_BINBLOB: + { + static quint32 cumLen = 0; + QIODevice *blob; + + blob = static_cast(controller)->binaryBlob(); + Q_ASSERT(blob != NULL); + + while ((cumLen < len) && mpSocket->bytesAvailable()) + { + int l; + + l = mpSocket->read(msg, sizeof(msg)); + blob->write(msg, l); + cumLen += l; + } + + qDebug("%s: bin blob rcvd %d/%d", __PRETTY_FUNCTION__, cumLen, len); + + if (cumLen < len) + return; + + cumLen = 0; + + if (!isPending) + { + qDebug("not waiting for response"); + goto _error_exit; + } + + if (pendingMethodId != method) + { + qDebug("invalid method id %d (expected = %d)", method, + pendingMethodId); + goto _error_exit; + } + + break; + } + + case PB_MSG_TYPE_RESPONSE: + // Wait till we have the entire message + if (mpSocket->bytesAvailable() < len) + { + qDebug("client: not enough data available for a complete msg"); + return; + } + + msgLen = mpSocket->read(msg, sizeof(msg)); + + Q_ASSERT((unsigned) msgLen == len); + + //qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); + //BUFDUMP(msg, msgLen); + + if (!isPending) + { + qDebug("not waiting for response"); + goto _error_exit; + } + + if (pendingMethodId != method) + { + qDebug("invalid method id %d (expected = %d)", method, + pendingMethodId); + goto _error_exit; + } + + response->ParseFromArray((void*) msg, len); + + // Avoid printing stats + if (method != 12) + { + qDebug("client(%s): Parsed as %s", __FUNCTION__, + response->DebugString().c_str()); + } + + if (!response->IsInitialized()) + { + qWarning("RpcChannel: missing required fields in response"); + qDebug(response->InitializationErrorString().c_str()); + + controller->SetFailed("Required fields missing"); + } + break; + + default: + qFatal("%s: unexpected type %d", __PRETTY_FUNCTION__, type); + goto _error_exit; + + } + + pendingMethodId = -1; + controller = NULL; + response = NULL; + isPending = false; + parsing = false; + + done->Run(); + + if (pendingCallList.size()) + { + RpcCall call = pendingCallList.takeFirst(); + CallMethod(call.method, call.controller, call.request, call.response, + call.done); + } + + return; + +_error_exit: + parsing = false; + qDebug("client(%s) discarding received msg", __FUNCTION__); + return; +} + +void PbRpcChannel::on_mpSocket_stateChanged( + QAbstractSocket::SocketState socketState) +{ + qDebug("In %s", __FUNCTION__); + emit stateChanged(socketState); +} + +void PbRpcChannel::on_mpSocket_connected() +{ + qDebug("In %s", __FUNCTION__); + emit connected(); +} + +void PbRpcChannel::on_mpSocket_disconnected() +{ + qDebug("In %s", __FUNCTION__); + + pendingMethodId = -1; + controller = NULL; + response = NULL; + isPending = false; + // \todo convert parsing from static to data member + //parsing = false + pendingCallList.clear(); + + emit disconnected(); +} + +void PbRpcChannel::on_mpSocket_error(QAbstractSocket::SocketError socketError) +{ + qDebug("In %s", __FUNCTION__); + emit error(socketError); +} + diff --git a/rpc/pbrpcchannel.h b/rpc/pbrpcchannel.h index e467781..8c2efbc 100644 --- a/rpc/pbrpcchannel.h +++ b/rpc/pbrpcchannel.h @@ -1,83 +1,83 @@ -#ifndef _PB_RPC_CHANNEL_H -#define _PB_RPC_CHANNEL_H - -#include -#include - -#include -#include -#include - -#include "pbrpccommon.h" -#include "pbrpccontroller.h" - -class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel -{ - Q_OBJECT - - // If isPending is TRUE, then controller, done, response - // and pendingMethodId correspond to the last method called by - // the service stub - bool isPending; - int pendingMethodId; - - // controller, done, response are set to the corresponding values - // passed by the stub to CallMethod(). They are reset to NULL when - // we get a response back from the server in on_mpSocket_readyRead() - // after calling done->Run(). - - /*! \todo (MED) : change controller, done and response to references - instead of pointers? */ - ::google::protobuf::RpcController *controller; - ::google::protobuf::Closure *done; - ::google::protobuf::Message *response; - - typedef struct _RpcCall { - const ::google::protobuf::MethodDescriptor *method; - ::google::protobuf::RpcController *controller; - const ::google::protobuf::Message *request; - ::google::protobuf::Message *response; - ::google::protobuf::Closure *done; - } RpcCall; - QList pendingCallList; - - QHostAddress mServerAddress; - quint16 mServerPort; - QTcpSocket *mpSocket; - -public: - PbRpcChannel(QHostAddress ip, quint16 port); - ~PbRpcChannel(); - - void establish(); - void establish(QHostAddress ip, quint16 port); - void tearDown(); - - const QHostAddress& serverAddress() const { return mServerAddress; } - quint16 serverPort() const { return mServerPort; } - - QAbstractSocket::SocketState state() const - { return mpSocket->state(); } - - void CallMethod(const ::google::protobuf::MethodDescriptor *method, - ::google::protobuf::RpcController *controller, - const ::google::protobuf::Message *req, - ::google::protobuf::Message *response, - ::google::protobuf::Closure* done); - -signals: - void connected(); - void disconnected(); - void error(QAbstractSocket::SocketError socketError); - void stateChanged(QAbstractSocket::SocketState socketState); - -private slots: - void on_mpSocket_connected(); - void on_mpSocket_disconnected(); - void on_mpSocket_stateChanged(QAbstractSocket::SocketState socketState); - void on_mpSocket_error(QAbstractSocket::SocketError socketError); - - void on_mpSocket_readyRead(); -}; - -#endif +#ifndef _PB_RPC_CHANNEL_H +#define _PB_RPC_CHANNEL_H + +#include +#include + +#include +#include +#include + +#include "pbrpccommon.h" +#include "pbrpccontroller.h" + +class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel +{ + Q_OBJECT + + // If isPending is TRUE, then controller, done, response + // and pendingMethodId correspond to the last method called by + // the service stub + bool isPending; + int pendingMethodId; + + // controller, done, response are set to the corresponding values + // passed by the stub to CallMethod(). They are reset to NULL when + // we get a response back from the server in on_mpSocket_readyRead() + // after calling done->Run(). + + /*! \todo (MED) : change controller, done and response to references + instead of pointers? */ + ::google::protobuf::RpcController *controller; + ::google::protobuf::Closure *done; + ::google::protobuf::Message *response; + + typedef struct _RpcCall { + const ::google::protobuf::MethodDescriptor *method; + ::google::protobuf::RpcController *controller; + const ::google::protobuf::Message *request; + ::google::protobuf::Message *response; + ::google::protobuf::Closure *done; + } RpcCall; + QList pendingCallList; + + QHostAddress mServerAddress; + quint16 mServerPort; + QTcpSocket *mpSocket; + +public: + PbRpcChannel(QHostAddress ip, quint16 port); + ~PbRpcChannel(); + + void establish(); + void establish(QHostAddress ip, quint16 port); + void tearDown(); + + const QHostAddress& serverAddress() const { return mServerAddress; } + quint16 serverPort() const { return mServerPort; } + + QAbstractSocket::SocketState state() const + { return mpSocket->state(); } + + void CallMethod(const ::google::protobuf::MethodDescriptor *method, + ::google::protobuf::RpcController *controller, + const ::google::protobuf::Message *req, + ::google::protobuf::Message *response, + ::google::protobuf::Closure* done); + +signals: + void connected(); + void disconnected(); + void error(QAbstractSocket::SocketError socketError); + void stateChanged(QAbstractSocket::SocketState socketState); + +private slots: + void on_mpSocket_connected(); + void on_mpSocket_disconnected(); + void on_mpSocket_stateChanged(QAbstractSocket::SocketState socketState); + void on_mpSocket_error(QAbstractSocket::SocketError socketError); + + void on_mpSocket_readyRead(); +}; + +#endif diff --git a/rpc/pbrpccommon.h b/rpc/pbrpccommon.h index 4ea1281..12040ee 100644 --- a/rpc/pbrpccommon.h +++ b/rpc/pbrpccommon.h @@ -1,61 +1,61 @@ -#ifndef _PB_RPC_COMMON_H -#define _PB_RPC_COMMON_H - -//! \todo (LOW) check which one is right - wrong one seems to be working!!!!! -#if 0 -#define GET16(p) (quint16)( \ - (*((quint8*)(p)+0) << 8 ) \ - | (*((quint8*)(p)+1))) -#else -#define GET16(p) (quint16)( \ - (*((quint8*)(p)+1) << 8 ) \ - | (*((quint8*)(p)+0))) -#define GET32(p) (quint32)( \ - (*((quint8*)(p)+3) << 24) \ - | (*((quint8*)(p)+2) << 16) \ - | (*((quint8*)(p)+1) << 8 ) \ - | (*((quint8*)(p)+0))) -#endif - -#define BYTESWAP4(x) \ - (((x & 0xFF000000) >> 24) | \ - ((x & 0x00FF0000) >> 8) | \ - ((x & 0x0000FF00) << 8) | \ - ((x & 0x000000FF) << 24)) - -#define BYTESWAP2(x) \ - (((x & 0xFF00) >> 8) | \ - ((x & 0x00FF) << 8)) - -//! \todo (LOW) : portability -#if 1 -#define HTONL(x) BYTESWAP4(x) -#define NTOHL(x) BYTESWAP4(x) -#define HTONS(x) BYTESWAP2(x) -#define NTOHS(x) BYTESWAP2(x) -#else -#define HTONL(x) (x) -#define NTOHL(x) (x) -#define HTONS(x) (x) -#define NTOHS(x) (x) -#endif - -// Print a HexDump -#define BUFDUMP(ptr, len) qDebug("%s", QString(QByteArray((char*)(ptr), \ - (len)).toHex()).toAscii().data()); - -/* -** RPC Header (8) -** - MSG_TYPE (2) -** - METHOD_ID (2) -** - LEN (4) [not including this header] -*/ -#define PB_HDR_SIZE 8 - -#define PB_MSG_TYPE_REQUEST 1 -#define PB_MSG_TYPE_RESPONSE 2 -#define PB_MSG_TYPE_BINBLOB 3 - -#define MSGBUF_SIZE 4096 - -#endif +#ifndef _PB_RPC_COMMON_H +#define _PB_RPC_COMMON_H + +//! \todo (LOW) check which one is right - wrong one seems to be working!!!!! +#if 0 +#define GET16(p) (quint16)( \ + (*((quint8*)(p)+0) << 8 ) \ + | (*((quint8*)(p)+1))) +#else +#define GET16(p) (quint16)( \ + (*((quint8*)(p)+1) << 8 ) \ + | (*((quint8*)(p)+0))) +#define GET32(p) (quint32)( \ + (*((quint8*)(p)+3) << 24) \ + | (*((quint8*)(p)+2) << 16) \ + | (*((quint8*)(p)+1) << 8 ) \ + | (*((quint8*)(p)+0))) +#endif + +#define BYTESWAP4(x) \ + (((x & 0xFF000000) >> 24) | \ + ((x & 0x00FF0000) >> 8) | \ + ((x & 0x0000FF00) << 8) | \ + ((x & 0x000000FF) << 24)) + +#define BYTESWAP2(x) \ + (((x & 0xFF00) >> 8) | \ + ((x & 0x00FF) << 8)) + +//! \todo (LOW) : portability +#if 1 +#define HTONL(x) BYTESWAP4(x) +#define NTOHL(x) BYTESWAP4(x) +#define HTONS(x) BYTESWAP2(x) +#define NTOHS(x) BYTESWAP2(x) +#else +#define HTONL(x) (x) +#define NTOHL(x) (x) +#define HTONS(x) (x) +#define NTOHS(x) (x) +#endif + +// Print a HexDump +#define BUFDUMP(ptr, len) qDebug("%s", QString(QByteArray((char*)(ptr), \ + (len)).toHex()).toAscii().data()); + +/* +** RPC Header (8) +** - MSG_TYPE (2) +** - METHOD_ID (2) +** - LEN (4) [not including this header] +*/ +#define PB_HDR_SIZE 8 + +#define PB_MSG_TYPE_REQUEST 1 +#define PB_MSG_TYPE_RESPONSE 2 +#define PB_MSG_TYPE_BINBLOB 3 + +#define MSGBUF_SIZE 4096 + +#endif diff --git a/rpc/pbrpccontroller.h b/rpc/pbrpccontroller.h index b446c73..99acc5a 100644 --- a/rpc/pbrpccontroller.h +++ b/rpc/pbrpccontroller.h @@ -1,34 +1,34 @@ -#ifndef _PB_RPC_CONTROLLER_H -#define _PB_RPC_CONTROLLER_H - -#include - -class QIODevice; - -class PbRpcController : public ::google::protobuf::RpcController -{ - bool failed; - QIODevice *blob; - std::string errStr; - -public: - PbRpcController() { Reset(); } - - // Client Side Methods - void Reset() { failed=false; blob = NULL; } - bool Failed() const { return failed; } - void StartCancel() { /*! \todo (MED) */} - std::string ErrorText() const { return errStr; } - - // Server Side Methods - void SetFailed(const std::string &reason) - { failed = true; errStr = reason; } - bool IsCanceled() const { return false; }; - void NotifyOnCancel(::google::protobuf::Closure *callback) { /*! \todo (MED) */ } - - // srivatsp added - QIODevice* binaryBlob() { return blob; }; - void setBinaryBlob(QIODevice *binaryBlob) { blob = binaryBlob; }; -}; - -#endif +#ifndef _PB_RPC_CONTROLLER_H +#define _PB_RPC_CONTROLLER_H + +#include + +class QIODevice; + +class PbRpcController : public ::google::protobuf::RpcController +{ + bool failed; + QIODevice *blob; + std::string errStr; + +public: + PbRpcController() { Reset(); } + + // Client Side Methods + void Reset() { failed=false; blob = NULL; } + bool Failed() const { return failed; } + void StartCancel() { /*! \todo (MED) */} + std::string ErrorText() const { return errStr; } + + // Server Side Methods + void SetFailed(const std::string &reason) + { failed = true; errStr = reason; } + bool IsCanceled() const { return false; }; + void NotifyOnCancel(::google::protobuf::Closure *callback) { /*! \todo (MED) */ } + + // srivatsp added + QIODevice* binaryBlob() { return blob; }; + void setBinaryBlob(QIODevice *binaryBlob) { blob = binaryBlob; }; +}; + +#endif diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index 804c4ee..d85c753 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -1,256 +1,256 @@ -//#include "pbhelper.h" -#include "rpcserver.h" - -RpcServer::RpcServer() -{ - server = NULL; - clientSock = NULL; - - service = NULL; - - isPending = false; - pendingMethodId = -1; // don't care as long as isPending is false -} - -RpcServer::~RpcServer() -{ - if (server) - delete server; -} - -bool RpcServer::registerService(::google::protobuf::Service *service, - quint16 tcpPortNum) -{ - this->service = service; - - server = new QTcpServer(); - connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); - if (!server->listen(QHostAddress::Any, tcpPortNum)) - { - qDebug("Unable to start the server: %s", - server->errorString().toAscii().constData()); - errorString_ = QString("Error starting Ostinato server: %1").arg( - server->errorString()); - return false; - } - - qDebug("The server is running on %s: %d", - server->serverAddress().toString().toAscii().constData(), - server->serverPort()); - errorString_ = QString(); - return true; -} - -QString RpcServer::errorString() -{ - return errorString_; -} - -void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController) -{ - QIODevice *blob; - char msg[MSGBUF_SIZE]; - int len; - - //qDebug("In RpcServer::done"); - - if (PbRpcController->Failed()) - { - qDebug("rpc failed"); - goto _exit; - } - - blob = PbRpcController->binaryBlob(); - if (blob) - { - len = blob->size(); - qDebug("is binary blob of len %d", len); - - *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_BINBLOB); // type - *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method - (*(quint32*)(&msg[4])) = HTONL(len); // len - - clientSock->write(msg, PB_HDR_SIZE); - - blob->seek(0); - while (!blob->atEnd()) - { - int l; - - len = blob->read(msg, sizeof(msg)); - l = clientSock->write(msg, len); - Q_ASSERT(l == len); - } - - goto _exit; - } - - if (!resp->IsInitialized()) - { - qWarning("response missing required fields!!"); - qDebug(resp->InitializationErrorString().c_str()); - qFatal("exiting"); - goto _exit; - } - - resp->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg)); - - len = resp->ByteSize(); - - *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_RESPONSE); // type - *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method - *((quint32*)(&msg[4])) = HTONL(len); // len - - // Avoid printing stats since it happens once every couple of seconds - if (pendingMethodId != 12) - { - qDebug("Server(%s): sending %d bytes to client encoding <%s>", - __FUNCTION__, len + PB_HDR_SIZE, resp->DebugString().c_str()); - //BUFDUMP(msg, len + 8); - } - - clientSock->write(msg, PB_HDR_SIZE + len); - -_exit: - delete PbRpcController; - isPending = false; -} - -void RpcServer::when_newConnection() -{ - if (clientSock) - { - QTcpSocket *sock; - - qDebug("already connected, no new connections will be accepted"); - - // Accept and close connection - //! \todo (MED) Send reason msg to client - sock = server->nextPendingConnection(); - sock->disconnectFromHost(); - sock->deleteLater(); - goto _exit; - } - - clientSock = server->nextPendingConnection(); - qDebug("accepting new connection from %s: %d", - clientSock->peerAddress().toString().toAscii().constData(), - clientSock->peerPort()); - - connect(clientSock, SIGNAL(readyRead()), - this, SLOT(when_dataAvail())); - connect(clientSock, SIGNAL(disconnected()), - this, SLOT(when_disconnected())); - connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(when_error(QAbstractSocket::SocketError))); - -_exit: - return; -} - -void RpcServer::when_disconnected() -{ - qDebug("connection closed from %s: %d", - clientSock->peerAddress().toString().toAscii().constData(), - clientSock->peerPort()); - - clientSock->deleteLater(); - clientSock = NULL; -} - -void RpcServer::when_error(QAbstractSocket::SocketError socketError) -{ - qDebug("%s", clientSock->errorString().toAscii().constData()); -} - -void RpcServer::when_dataAvail() -{ - char msg[MSGBUF_SIZE]; - int msgLen; - static bool parsing = false; - static quint16 type, method; - static quint32 len; - const ::google::protobuf::MethodDescriptor *methodDesc; - ::google::protobuf::Message *req, *resp; - PbRpcController *controller; - - if (!parsing) - { - if (clientSock->bytesAvailable() < PB_HDR_SIZE) - return; - - msgLen = clientSock->read(msg, PB_HDR_SIZE); - - Q_ASSERT(msgLen == PB_HDR_SIZE); - - type = NTOHS(GET16(&msg[0])); - method = NTOHS(GET16(&msg[2])); - len = NTOHL(GET32(&msg[4])); - //qDebug("type = %d, method = %d, len = %d", type, method, len); - - parsing = true; - } - - if (clientSock->bytesAvailable() < len) - return; - - msgLen = clientSock->read(msg, sizeof(msg)); - Q_ASSERT((unsigned) msgLen == len); - - if (type != PB_MSG_TYPE_REQUEST) - { - qDebug("server(%s): unexpected msg type %d (expected %d)", __FUNCTION__, - type, PB_MSG_TYPE_REQUEST); - goto _error_exit; - } - - methodDesc = service->GetDescriptor()->method(method); - if (!methodDesc) - { - qDebug("server(%s): invalid method id %d", __FUNCTION__, method); - goto _error_exit; //! \todo Return Error to client - } - - if (isPending) - { - qDebug("server(%s): rpc pending, try again", __FUNCTION__); - goto _error_exit; //! \todo Return Error to client - } - - pendingMethodId = method; - isPending = true; - - req = service->GetRequestPrototype(methodDesc).New(); - resp = service->GetResponsePrototype(methodDesc).New(); - - req->ParseFromArray((void*)msg, len); - if (!req->IsInitialized()) - { - qWarning("Missing required fields in request"); - qDebug(req->InitializationErrorString().c_str()); - qFatal("exiting"); - delete req; - delete resp; - - goto _error_exit; - } - //qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, - //resp->DebugString().c_str()); - - controller = new PbRpcController; - - //qDebug("before service->callmethod()"); - - service->CallMethod(methodDesc, controller, req, resp, - NewCallback(this, &RpcServer::done, resp, controller)); - - parsing = false; - - return; - -_error_exit: - parsing = false; - qDebug("server(%s): discarding msg from client", __FUNCTION__); - return; -} - +//#include "pbhelper.h" +#include "rpcserver.h" + +RpcServer::RpcServer() +{ + server = NULL; + clientSock = NULL; + + service = NULL; + + isPending = false; + pendingMethodId = -1; // don't care as long as isPending is false +} + +RpcServer::~RpcServer() +{ + if (server) + delete server; +} + +bool RpcServer::registerService(::google::protobuf::Service *service, + quint16 tcpPortNum) +{ + this->service = service; + + server = new QTcpServer(); + connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); + if (!server->listen(QHostAddress::Any, tcpPortNum)) + { + qDebug("Unable to start the server: %s", + server->errorString().toAscii().constData()); + errorString_ = QString("Error starting Ostinato server: %1").arg( + server->errorString()); + return false; + } + + qDebug("The server is running on %s: %d", + server->serverAddress().toString().toAscii().constData(), + server->serverPort()); + errorString_ = QString(); + return true; +} + +QString RpcServer::errorString() +{ + return errorString_; +} + +void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController) +{ + QIODevice *blob; + char msg[MSGBUF_SIZE]; + int len; + + //qDebug("In RpcServer::done"); + + if (PbRpcController->Failed()) + { + qDebug("rpc failed"); + goto _exit; + } + + blob = PbRpcController->binaryBlob(); + if (blob) + { + len = blob->size(); + qDebug("is binary blob of len %d", len); + + *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_BINBLOB); // type + *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method + (*(quint32*)(&msg[4])) = HTONL(len); // len + + clientSock->write(msg, PB_HDR_SIZE); + + blob->seek(0); + while (!blob->atEnd()) + { + int l; + + len = blob->read(msg, sizeof(msg)); + l = clientSock->write(msg, len); + Q_ASSERT(l == len); + } + + goto _exit; + } + + if (!resp->IsInitialized()) + { + qWarning("response missing required fields!!"); + qDebug(resp->InitializationErrorString().c_str()); + qFatal("exiting"); + goto _exit; + } + + resp->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg)); + + len = resp->ByteSize(); + + *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_RESPONSE); // type + *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method + *((quint32*)(&msg[4])) = HTONL(len); // len + + // Avoid printing stats since it happens once every couple of seconds + if (pendingMethodId != 12) + { + qDebug("Server(%s): sending %d bytes to client encoding <%s>", + __FUNCTION__, len + PB_HDR_SIZE, resp->DebugString().c_str()); + //BUFDUMP(msg, len + 8); + } + + clientSock->write(msg, PB_HDR_SIZE + len); + +_exit: + delete PbRpcController; + isPending = false; +} + +void RpcServer::when_newConnection() +{ + if (clientSock) + { + QTcpSocket *sock; + + qDebug("already connected, no new connections will be accepted"); + + // Accept and close connection + //! \todo (MED) Send reason msg to client + sock = server->nextPendingConnection(); + sock->disconnectFromHost(); + sock->deleteLater(); + goto _exit; + } + + clientSock = server->nextPendingConnection(); + qDebug("accepting new connection from %s: %d", + clientSock->peerAddress().toString().toAscii().constData(), + clientSock->peerPort()); + + connect(clientSock, SIGNAL(readyRead()), + this, SLOT(when_dataAvail())); + connect(clientSock, SIGNAL(disconnected()), + this, SLOT(when_disconnected())); + connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(when_error(QAbstractSocket::SocketError))); + +_exit: + return; +} + +void RpcServer::when_disconnected() +{ + qDebug("connection closed from %s: %d", + clientSock->peerAddress().toString().toAscii().constData(), + clientSock->peerPort()); + + clientSock->deleteLater(); + clientSock = NULL; +} + +void RpcServer::when_error(QAbstractSocket::SocketError socketError) +{ + qDebug("%s", clientSock->errorString().toAscii().constData()); +} + +void RpcServer::when_dataAvail() +{ + char msg[MSGBUF_SIZE]; + int msgLen; + static bool parsing = false; + static quint16 type, method; + static quint32 len; + const ::google::protobuf::MethodDescriptor *methodDesc; + ::google::protobuf::Message *req, *resp; + PbRpcController *controller; + + if (!parsing) + { + if (clientSock->bytesAvailable() < PB_HDR_SIZE) + return; + + msgLen = clientSock->read(msg, PB_HDR_SIZE); + + Q_ASSERT(msgLen == PB_HDR_SIZE); + + type = NTOHS(GET16(&msg[0])); + method = NTOHS(GET16(&msg[2])); + len = NTOHL(GET32(&msg[4])); + //qDebug("type = %d, method = %d, len = %d", type, method, len); + + parsing = true; + } + + if (clientSock->bytesAvailable() < len) + return; + + msgLen = clientSock->read(msg, sizeof(msg)); + Q_ASSERT((unsigned) msgLen == len); + + if (type != PB_MSG_TYPE_REQUEST) + { + qDebug("server(%s): unexpected msg type %d (expected %d)", __FUNCTION__, + type, PB_MSG_TYPE_REQUEST); + goto _error_exit; + } + + methodDesc = service->GetDescriptor()->method(method); + if (!methodDesc) + { + qDebug("server(%s): invalid method id %d", __FUNCTION__, method); + goto _error_exit; //! \todo Return Error to client + } + + if (isPending) + { + qDebug("server(%s): rpc pending, try again", __FUNCTION__); + goto _error_exit; //! \todo Return Error to client + } + + pendingMethodId = method; + isPending = true; + + req = service->GetRequestPrototype(methodDesc).New(); + resp = service->GetResponsePrototype(methodDesc).New(); + + req->ParseFromArray((void*)msg, len); + if (!req->IsInitialized()) + { + qWarning("Missing required fields in request"); + qDebug(req->InitializationErrorString().c_str()); + qFatal("exiting"); + delete req; + delete resp; + + goto _error_exit; + } + //qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, + //resp->DebugString().c_str()); + + controller = new PbRpcController; + + //qDebug("before service->callmethod()"); + + service->CallMethod(methodDesc, controller, req, resp, + NewCallback(this, &RpcServer::done, resp, controller)); + + parsing = false; + + return; + +_error_exit: + parsing = false; + qDebug("server(%s): discarding msg from client", __FUNCTION__); + return; +} + diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h index e353628..f4be419 100644 --- a/rpc/rpcserver.h +++ b/rpc/rpcserver.h @@ -1,44 +1,44 @@ -#ifndef _RPC_SERVER_H -#define _RPC_SERVER_H - -#include -#include -#include - -#include -#include - -#include "pbrpccommon.h" -#include "pbrpccontroller.h" - - -class RpcServer : public QObject -{ - Q_OBJECT - - QTcpServer *server; - QTcpSocket *clientSock; - - ::google::protobuf::Service *service; - - bool isPending; - int pendingMethodId; - QString errorString_; - -public: - RpcServer(); //! \todo (LOW) use 'parent' param - virtual ~RpcServer(); - - bool registerService(::google::protobuf::Service *service, - quint16 tcpPortNum); - QString errorString(); - void done(::google::protobuf::Message *resp, PbRpcController *controller); - -private slots: - void when_newConnection(); - void when_disconnected(); - void when_dataAvail(); - void when_error(QAbstractSocket::SocketError socketError); -}; - -#endif +#ifndef _RPC_SERVER_H +#define _RPC_SERVER_H + +#include +#include +#include + +#include +#include + +#include "pbrpccommon.h" +#include "pbrpccontroller.h" + + +class RpcServer : public QObject +{ + Q_OBJECT + + QTcpServer *server; + QTcpSocket *clientSock; + + ::google::protobuf::Service *service; + + bool isPending; + int pendingMethodId; + QString errorString_; + +public: + RpcServer(); //! \todo (LOW) use 'parent' param + virtual ~RpcServer(); + + bool registerService(::google::protobuf::Service *service, + quint16 tcpPortNum); + QString errorString(); + void done(::google::protobuf::Message *resp, PbRpcController *controller); + +private slots: + void when_newConnection(); + void when_disconnected(); + void when_dataAvail(); + void when_error(QAbstractSocket::SocketError socketError); +}; + +#endif diff --git a/server/drone.cpp b/server/drone.cpp index d7609de..9dcccc8 100644 --- a/server/drone.cpp +++ b/server/drone.cpp @@ -1,76 +1,76 @@ -#include "drone.h" - -#include "rpcserver.h" -#include "myservice.h" - -#include -#include - -extern int myport; - -Drone::Drone(QWidget *parent) - : QWidget(parent) -{ - setupUi(this); - - rpcServer = new RpcServer(); - service = new MyService(); -} - -Drone::~Drone() -{ - trayIcon_->hide(); - delete rpcServer; - delete service; -} - -bool Drone::init() -{ - Q_ASSERT(rpcServer); - - if (!rpcServer->registerService(service, myport ? myport : 7878)) - { - QMessageBox::critical(0, qApp->applicationName(), - rpcServer->errorString()); - return false; - } - - trayIconMenu_ = new QMenu(this); - - trayIconMenu_->addAction(actionShow); - trayIconMenu_->addAction(actionExit); - trayIconMenu_->setDefaultAction(actionShow); - trayIcon_ = new QSystemTrayIcon(); - trayIcon_->setIcon(QIcon(":/icons/portgroup.png")); - trayIcon_->setToolTip(qApp->applicationName()); - trayIcon_->setContextMenu(trayIconMenu_); - trayIcon_->show(); - - connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); - connect(this, SIGNAL(hideMe(bool)), this, SLOT(setHidden(bool)), - Qt::QueuedConnection); - - return true; -} - -void Drone::changeEvent(QEvent *event) -{ - if (event->type() == QEvent::WindowStateChange && isMinimized()) - { - emit hideMe(true); - event->ignore(); - return; - } - - QWidget::changeEvent(event); -} - -void Drone::trayIconActivated(QSystemTrayIcon::ActivationReason reason) -{ - if (reason == QSystemTrayIcon::DoubleClick) - { - showNormal(); - activateWindow(); - } -} +#include "drone.h" + +#include "rpcserver.h" +#include "myservice.h" + +#include +#include + +extern int myport; + +Drone::Drone(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + rpcServer = new RpcServer(); + service = new MyService(); +} + +Drone::~Drone() +{ + trayIcon_->hide(); + delete rpcServer; + delete service; +} + +bool Drone::init() +{ + Q_ASSERT(rpcServer); + + if (!rpcServer->registerService(service, myport ? myport : 7878)) + { + QMessageBox::critical(0, qApp->applicationName(), + rpcServer->errorString()); + return false; + } + + trayIconMenu_ = new QMenu(this); + + trayIconMenu_->addAction(actionShow); + trayIconMenu_->addAction(actionExit); + trayIconMenu_->setDefaultAction(actionShow); + trayIcon_ = new QSystemTrayIcon(); + trayIcon_->setIcon(QIcon(":/icons/portgroup.png")); + trayIcon_->setToolTip(qApp->applicationName()); + trayIcon_->setContextMenu(trayIconMenu_); + trayIcon_->show(); + + connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + connect(this, SIGNAL(hideMe(bool)), this, SLOT(setHidden(bool)), + Qt::QueuedConnection); + + return true; +} + +void Drone::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::WindowStateChange && isMinimized()) + { + emit hideMe(true); + event->ignore(); + return; + } + + QWidget::changeEvent(event); +} + +void Drone::trayIconActivated(QSystemTrayIcon::ActivationReason reason) +{ + if (reason == QSystemTrayIcon::DoubleClick) + { + showNormal(); + activateWindow(); + } +} diff --git a/server/drone.h b/server/drone.h index c441af7..c8d9ff2 100644 --- a/server/drone.h +++ b/server/drone.h @@ -1,37 +1,37 @@ -#ifndef _DRONE_H -#define _DRONE_H - -#include "ui_drone.h" - -#include -#include - -class RpcServer; -namespace OstProto { class OstService; } - -class Drone : public QWidget, Ui::Drone -{ - Q_OBJECT - -public: - Drone(QWidget *parent = 0); - ~Drone(); - bool init(); - -signals: - void hideMe(bool hidden); - -protected: - void changeEvent(QEvent *event); - -private: - QSystemTrayIcon *trayIcon_; - QMenu *trayIconMenu_; - RpcServer *rpcServer; - OstProto::OstService *service; - -private slots: - void trayIconActivated(QSystemTrayIcon::ActivationReason reason); - -}; -#endif +#ifndef _DRONE_H +#define _DRONE_H + +#include "ui_drone.h" + +#include +#include + +class RpcServer; +namespace OstProto { class OstService; } + +class Drone : public QWidget, Ui::Drone +{ + Q_OBJECT + +public: + Drone(QWidget *parent = 0); + ~Drone(); + bool init(); + +signals: + void hideMe(bool hidden); + +protected: + void changeEvent(QEvent *event); + +private: + QSystemTrayIcon *trayIcon_; + QMenu *trayIconMenu_; + RpcServer *rpcServer; + OstProto::OstService *service; + +private slots: + void trayIconActivated(QSystemTrayIcon::ActivationReason reason); + +}; +#endif diff --git a/server/drone.pro b/server/drone.pro index a402b4c..e33bb5c 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -1,26 +1,26 @@ -TEMPLATE = app -CONFIG += qt debug -QT += network script -DEFINES += HAVE_REMOTE WPCAP -INCLUDEPATH += "../rpc" -win32:LIBS += -lwpcap -lpacket -unix:LIBS += -lpcap -win32:LIBS += -L"../common/debug" -lostproto -unix:LIBS += -L"../common" -lostproto -win32:LIBS += -L"../rpc/debug" -lpbrpc -unix:LIBS += -L"../rpc" -lpbrpc -LIBS += -lprotobuf -POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" -RESOURCES += drone.qrc -HEADERS += drone.h -FORMS += drone.ui -SOURCES += \ - drone_main.cpp \ - drone.cpp \ - portmanager.cpp \ - abstractport.cpp \ - pcapport.cpp \ - winpcapport.cpp -SOURCES += myservice.cpp -SOURCES += pcapextra.cpp - +TEMPLATE = app +CONFIG += qt debug +QT += network script +DEFINES += HAVE_REMOTE WPCAP +INCLUDEPATH += "../rpc" +win32:LIBS += -lwpcap -lpacket +unix:LIBS += -lpcap +win32:LIBS += -L"../common/debug" -lostproto +unix:LIBS += -L"../common" -lostproto +win32:LIBS += -L"../rpc/debug" -lpbrpc +unix:LIBS += -L"../rpc" -lpbrpc +LIBS += -lprotobuf +POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" +RESOURCES += drone.qrc +HEADERS += drone.h +FORMS += drone.ui +SOURCES += \ + drone_main.cpp \ + drone.cpp \ + portmanager.cpp \ + abstractport.cpp \ + pcapport.cpp \ + winpcapport.cpp +SOURCES += myservice.cpp +SOURCES += pcapextra.cpp + diff --git a/server/drone_main.cpp b/server/drone_main.cpp index f6baad2..0bac7c1 100644 --- a/server/drone_main.cpp +++ b/server/drone_main.cpp @@ -1,25 +1,25 @@ -#include "drone.h" - -int myport; - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - Drone drone; - - app.setApplicationName(drone.objectName()); - - if (argc > 1) - myport = atoi(argv[1]); - - if (!drone.init()) - exit(-1); - - drone.setWindowFlags(drone.windowFlags() - | Qt::WindowMaximizeButtonHint - | Qt::WindowMinimizeButtonHint); - drone.showMinimized(); - app.exec(); - return 0; -} - +#include "drone.h" + +int myport; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + Drone drone; + + app.setApplicationName(drone.objectName()); + + if (argc > 1) + myport = atoi(argv[1]); + + if (!drone.init()) + exit(-1); + + drone.setWindowFlags(drone.windowFlags() + | Qt::WindowMaximizeButtonHint + | Qt::WindowMinimizeButtonHint); + drone.showMinimized(); + app.exec(); + return 0; +} + diff --git a/server/myservice.cpp b/server/myservice.cpp index 4da9b7e..d043df9 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -1,421 +1,421 @@ - -#include "myservice.h" - -#if 0 -#include -#include -#include "qdebug.h" - -#include "../common/protocollistiterator.h" -#include "../common/abstractprotocol.h" -#endif - -#include "../common/streambase.h" -#include "../rpc/pbrpccontroller.h" -#include "portmanager.h" - -MyService::MyService() -{ - PortManager *portManager = PortManager::instance(); - int n = portManager->portCount(); - - for (int i = 0; i < n; i++) - portInfo.append(portManager->port(i)); -} - -MyService::~MyService() -{ -} - -void MyService::getPortIdList(::google::protobuf::RpcController* controller, - const ::OstProto::Void* request, - ::OstProto::PortIdList* response, - ::google::protobuf::Closure* done) -{ - qDebug("In %s", __PRETTY_FUNCTION__); - - for (int i = 0; i < portInfo.size(); i++) - { - ::OstProto::PortId *p; - - p = response->add_port_id(); - p->set_id(portInfo[i]->id()); - } - - done->Run(); -} - -void MyService::getPortConfig(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::PortConfigList* response, - ::google::protobuf::Closure* done) -{ - qDebug("In %s", __PRETTY_FUNCTION__); - - for (int i = 0; i < request->port_id_size(); i++) - { - int id; - - id = request->port_id(i).id(); - if (id < portInfo.size()) - { - OstProto::Port *p; - - p = response->add_port(); - portInfo[id]->protoDataCopyInto(p); - } - } - - done->Run(); -} - -void MyService::getStreamIdList(::google::protobuf::RpcController* controller, - const ::OstProto::PortId* request, - ::OstProto::StreamIdList* response, - ::google::protobuf::Closure* done) -{ - int portId; - - qDebug("In %s", __PRETTY_FUNCTION__); - - portId = request->id(); - if ((portId < 0) || (portId >= portInfo.size())) - goto _invalid_port; - - response->mutable_port_id()->set_id(portId); - for (int i = 0; i < portInfo[portId]->streamCount(); i++) - { - OstProto::StreamId *s; - - s = response->add_stream_id(); - s->set_id(portInfo[portId]->stream(i)->id()); - } - done->Run(); - return; - -_invalid_port: - controller->SetFailed("Invalid Port Id"); - done->Run(); -} - -void MyService::getStreamConfig(::google::protobuf::RpcController* controller, - const ::OstProto::StreamIdList* request, - ::OstProto::StreamConfigList* response, - ::google::protobuf::Closure* done) -{ - int portId; - - qDebug("In %s", __PRETTY_FUNCTION__); - - portId = request->port_id().id(); - if ((portId < 0) || (portId >= portInfo.size())) - goto _invalid_port; - - response->mutable_port_id()->set_id(portId); - for (int i = 0; i < request->stream_id_size(); i++) - { - StreamBase *stream; - OstProto::Stream *s; - - stream = portInfo[portId]->stream(request->stream_id(i).id()); - if (!stream) - continue; //! \todo(LOW): Partial status of RPC - - s = response->add_stream(); - stream->protoDataCopyInto(*s); - } - done->Run(); - return; - -_invalid_port: - controller->SetFailed("invalid portid"); - done->Run(); -} - -void MyService::addStream(::google::protobuf::RpcController* controller, - const ::OstProto::StreamIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done) -{ - int portId; - - qDebug("In %s", __PRETTY_FUNCTION__); - - portId = request->port_id().id(); - if ((portId < 0) || (portId >= portInfo.size())) - goto _invalid_port; - - for (int i = 0; i < request->stream_id_size(); i++) - { - StreamBase *stream; - - // If stream with same id as in request exists already ==> error!! - stream = portInfo[portId]->stream(request->stream_id(i).id()); - if (stream) - continue; //! \todo (LOW): Partial status of RPC - - // Append a new "default" stream - actual contents of the new stream is - // expected in a subsequent "modifyStream" request - set the stream id - // now itself however!!! - stream = new StreamBase; - stream->setId(request->stream_id(i).id()); - portInfo[portId]->addStream(stream); - - } - - //! \todo (LOW): fill-in response "Ack"???? - - done->Run(); - return; - -_invalid_port: - controller->SetFailed("invalid portid"); - done->Run(); -} - -void MyService::deleteStream(::google::protobuf::RpcController* controller, - const ::OstProto::StreamIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done) -{ - int portId; - - qDebug("In %s", __PRETTY_FUNCTION__); - - portId = request->port_id().id(); - if ((portId < 0) || (portId >= portInfo.size())) - goto _invalid_port; - - for (int i = 0; i < request->stream_id_size(); i++) - portInfo[portId]->deleteStream(request->stream_id(i).id()); - - //! \todo (LOW): fill-in response "Ack"???? - - done->Run(); - return; - -_invalid_port: - controller->SetFailed("invalid portid"); - done->Run(); -} - -void MyService::modifyStream(::google::protobuf::RpcController* controller, - const ::OstProto::StreamConfigList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done) -{ - int portId; - - qDebug("In %s", __PRETTY_FUNCTION__); - - portId = request->port_id().id(); - if ((portId < 0) || (portId >= portInfo.size())) - goto _invalid_port; - - for (int i = 0; i < request->stream_size(); i++) - { - StreamBase *stream; - - stream = portInfo[portId]->stream(request->stream(i).stream_id().id()); - if (stream) - { - stream->protoDataCopyFrom(request->stream(i)); - portInfo[portId]->setDirty(); - } - } - - //! \todo(LOW): fill-in response "Ack"???? - - done->Run(); - return; - -_invalid_port: - controller->SetFailed("invalid portid"); - done->Run(); -} - -void MyService::startTx(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done) -{ - qDebug("In %s", __PRETTY_FUNCTION__); - - for (int i = 0; i < request->port_id_size(); i++) - { - int portId; - - portId = request->port_id(i).id(); - if ((portId < 0) || (portId >= portInfo.size())) - continue; //! \todo (LOW): partial RPC? - - portInfo[portId]->startTransmit(); - } - - //! \todo (LOW): fill-in response "Ack"???? - - done->Run(); -} - -void MyService::stopTx(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done) -{ - qDebug("In %s", __PRETTY_FUNCTION__); - - for (int i = 0; i < request->port_id_size(); i++) - { - int portId; - - portId = request->port_id(i).id(); - if ((portId < 0) || (portId >= portInfo.size())) - continue; //! \todo (LOW): partial RPC? - - portInfo[portId]->stopTransmit(); - } - - //! \todo (LOW): fill-in response "Ack"???? - - done->Run(); -} - -void MyService::startCapture(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done) -{ - qDebug("In %s", __PRETTY_FUNCTION__); - - for (int i = 0; i < request->port_id_size(); i++) - { - int portId; - - portId = request->port_id(i).id(); - if ((portId < 0) || (portId >= portInfo.size())) - continue; //! \todo (LOW): partial RPC? - - portInfo[portId]->startCapture(); - } - - //! \todo (LOW): fill-in response "Ack"???? - - done->Run(); -} - -void MyService::stopCapture(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done) -{ - qDebug("In %s", __PRETTY_FUNCTION__); - for (int i=0; i < request->port_id_size(); i++) - { - int portId; - - portId = request->port_id(i).id(); - if ((portId < 0) || (portId >= portInfo.size())) - continue; //! \todo (LOW): partial RPC? - - portInfo[portId]->stopCapture(); - } - - //! \todo (LOW): fill-in response "Ack"???? - - done->Run(); -} - -void MyService::getCaptureBuffer(::google::protobuf::RpcController* controller, - const ::OstProto::PortId* request, - ::OstProto::CaptureBuffer* response, - ::google::protobuf::Closure* done) -{ - int portId; - - qDebug("In %s", __PRETTY_FUNCTION__); - - portId = request->id(); - if ((portId < 0) || (portId >= portInfo.size())) - goto _invalid_port; - - portInfo[portId]->stopCapture(); - static_cast(controller)->setBinaryBlob( - portInfo[portId]->captureData()); - - done->Run(); - return; - -_invalid_port: - controller->SetFailed("invalid portid"); - done->Run(); -} - -void MyService::getStats(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::PortStatsList* response, - ::google::protobuf::Closure* done) -{ - //qDebug("In %s", __PRETTY_FUNCTION__); - - for (int i = 0; i < request->port_id_size(); i++) - { - int portId; - AbstractPort::PortStats stats; - OstProto::PortStats *s; - OstProto::PortState *st; - - portId = request->port_id(i).id(); - if ((portId < 0) || (portId >= portInfo.size())) - continue; //! \todo(LOW): partial rpc? - - s = response->add_port_stats(); - s->mutable_port_id()->set_id(request->port_id(i).id()); - - st = s->mutable_state(); - st->set_link_state(portInfo[portId]->linkState()); - st->set_is_transmit_on(portInfo[portId]->isTransmitOn()); - st->set_is_capture_on(portInfo[portId]->isCaptureOn()); - - portInfo[portId]->stats(&stats); - -#if 0 - if (portId == 2) - qDebug(">%llu", stats.rxPkts); -#endif - - s->set_rx_pkts(stats.rxPkts); - s->set_rx_bytes(stats.rxBytes); - s->set_rx_pps(stats.rxPps); - s->set_rx_bps(stats.rxBps); - - s->set_tx_pkts(stats.txPkts); - s->set_tx_bytes(stats.txBytes); - s->set_tx_pps(stats.txPps); - s->set_tx_bps(stats.txBps); - } - - done->Run(); -} - -void MyService::clearStats(::google::protobuf::RpcController* controller, - const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, - ::google::protobuf::Closure* done) -{ - qDebug("In %s", __PRETTY_FUNCTION__); - - for (int i = 0; i < request->port_id_size(); i++) - { - int portId; - - portId = request->port_id(i).id(); - if ((portId < 0) || (portId >= portInfo.size())) - continue; //! \todo (LOW): partial RPC? - - portInfo[portId]->resetStats(); - } - - //! \todo (LOW): fill-in response "Ack"???? - - done->Run(); -} + +#include "myservice.h" + +#if 0 +#include +#include +#include "qdebug.h" + +#include "../common/protocollistiterator.h" +#include "../common/abstractprotocol.h" +#endif + +#include "../common/streambase.h" +#include "../rpc/pbrpccontroller.h" +#include "portmanager.h" + +MyService::MyService() +{ + PortManager *portManager = PortManager::instance(); + int n = portManager->portCount(); + + for (int i = 0; i < n; i++) + portInfo.append(portManager->port(i)); +} + +MyService::~MyService() +{ +} + +void MyService::getPortIdList(::google::protobuf::RpcController* controller, + const ::OstProto::Void* request, + ::OstProto::PortIdList* response, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __PRETTY_FUNCTION__); + + for (int i = 0; i < portInfo.size(); i++) + { + ::OstProto::PortId *p; + + p = response->add_port_id(); + p->set_id(portInfo[i]->id()); + } + + done->Run(); +} + +void MyService::getPortConfig(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::PortConfigList* response, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __PRETTY_FUNCTION__); + + for (int i = 0; i < request->port_id_size(); i++) + { + int id; + + id = request->port_id(i).id(); + if (id < portInfo.size()) + { + OstProto::Port *p; + + p = response->add_port(); + portInfo[id]->protoDataCopyInto(p); + } + } + + done->Run(); +} + +void MyService::getStreamIdList(::google::protobuf::RpcController* controller, + const ::OstProto::PortId* request, + ::OstProto::StreamIdList* response, + ::google::protobuf::Closure* done) +{ + int portId; + + qDebug("In %s", __PRETTY_FUNCTION__); + + portId = request->id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; + + response->mutable_port_id()->set_id(portId); + for (int i = 0; i < portInfo[portId]->streamCount(); i++) + { + OstProto::StreamId *s; + + s = response->add_stream_id(); + s->set_id(portInfo[portId]->stream(i)->id()); + } + done->Run(); + return; + +_invalid_port: + controller->SetFailed("Invalid Port Id"); + done->Run(); +} + +void MyService::getStreamConfig(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::StreamConfigList* response, + ::google::protobuf::Closure* done) +{ + int portId; + + qDebug("In %s", __PRETTY_FUNCTION__); + + portId = request->port_id().id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; + + response->mutable_port_id()->set_id(portId); + for (int i = 0; i < request->stream_id_size(); i++) + { + StreamBase *stream; + OstProto::Stream *s; + + stream = portInfo[portId]->stream(request->stream_id(i).id()); + if (!stream) + continue; //! \todo(LOW): Partial status of RPC + + s = response->add_stream(); + stream->protoDataCopyInto(*s); + } + done->Run(); + return; + +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); +} + +void MyService::addStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) +{ + int portId; + + qDebug("In %s", __PRETTY_FUNCTION__); + + portId = request->port_id().id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; + + for (int i = 0; i < request->stream_id_size(); i++) + { + StreamBase *stream; + + // If stream with same id as in request exists already ==> error!! + stream = portInfo[portId]->stream(request->stream_id(i).id()); + if (stream) + continue; //! \todo (LOW): Partial status of RPC + + // Append a new "default" stream - actual contents of the new stream is + // expected in a subsequent "modifyStream" request - set the stream id + // now itself however!!! + stream = new StreamBase; + stream->setId(request->stream_id(i).id()); + portInfo[portId]->addStream(stream); + + } + + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); + return; + +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); +} + +void MyService::deleteStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) +{ + int portId; + + qDebug("In %s", __PRETTY_FUNCTION__); + + portId = request->port_id().id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; + + for (int i = 0; i < request->stream_id_size(); i++) + portInfo[portId]->deleteStream(request->stream_id(i).id()); + + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); + return; + +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); +} + +void MyService::modifyStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamConfigList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) +{ + int portId; + + qDebug("In %s", __PRETTY_FUNCTION__); + + portId = request->port_id().id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; + + for (int i = 0; i < request->stream_size(); i++) + { + StreamBase *stream; + + stream = portInfo[portId]->stream(request->stream(i).stream_id().id()); + if (stream) + { + stream->protoDataCopyFrom(request->stream(i)); + portInfo[portId]->setDirty(); + } + } + + //! \todo(LOW): fill-in response "Ack"???? + + done->Run(); + return; + +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); +} + +void MyService::startTx(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __PRETTY_FUNCTION__); + + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; + + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? + + portInfo[portId]->startTransmit(); + } + + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); +} + +void MyService::stopTx(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __PRETTY_FUNCTION__); + + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; + + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? + + portInfo[portId]->stopTransmit(); + } + + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); +} + +void MyService::startCapture(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __PRETTY_FUNCTION__); + + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; + + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? + + portInfo[portId]->startCapture(); + } + + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); +} + +void MyService::stopCapture(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __PRETTY_FUNCTION__); + for (int i=0; i < request->port_id_size(); i++) + { + int portId; + + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? + + portInfo[portId]->stopCapture(); + } + + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); +} + +void MyService::getCaptureBuffer(::google::protobuf::RpcController* controller, + const ::OstProto::PortId* request, + ::OstProto::CaptureBuffer* response, + ::google::protobuf::Closure* done) +{ + int portId; + + qDebug("In %s", __PRETTY_FUNCTION__); + + portId = request->id(); + if ((portId < 0) || (portId >= portInfo.size())) + goto _invalid_port; + + portInfo[portId]->stopCapture(); + static_cast(controller)->setBinaryBlob( + portInfo[portId]->captureData()); + + done->Run(); + return; + +_invalid_port: + controller->SetFailed("invalid portid"); + done->Run(); +} + +void MyService::getStats(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::PortStatsList* response, + ::google::protobuf::Closure* done) +{ + //qDebug("In %s", __PRETTY_FUNCTION__); + + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; + AbstractPort::PortStats stats; + OstProto::PortStats *s; + OstProto::PortState *st; + + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo(LOW): partial rpc? + + s = response->add_port_stats(); + s->mutable_port_id()->set_id(request->port_id(i).id()); + + st = s->mutable_state(); + st->set_link_state(portInfo[portId]->linkState()); + st->set_is_transmit_on(portInfo[portId]->isTransmitOn()); + st->set_is_capture_on(portInfo[portId]->isCaptureOn()); + + portInfo[portId]->stats(&stats); + +#if 0 + if (portId == 2) + qDebug(">%llu", stats.rxPkts); +#endif + + s->set_rx_pkts(stats.rxPkts); + s->set_rx_bytes(stats.rxBytes); + s->set_rx_pps(stats.rxPps); + s->set_rx_bps(stats.rxBps); + + s->set_tx_pkts(stats.txPkts); + s->set_tx_bytes(stats.txBytes); + s->set_tx_pps(stats.txPps); + s->set_tx_bps(stats.txBps); + } + + done->Run(); +} + +void MyService::clearStats(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __PRETTY_FUNCTION__); + + for (int i = 0; i < request->port_id_size(); i++) + { + int portId; + + portId = request->port_id(i).id(); + if ((portId < 0) || (portId >= portInfo.size())) + continue; //! \todo (LOW): partial RPC? + + portInfo[portId]->resetStats(); + } + + //! \todo (LOW): fill-in response "Ack"???? + + done->Run(); +} From be620e0ab6859481bc1461a46b7a4cd93358089d Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 2 Jan 2010 13:49:54 +0000 Subject: [PATCH 39/98] Changes for successful Linux compilation --- client/mainwindow.cpp | 3 ++- client/ostinato.pro | 3 ++- client/portgroup.cpp | 9 +++++++-- common/dot3.h | 2 +- server/drone.pro | 3 ++- server/pcapextra.h | 2 +- server/pcapport.cpp | 7 ++++++- server/pcapport.h | 1 + server/portmanager.cpp | 1 + server/winpcapport.cpp | 4 ++++ server/winpcapport.h | 4 ++++ 11 files changed, 31 insertions(+), 8 deletions(-) diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 0f818c5..4b967a6 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -18,7 +18,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow (parent) { localServer_ = new QProcess(this); - localServer_->start("drone.exe"); + localServer_->setProcessChannelMode(QProcess::ForwardedChannels); + localServer_->start("./drone.exe"); pgl = new PortGroupList; diff --git a/client/ostinato.pro b/client/ostinato.pro index 3afbdc2..a644eb9 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -7,7 +7,8 @@ win32:LIBS += -L"../common/debug" -lostproto unix: LIBS += -L"../common" -lostproto win32:LIBS += -L"../rpc/debug" -lpbrpc unix:LIBS += -L"../rpc" -lpbrpc -POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" +win32:POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" +unix:POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a" RESOURCES += ostinato.qrc HEADERS += \ dumpview.h \ diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 4ec94c3..606393c 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -620,13 +620,18 @@ void PortGroup::processStopCaptureAck(OstProto::Ack *ack) void PortGroup::processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile) { +#ifdef Q_OS_WIN32 + QString viewer("C:/Program Files/Wireshark/wireshark.exe"); +#else + QString viewer("/usr/bin/wireshark"); +#endif + qDebug("In %s", __FUNCTION__); capFile->flush(); capFile->close(); - if (!QProcess::startDetached("C:/Program Files/Wireshark/wireshark.exe", - QStringList() << capFile->fileName())) + if (!QProcess::startDetached(viewer, QStringList() << capFile->fileName())) qDebug("Failed starting Wireshark"); delete buf; diff --git a/common/dot3.h b/common/dot3.h index af045db..925374a 100644 --- a/common/dot3.h +++ b/common/dot3.h @@ -4,7 +4,7 @@ #include "abstractprotocol.h" #include "dot3.pb.h" -#include "ui_Dot3.h" +#include "ui_dot3.h" class Dot3ConfigForm : public QWidget, public Ui::dot3 { diff --git a/server/drone.pro b/server/drone.pro index e33bb5c..5fc71d5 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -10,7 +10,8 @@ unix:LIBS += -L"../common" -lostproto win32:LIBS += -L"../rpc/debug" -lpbrpc unix:LIBS += -L"../rpc" -lpbrpc LIBS += -lprotobuf -POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" +win32:POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" +unix:POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a" RESOURCES += drone.qrc HEADERS += drone.h FORMS += drone.ui diff --git a/server/pcapextra.h b/server/pcapextra.h index 1f1c9f3..de4cec1 100644 --- a/server/pcapextra.h +++ b/server/pcapextra.h @@ -6,7 +6,7 @@ #ifndef Q_OS_WIN32 -//#define PCAP_OPENFLAG_PROMISCUOUS 1 +#define PCAP_OPENFLAG_PROMISCUOUS 1 struct pcap_send_queue { diff --git a/server/pcapport.cpp b/server/pcapport.cpp index a133812..f709b26 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -22,6 +22,10 @@ PcapPort::PcapPort(int id, const char *device) { if (strcmp(device, dev->name) == 0) { +#ifndef Q_OS_WIN32 + if (dev->name) + data_.set_name(dev->name); +#endif if (dev->description) data_.set_description(dev->description); @@ -214,7 +218,7 @@ void PcapPort::PortTransmitter::setHandle(pcap_t *handle) void PcapPort::PortTransmitter::useExternalStats(AbstractPort::PortStats *stats) { - if (usingInternalStats_); + if (usingInternalStats_) delete stats_; stats_ = stats; usingInternalStats_ = false; @@ -384,6 +388,7 @@ void PcapPort::PortCapturer::run() if (stop_) { + qDebug("user requested capture stop\n"); stop_ = false; break; } diff --git a/server/pcapport.h b/server/pcapport.h index a17e665..9f80e57 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -6,6 +6,7 @@ #include #include "abstractport.h" +#include "pcapextra.h" class PcapPort : public AbstractPort { diff --git a/server/portmanager.cpp b/server/portmanager.cpp index 6105559..6442c72 100644 --- a/server/portmanager.cpp +++ b/server/portmanager.cpp @@ -2,6 +2,7 @@ #include +#include "pcapport.h" #include "winpcapport.h" PortManager *PortManager::instance_ = NULL; diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp index 4e64913..b6e536d 100644 --- a/server/winpcapport.cpp +++ b/server/winpcapport.cpp @@ -1,5 +1,7 @@ #include "winpcapport.h" +#ifdef Q_OS_WIN32 + const uint OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114; WinPcapPort::WinPcapPort(int id, const char *device) @@ -140,3 +142,5 @@ void WinPcapPort::PortMonitor::run() QThread::msleep(1000); } } + +#endif diff --git a/server/winpcapport.h b/server/winpcapport.h index 3f2a3b0..d351fe2 100644 --- a/server/winpcapport.h +++ b/server/winpcapport.h @@ -1,6 +1,8 @@ #ifndef _SERVER_WIN_PCAP_PORT_H #define _SERVER_WIN_PCAP_PORT_H +#ifdef Q_OS_WIN32 + #include "pcapport.h" #include @@ -27,3 +29,5 @@ private: }; #endif + +#endif From 395024cc0c86964babc4b70768ff993afe533f7b Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 2 Jan 2010 14:50:19 +0000 Subject: [PATCH 40/98] Fixed Windows compilation issues (introduced while fixing the linux compilation issues!) --- client/portgroup.cpp | 3 ++- server/pcapport.cpp | 2 ++ server/portmanager.cpp | 1 + server/winpcapport.h | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 606393c..75d18a8 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -1,5 +1,6 @@ -#include +#include #include +#include #include "portgroup.h" diff --git a/server/pcapport.cpp b/server/pcapport.cpp index f709b26..2879680 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -1,5 +1,7 @@ #include "pcapport.h" +#include + pcap_if_t *PcapPort::deviceList_ = NULL; PcapPort::PcapPort(int id, const char *device) diff --git a/server/portmanager.cpp b/server/portmanager.cpp index 6442c72..1877234 100644 --- a/server/portmanager.cpp +++ b/server/portmanager.cpp @@ -1,5 +1,6 @@ #include "portmanager.h" +#include #include #include "pcapport.h" diff --git a/server/winpcapport.h b/server/winpcapport.h index d351fe2..80a83c9 100644 --- a/server/winpcapport.h +++ b/server/winpcapport.h @@ -1,6 +1,8 @@ #ifndef _SERVER_WIN_PCAP_PORT_H #define _SERVER_WIN_PCAP_PORT_H +#include + #ifdef Q_OS_WIN32 #include "pcapport.h" From aac2229403503876576a7c2fe00301eccb709791 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 3 Jan 2010 08:56:16 +0000 Subject: [PATCH 41/98] Removed a bunch of gcc4 warnings - mostly "unused param" --- client/dumpview.cpp | 30 +++++++++++++------------- client/hexlineedit.cpp | 2 +- client/packetmodel.cpp | 3 ++- client/packetmodel.h | 10 +++++---- client/portgroup.cpp | 4 ++-- client/portmodel.cpp | 4 ++-- client/portstatsfilterdialog.cpp | 9 ++++---- client/portstatsmodel.cpp | 4 ++-- client/portswindow.cpp | 7 ++++--- client/streamconfigdialog.cpp | 4 ++-- client/streammodel.cpp | 6 +++--- common/abstractprotocol.cpp | 12 +++++------ common/dot3.cpp | 4 ++-- common/llc.cpp | 4 ++-- common/mac.cpp | 4 ++-- common/payload.cpp | 4 ++-- common/sample.cpp | 1 + common/snap.cpp | 4 ++-- common/streambase.cpp | 1 + common/tcp.cpp | 4 ++-- common/udp.cpp | 5 +++-- common/userscript.cpp | 2 +- common/vlan.cpp | 4 ++-- rpc/pbrpccontroller.h | 4 +++- rpc/rpcserver.cpp | 3 ++- server/abstractport.cpp | 2 +- server/myservice.cpp | 36 ++++++++++++++++---------------- server/pcapport.cpp | 4 +++- 28 files changed, 98 insertions(+), 83 deletions(-) diff --git a/client/dumpview.cpp b/client/dumpview.cpp index 0056502..65584ee 100644 --- a/client/dumpview.cpp +++ b/client/dumpview.cpp @@ -3,6 +3,7 @@ //! \todo Enable Scrollbars DumpView::DumpView(QWidget *parent) + : QAbstractItemView(parent) { int w, h; @@ -26,7 +27,7 @@ DumpView::DumpView(QWidget *parent) qDebug("DumpView::DumpView"); } -QModelIndex DumpView::indexAt( const QPoint &point ) const +QModelIndex DumpView::indexAt(const QPoint &/*point*/) const { #if 0 int x = point.x(); @@ -84,12 +85,12 @@ _exit: return QModelIndex(); } -void DumpView::scrollTo( const QModelIndex &index, ScrollHint hint ) +void DumpView::scrollTo(const QModelIndex &/*index*/, ScrollHint /*hint*/) { // FIXME: implement scrolling } -QRect DumpView::visualRect( const QModelIndex &index ) const +QRect DumpView::visualRect(const QModelIndex &/*index*/) const { // FIXME: calculate actual rect return rect(); @@ -101,20 +102,20 @@ int DumpView::horizontalOffset() const return horizontalScrollBar()->value(); } -bool DumpView::isIndexHidden( const QModelIndex &index ) const +bool DumpView::isIndexHidden(const QModelIndex &/*index*/) const { return false; } -QModelIndex DumpView::moveCursor( CursorAction cursorAction, - Qt::KeyboardModifiers modifiers ) +QModelIndex DumpView::moveCursor(CursorAction /*cursorAction*/, + Qt::KeyboardModifiers /*modifiers*/) { // FIXME(MED): need to implement movement using cursor return currentIndex(); } -void DumpView::setSelection( const QRect &rect, - QItemSelectionModel::SelectionFlags flags ) +void DumpView::setSelection(const QRect &/*rect*/, + QItemSelectionModel::SelectionFlags flags) { // FIXME(HI): calculate indexes using rect selectionModel()->select(QModelIndex(), flags); @@ -125,22 +126,23 @@ int DumpView::verticalOffset() const return verticalScrollBar()->value(); } -QRegion DumpView::visualRegionForSelection( const QItemSelection &selection ) const +QRegion DumpView::visualRegionForSelection( + const QItemSelection &/*selection*/) const { // FIXME(HI) return QRegion(rect()); } //protected slots: -void DumpView::dataChanged( const QModelIndex &topLeft, - const QModelIndex &bottomRight ) +void DumpView::dataChanged(const QModelIndex &/*topLeft*/, + const QModelIndex &/*bottomRight*/) { // FIXME(HI) update(); } -void DumpView::selectionChanged( const QItemSelection &selected, - const QItemSelection &deselected ) +void DumpView::selectionChanged(const QItemSelection &/*selected*/, + const QItemSelection &/*deselected*/) { // FIXME(HI) update(); @@ -220,7 +222,7 @@ void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize, } // TODO(LOW): rewrite this function - it's a mess! -void DumpView::paintEvent(QPaintEvent* event) +void DumpView::paintEvent(QPaintEvent* /*event*/) { QStylePainter painter(viewport()); QRect offsetRect = mOffsetPaneTopRect; diff --git a/client/hexlineedit.cpp b/client/hexlineedit.cpp index 4497710..68d7dab 100644 --- a/client/hexlineedit.cpp +++ b/client/hexlineedit.cpp @@ -9,7 +9,7 @@ HexLineEdit::HexLineEdit( QWidget * parent) //QLineEdit::QLineEdit(parent); } -void HexLineEdit::focusOutEvent( QFocusEvent *e ) +void HexLineEdit::focusOutEvent(QFocusEvent* /*e*/) { #if 0 const QValidator *v = validator(); diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index df5a30b..11ed59d 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -5,6 +5,7 @@ #include "../common/abstractprotocol.h" PacketModel::PacketModel(QObject *parent) + : QAbstractItemModel(parent) { } @@ -51,7 +52,7 @@ int PacketModel::rowCount(const QModelIndex &parent) const return 0; // catch all } -int PacketModel::columnCount(const QModelIndex &parent) const +int PacketModel::columnCount(const QModelIndex &/*parent*/) const { return 1; } diff --git a/client/packetmodel.h b/client/packetmodel.h index cd81a8f..4f3b542 100644 --- a/client/packetmodel.h +++ b/client/packetmodel.h @@ -16,8 +16,10 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const { return QVariant(); } ; + QVariant headerData(int /*section*/, Qt::Orientation /*orientation*/, + int /*role= Qt::DisplayRole*/) const { + return QVariant(); + } QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; QModelIndex parent(const QModelIndex &index) const; @@ -28,8 +30,8 @@ private: struct { quint16 type; -#define ITYP_PROTOCOL 1 -#define ITYP_FIELD 2 +#define ITYP_PROTOCOL 1 +#define ITYP_FIELD 2 quint16 protocol; // protocol is valid for both ITYPs } ws; } IndexId; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 75d18a8..8705224 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -85,7 +85,7 @@ void PortGroup::on_rpcChannel_disconnected() void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) { - qDebug("error\n"); + qDebug("%s: error %d", __FUNCTION__, socketError); emit portGroupDataChanged(mPortGroupId); } @@ -429,7 +429,7 @@ _exit: return; } -void PortGroup::processModifyStreamAck(OstProto::Ack *ack) +void PortGroup::processModifyStreamAck(OstProto::Ack */*ack*/) { qDebug("In %s", __FUNCTION__); diff --git a/client/portmodel.cpp b/client/portmodel.cpp index 6ab422e..241090d 100644 --- a/client/portmodel.cpp +++ b/client/portmodel.cpp @@ -53,7 +53,7 @@ int PortModel::rowCount(const QModelIndex &parent) const } } -int PortModel::columnCount(const QModelIndex &parent ) const +int PortModel::columnCount(const QModelIndex &/*parent*/) const { return 1; // FIXME: hardcoding } @@ -166,7 +166,7 @@ QVariant PortModel::data(const QModelIndex &index, int role) const return QVariant(); } -QVariant PortModel::headerData(int section, Qt::Orientation orientation, int role) const +QVariant PortModel::headerData(int /*section*/, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) return QVariant(); diff --git a/client/portstatsfilterdialog.cpp b/client/portstatsfilterdialog.cpp index 4291fea..724ee40 100644 --- a/client/portstatsfilterdialog.cpp +++ b/client/portstatsfilterdialog.cpp @@ -1,6 +1,7 @@ #include "portstatsfilterdialog.h" PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent) + : QDialog(parent) { setupUi(this); @@ -92,8 +93,8 @@ void PortStatsFilterDialog::on_lvUnselected_doubleClicked(const QModelIndex &ind { QStandardItem *item; - item = mUnselected.takeItem(lvUnselected->currentIndex().row()); - if (mUnselected.removeRow(lvUnselected->currentIndex().row())) + item = mUnselected.takeItem(index.row()); + if (mUnselected.removeRow(index.row())) mSelected.appendRow(item); } @@ -101,8 +102,8 @@ void PortStatsFilterDialog::on_lvSelected_doubleClicked(const QModelIndex &index { QStandardItem *item; - item = mSelected.takeItem(lvSelected->currentIndex().row()); - if (mSelected.removeRow(lvSelected->currentIndex().row())) + item = mSelected.takeItem(index.row()); + if (mSelected.removeRow(index.row())) { mUnselected.appendRow(item); mUnselected.sort(0); diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 58993e4..1958d8d 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -261,7 +261,7 @@ void PortStatsModel::when_portListChanged() reset(); } -void PortStatsModel::on_portStatsUpdate(int port, void*stats) +void PortStatsModel::on_portStatsUpdate(int port, void* /*stats*/) { QModelIndex topLeft = index(port, 0, QModelIndex()); QModelIndex bottomRight = index(port, e_STAT_MAX, QModelIndex()); @@ -277,7 +277,7 @@ void PortStatsModel::updateStats() pgl->mPortGroups[i]->getPortStats(); } -void PortStatsModel::when_portGroup_stats_update(quint32 portGroupId) +void PortStatsModel::when_portGroup_stats_update(quint32 /*portGroupId*/) { // FIXME(MED): update only the changed ports, not all diff --git a/client/portswindow.cpp b/client/portswindow.cpp index c8dd179..22ae629 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -5,6 +5,7 @@ #include PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) + : QWidget(parent) { StreamListDelegate *delegate = new StreamListDelegate; //slm = new StreamListModel(); @@ -90,7 +91,7 @@ void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) } void PortsWindow::when_portView_currentChanged(const QModelIndex& current, - const QModelIndex& previous) + const QModelIndex& /*previous*/) { plm->getStreamModel()->setCurrentPortIndex(current); updatePortViewActions(current); @@ -114,8 +115,8 @@ void PortsWindow::when_portView_currentChanged(const QModelIndex& current, } } -void PortsWindow::when_streamView_currentChanged(const QModelIndex& current, - const QModelIndex& previous) +void PortsWindow::when_streamView_currentChanged(const QModelIndex& /*current*/, + const QModelIndex& /*previous*/) { qDebug("stream view current changed"); updateStreamViewActions(); diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index eb3da50..3c75c3f 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -311,7 +311,7 @@ void StreamConfigDialog::on_tbSelectProtocols_currentChanged(int index) } void StreamConfigDialog::when_lvAllProtocols_selectionChanged( - const QItemSelection &selected, const QItemSelection &deselected) + const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/) { int size = lvAllProtocols->selectionModel()->selectedIndexes().size(); @@ -321,7 +321,7 @@ void StreamConfigDialog::when_lvAllProtocols_selectionChanged( } void StreamConfigDialog::when_lvSelectedProtocols_currentChanged( - const QModelIndex ¤t, const QModelIndex &previous) + const QModelIndex ¤t, const QModelIndex &/*previous*/) { qDebug("%s: currentRow = %d\n", __FUNCTION__, current.row()); diff --git a/client/streammodel.cpp b/client/streammodel.cpp index c58d25b..76735d0 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -21,7 +21,7 @@ int StreamModel::rowCount(const QModelIndex &parent) const return 0; } -int StreamModel::columnCount(const QModelIndex &parent ) const +int StreamModel::columnCount(const QModelIndex &/*parent*/) const { return (int) StreamMaxFields; } @@ -197,7 +197,7 @@ QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int r return QVariant(); } -bool StreamModel::insertRows(int row, int count, const QModelIndex &parent) +bool StreamModel::insertRows(int row, int count, const QModelIndex &/*parent*/) { qDebug("insertRows() row = %d", row); qDebug("insertRows() count = %d", count); @@ -209,7 +209,7 @@ bool StreamModel::insertRows(int row, int count, const QModelIndex &parent) return true; } -bool StreamModel::removeRows(int row, int count, const QModelIndex &parent) +bool StreamModel::removeRows(int row, int count, const QModelIndex &/*parent*/) { qDebug("removeRows() row = %d", row); qDebug("removeRows() count = %d", count); diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 8773154..f66dfdd 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -36,8 +36,8 @@ AbstractProtocol::~AbstractProtocol() { } -AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream, - AbstractProtocol *parent) +AbstractProtocol* AbstractProtocol::createInstance(StreamBase* /* stream */, + AbstractProtocol* /* parent */) { return NULL; } @@ -124,7 +124,7 @@ int AbstractProtocol::frameFieldCount() const return (fieldCount() - metaFieldCount()); } -AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int index) const +AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const { return FieldIsNormal; } @@ -187,8 +187,8 @@ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, /*! Sets the value of a field corresponding to index \n Returns true if field is successfully set, false otherwise \n The default implementation always returns false */ -bool AbstractProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) +bool AbstractProtocol::setFieldData(int /*index*/, const QVariant& /*value*/, + FieldAttrib /*attrib*/) { return false; } @@ -198,7 +198,7 @@ AbstractProtocol::ProtocolIdType AbstractProtocol::protocolIdType() const return ProtocolIdNone; } -quint32 AbstractProtocol::protocolId(ProtocolIdType type) const +quint32 AbstractProtocol::protocolId(ProtocolIdType /*type*/) const { return 0; } diff --git a/common/dot3.cpp b/common/dot3.cpp index ddf58a8..1c16f40 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -113,8 +113,8 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool Dot3Protocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) +bool Dot3Protocol::setFieldData(int /*index*/, const QVariant &/*value*/, + FieldAttrib /*attrib*/) { return false; } diff --git a/common/llc.cpp b/common/llc.cpp index a4943f7..5a5f1d2 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -130,8 +130,8 @@ QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib, return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool LlcProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) +bool LlcProtocol::setFieldData(int /*index*/, const QVariant &/*value*/, + FieldAttrib /*attrib*/) { return false; } diff --git a/common/mac.cpp b/common/mac.cpp index efbd518..30f0ec2 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -233,8 +233,8 @@ QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool MacProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) +bool MacProtocol::setFieldData(int /*index*/, const QVariant& /*value*/, + FieldAttrib /*attrib*/) { return false; } diff --git a/common/payload.cpp b/common/payload.cpp index 276af95..292c0c5 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -181,8 +181,8 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool PayloadProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) +bool PayloadProtocol::setFieldData(int /*index*/, const QVariant &/*value*/, + FieldAttrib /*attrib*/) { return false; } diff --git a/common/sample.cpp b/common/sample.cpp index 00a65e6..0b7da64 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -220,6 +220,7 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, cksum = protocolFrameCksum(streamIndex, CksumIp); } default: + cksum = 0; // avoid the 'maybe used unitialized' warning break; } diff --git a/common/snap.cpp b/common/snap.cpp index 3eaab91..cfabc1b 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -135,8 +135,8 @@ QVariant SnapProtocol::fieldData(int index, FieldAttrib attrib, return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool SnapProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) +bool SnapProtocol::setFieldData(int /*index*/, const QVariant &/*value*/, + FieldAttrib /*attrib*/) { return false; } diff --git a/common/streambase.cpp b/common/streambase.cpp index e40f009..671f4d3 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -191,6 +191,7 @@ quint16 StreamBase::frameLen(int streamIndex) const break; case OstProto::StreamCore::e_fl_random: //! \todo (MED) This 'random' sequence is same across iterations + pktLen = 64; // to avoid the 'maybe used uninitialized' warning qsrand(((uint) this)); for (int i = 0; i <= streamIndex; i++) pktLen = qrand(); diff --git a/common/tcp.cpp b/common/tcp.cpp index b6990f5..7a66347 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -374,8 +374,8 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool TcpProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) +bool TcpProtocol::setFieldData(int /*index*/, const QVariant &/*value*/, + FieldAttrib /*attrib*/) { return false; } diff --git a/common/udp.cpp b/common/udp.cpp index e65e0af..b83a07a 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -205,6 +205,7 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, qDebug("UDP cksum = %hu", cksum); } default: + cksum = 0; break; } @@ -251,8 +252,8 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool UdpProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) +bool UdpProtocol::setFieldData(int /*index*/, const QVariant &/*value*/, + FieldAttrib /*attrib*/) { //! implement UdpProtocol::setFieldData() return false; diff --git a/common/userscript.cpp b/common/userscript.cpp index 89191fb..ba26c72 100644 --- a/common/userscript.cpp +++ b/common/userscript.cpp @@ -35,7 +35,7 @@ void UserScriptConfigForm::on_programEdit_textChanged() compileButton->setEnabled(true); } -void UserScriptConfigForm::on_compileButton_clicked(bool checked) +void UserScriptConfigForm::on_compileButton_clicked(bool /*checked*/) { protocol_->storeConfigWidget(); if (!protocol_->isScriptValid()) diff --git a/common/vlan.cpp b/common/vlan.cpp index 83ed52d..5abee7d 100644 --- a/common/vlan.cpp +++ b/common/vlan.cpp @@ -193,8 +193,8 @@ QVariant VlanProtocol::fieldData(int index, FieldAttrib attrib, return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool VlanProtocol::setFieldData(int index, const QVariant &value, - FieldAttrib attrib) +bool VlanProtocol::setFieldData(int /*index*/, const QVariant &/*value*/, + FieldAttrib /*attrib*/) { return false; } diff --git a/rpc/pbrpccontroller.h b/rpc/pbrpccontroller.h index 99acc5a..6eef8cd 100644 --- a/rpc/pbrpccontroller.h +++ b/rpc/pbrpccontroller.h @@ -24,7 +24,9 @@ public: void SetFailed(const std::string &reason) { failed = true; errStr = reason; } bool IsCanceled() const { return false; }; - void NotifyOnCancel(::google::protobuf::Closure *callback) { /*! \todo (MED) */ } + void NotifyOnCancel(::google::protobuf::Closure* /* callback */) { + /*! \todo (MED) */ + } // srivatsp added QIODevice* binaryBlob() { return blob; }; diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index d85c753..73f6f51 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -160,7 +160,8 @@ void RpcServer::when_disconnected() void RpcServer::when_error(QAbstractSocket::SocketError socketError) { - qDebug("%s", clientSock->errorString().toAscii().constData()); + qDebug("%s (%d)", clientSock->errorString().toAscii().constData(), + socketError); } void RpcServer::when_dataAvail() diff --git a/server/abstractport.cpp b/server/abstractport.cpp index dfaf5b9..7e71e0d 100644 --- a/server/abstractport.cpp +++ b/server/abstractport.cpp @@ -8,7 +8,7 @@ AbstractPort::AbstractPort(int id, const char *device) { data_.mutable_port_id()->set_id(id); - data_.set_name(QString("if%1 ").arg(id).toStdString()); + data_.set_name(device); //! \todo (LOW) admin enable/disable of port data_.set_is_enabled(true); diff --git a/server/myservice.cpp b/server/myservice.cpp index d043df9..123e9ce 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -27,8 +27,8 @@ MyService::~MyService() { } -void MyService::getPortIdList(::google::protobuf::RpcController* controller, - const ::OstProto::Void* request, +void MyService::getPortIdList(::google::protobuf::RpcController* /*controller*/, + const ::OstProto::Void* /*request*/, ::OstProto::PortIdList* response, ::google::protobuf::Closure* done) { @@ -45,7 +45,7 @@ void MyService::getPortIdList(::google::protobuf::RpcController* controller, done->Run(); } -void MyService::getPortConfig(::google::protobuf::RpcController* controller, +void MyService::getPortConfig(::google::protobuf::RpcController* /*controller*/, const ::OstProto::PortIdList* request, ::OstProto::PortConfigList* response, ::google::protobuf::Closure* done) @@ -134,7 +134,7 @@ _invalid_port: void MyService::addStream(::google::protobuf::RpcController* controller, const ::OstProto::StreamIdList* request, - ::OstProto::Ack* response, + ::OstProto::Ack* /*response*/, ::google::protobuf::Closure* done) { int portId; @@ -175,7 +175,7 @@ _invalid_port: void MyService::deleteStream(::google::protobuf::RpcController* controller, const ::OstProto::StreamIdList* request, - ::OstProto::Ack* response, + ::OstProto::Ack* /*response*/, ::google::protobuf::Closure* done) { int portId; @@ -201,7 +201,7 @@ _invalid_port: void MyService::modifyStream(::google::protobuf::RpcController* controller, const ::OstProto::StreamConfigList* request, - ::OstProto::Ack* response, + ::OstProto::Ack* /*response*/, ::google::protobuf::Closure* done) { int portId; @@ -234,9 +234,9 @@ _invalid_port: done->Run(); } -void MyService::startTx(::google::protobuf::RpcController* controller, +void MyService::startTx(::google::protobuf::RpcController* /*controller*/, const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, + ::OstProto::Ack* /*response*/, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); @@ -257,9 +257,9 @@ void MyService::startTx(::google::protobuf::RpcController* controller, done->Run(); } -void MyService::stopTx(::google::protobuf::RpcController* controller, +void MyService::stopTx(::google::protobuf::RpcController* /*controller*/, const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, + ::OstProto::Ack* /*response*/, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); @@ -280,9 +280,9 @@ void MyService::stopTx(::google::protobuf::RpcController* controller, done->Run(); } -void MyService::startCapture(::google::protobuf::RpcController* controller, +void MyService::startCapture(::google::protobuf::RpcController* /*controller*/, const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, + ::OstProto::Ack* /*response*/, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); @@ -303,9 +303,9 @@ void MyService::startCapture(::google::protobuf::RpcController* controller, done->Run(); } -void MyService::stopCapture(::google::protobuf::RpcController* controller, +void MyService::stopCapture(::google::protobuf::RpcController* /*controller*/, const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, + ::OstProto::Ack* /*response*/, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); @@ -327,7 +327,7 @@ void MyService::stopCapture(::google::protobuf::RpcController* controller, void MyService::getCaptureBuffer(::google::protobuf::RpcController* controller, const ::OstProto::PortId* request, - ::OstProto::CaptureBuffer* response, + ::OstProto::CaptureBuffer* /*response*/, ::google::protobuf::Closure* done) { int portId; @@ -350,7 +350,7 @@ _invalid_port: done->Run(); } -void MyService::getStats(::google::protobuf::RpcController* controller, +void MyService::getStats(::google::protobuf::RpcController* /*controller*/, const ::OstProto::PortIdList* request, ::OstProto::PortStatsList* response, ::google::protobuf::Closure* done) @@ -397,9 +397,9 @@ void MyService::getStats(::google::protobuf::RpcController* controller, done->Run(); } -void MyService::clearStats(::google::protobuf::RpcController* controller, +void MyService::clearStats(::google::protobuf::RpcController* /*controller*/, const ::OstProto::PortIdList* request, - ::OstProto::Ack* response, + ::OstProto::Ack* /*response*/, ::google::protobuf::Closure* done) { qDebug("In %s", __PRETTY_FUNCTION__); diff --git a/server/pcapport.cpp b/server/pcapport.cpp index 2879680..9d1e4fb 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -24,7 +24,9 @@ PcapPort::PcapPort(int id, const char *device) { if (strcmp(device, dev->name) == 0) { -#ifndef Q_OS_WIN32 +#ifdef Q_OS_WIN32 + data_.set_name(QString("if%1 ").arg(id).toStdString()); +#else if (dev->name) data_.set_name(dev->name); #endif From 984d65b27d9b3d703152390f1dd042ad7a7f78a7 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 3 Jan 2010 13:57:47 +0000 Subject: [PATCH 42/98] - PortTransmitter on Windows now uses the Win32 QueryPerformanceCounter() instead of QThread::usleep() for more accurate timing - Port Stats limitations are now sent from the server to the client (as it should have always been!) --- client/port.h | 2 ++ client/portstatsmodel.cpp | 23 ++++++++------------ common/protocol.proto | 36 +++++++++++++++----------------- server/pcapport.cpp | 44 ++++++++++++++++++++++++++++++++++++++- server/pcapport.h | 2 ++ 5 files changed, 73 insertions(+), 34 deletions(-) diff --git a/client/port.h b/client/port.h index 53842a5..06162a0 100644 --- a/client/port.h +++ b/client/port.h @@ -45,6 +45,8 @@ public: { return QString().fromStdString(d.name()); } const QString description() const { return QString().fromStdString(d.description()); } + const QString notes() const + { return QString().fromStdString(d.notes()); } AdminStatus adminStatus() { return (d.is_enabled()?AdminEnable:AdminDisable); } ControlMode controlMode() diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 1958d8d..72b3d16 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -165,24 +165,23 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, int role) const { -#ifdef Q_OS_WIN32 - // TODO(MED): The limitations should be the server's not the client's! - // Ideally we shd enhance the protocol to convey limitation(s), if any, - // from server to client if (role == Qt::ToolTipRole) { if (orientation == Qt::Horizontal) { - return QString("Limitation(s)" - "

Frames/Bytes Receieved: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
" - "Frames/Bytes Sent: Only Ostinato Tx pkts (Tx by others NOT included)

" - "

Rx/Tx Rates are derived from the above and hence subject to same limitations

" - ); + QString notes; + uint portGroupIdx, portIdx; + + getDomainIndexes(index(0, section), portGroupIdx, portIdx); + notes = pgl->mPortGroups.at(portGroupIdx)->mPorts[portIdx]->notes(); + if (!notes.isEmpty()) + return notes; + else + return QVariant(); } else return QVariant(); } -#endif if (role != Qt::DisplayRole) return QVariant(); @@ -192,11 +191,7 @@ QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, in uint portGroupIdx, portIdx; getDomainIndexes(index(0, section), portGroupIdx, portIdx); -#ifdef Q_OS_WIN32 - return QString("Port %1-%2 (*)").arg(portGroupIdx).arg(portIdx); -#else return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx); -#endif } else return PortStatName.at(section); diff --git a/common/protocol.proto b/common/protocol.proto index 42caff1..86ceb59 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -15,18 +15,15 @@ message StreamCore { } // Basics - optional string name = 1; - optional bool is_enabled = 2; - optional uint32 ordinal = 3; + optional string name = 1; + optional bool is_enabled = 2; + optional uint32 ordinal = 3; // Frame Length (includes CRC) - optional FrameLengthMode len_mode = 14 [default = e_fl_fixed]; - optional uint32 frame_len = 15 [default = 64]; - optional uint32 frame_len_min = 16 [default = 64]; - optional uint32 frame_len_max = 17 [default = 1518]; - - // Currently Selected Protocols - //repeated uint32 frame_proto = 20; + optional FrameLengthMode len_mode = 14 [default = e_fl_fixed]; + optional uint32 frame_len = 15 [default = 64]; + optional uint32 frame_len_min = 16 [default = 64]; + optional uint32 frame_len_max = 17 [default = 1518]; } message StreamControl { @@ -46,14 +43,14 @@ message StreamControl { e_nw_goto_id = 2; } - optional SendUnit unit = 1 [default = e_su_packets]; - optional SendMode mode = 2 [default = e_sm_fixed]; - optional uint32 num_packets = 3 [default = 1]; - optional uint32 num_bursts = 4 [default = 1]; - optional uint32 packets_per_burst = 5 [default = 10]; - optional NextWhat next = 6 [default = e_nw_goto_next]; - optional uint32 packets_per_sec = 7 [default = 1]; - optional uint32 bursts_per_sec = 8 [default = 1]; + optional SendUnit unit = 1 [default = e_su_packets]; + optional SendMode mode = 2 [default = e_sm_fixed]; + optional uint32 num_packets = 3 [default = 1]; + optional uint32 num_bursts = 4 [default = 1]; + optional uint32 packets_per_burst = 5 [default = 10]; + optional NextWhat next = 6 [default = e_nw_goto_next]; + optional uint32 packets_per_sec = 7 [default = 1]; + optional uint32 bursts_per_sec = 8 [default = 1]; } message ProtocolId { @@ -129,7 +126,8 @@ message Port { required PortId port_id = 1; optional string name = 2; optional string description = 3; - optional bool is_enabled = 4; + optional string notes = 4; + optional bool is_enabled = 5; optional bool is_exclusive_control = 6; } diff --git a/server/pcapport.cpp b/server/pcapport.cpp index 9d1e4fb..ced12ab 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -2,6 +2,10 @@ #include +#ifdef Q_OS_WIN32 +#include +#endif + pcap_if_t *PcapPort::deviceList_ = NULL; PcapPort::PcapPort(int id, const char *device) @@ -40,11 +44,25 @@ PcapPort::PcapPort(int id, const char *device) void PcapPort::init() { + QString notes; + + if (!monitorRx_->isDirectional() && !data_.is_exclusive_control()) + notes.append("Rx Frames/Bytes: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
"); + if (!monitorTx_->isDirectional()) + { transmitter_->useExternalStats(&stats_); + notes.append("Tx Frames/Bytes: Only Ostinato Tx pkts (Tx by others NOT included)
"); + } transmitter_->setHandle(monitorRx_->handle()); + if (!notes.isEmpty()) + data_.set_notes(QString("Limitation(s)" + "

%1
" + "Rx/Tx Rates are also subject to above limitation(s)

"). + arg(notes).toStdString()); + monitorRx_->start(); monitorTx_->start(); } @@ -150,6 +168,14 @@ PcapPort::PortTransmitter::PortTransmitter(const char *device) { char errbuf[PCAP_ERRBUF_SIZE]; +#ifdef Q_OS_WIN32 + LARGE_INTEGER freq; + if (QueryPerformanceFrequency(&freq)) + ticksFreq_ = freq.QuadPart; + else + Q_ASSERT_X(false, "PortTransmitter::PortTransmitter", + "This Win32 platform does not support performance counter"); +#endif returnToQIdx_ = -1; stop_ = false; stats_ = new AbstractPort::PortStats; @@ -316,13 +342,29 @@ int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p, if (usec) { - QThread::usleep(usec); + udelay(usec); ts = hdr->ts; } } } } +void PcapPort::PortTransmitter::udelay(long usec) +{ +#ifdef Q_OS_WIN32 + LARGE_INTEGER tgtTicks; + LARGE_INTEGER curTicks; + + QueryPerformanceCounter(&curTicks); + tgtTicks.QuadPart = curTicks.QuadPart + (usec*ticksFreq_)/1000000; + + while (curTicks.QuadPart < tgtTicks.QuadPart) + QueryPerformanceCounter(&curTicks); +#else + QThread::usleep(usec); +#endif +} + PcapPort::PortCapturer::PortCapturer(const char *device) { device_ = QString::fromAscii(device); diff --git a/server/pcapport.h b/server/pcapport.h index 9f80e57..28e9499 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -80,8 +80,10 @@ protected: void run(); void stop(); private: + void udelay(long usec); int sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, int sync); + quint64 ticksFreq_; QList sendQueueList_; int returnToQIdx_; bool usingInternalStats_; From c97ae3bc55f7667b19af10c0fb80ced288166c82 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Fri, 8 Jan 2010 15:18:55 +0000 Subject: [PATCH 43/98] Fixed a bunch of memory leaks - thanks to the superb Valgrind! --- client/port.cpp | 2 ++ client/port.h | 3 ++- client/portgroup.cpp | 6 ++++-- client/portgrouplist.cpp | 16 +++++++++++++--- client/portgrouplist.h | 10 +++++++--- client/portstatsmodel.cpp | 8 ++++++-- client/portstatsmodel.h | 5 +++++ client/portswindow.cpp | 9 ++++++--- client/portswindow.h | 2 ++ common/protocolmanager.cpp | 10 ++++++++++ common/protocolmanager.h | 1 + common/streambase.cpp | 6 ++++-- rpc/rpcserver.cpp | 34 ++++++++++++++++++---------------- rpc/rpcserver.h | 14 ++++++++------ server/drone.cpp | 3 +++ server/pcapport.cpp | 6 ++++++ server/pcapport.h | 1 + server/portmanager.cpp | 2 ++ server/winpcapport.cpp | 2 ++ 19 files changed, 102 insertions(+), 38 deletions(-) diff --git a/client/port.cpp b/client/port.cpp index 2509927..fd091f4 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -22,6 +22,8 @@ Port::Port(quint32 id, quint32 portGroupId) Port::~Port() { + while (!mStreams.isEmpty()) + delete mStreams.takeFirst(); } void Port::updatePortConfig(OstProto::Port *port) diff --git a/client/port.h b/client/port.h index 06162a0..2c36660 100644 --- a/client/port.h +++ b/client/port.h @@ -13,8 +13,9 @@ class Port : public QObject { Q_OBJECT static uint mAllocStreamId; + OstProto::Port d; - OstProto::PortStats stats; + OstProto::PortStats stats; // FIXME(HI): consider removing mPortId as it is duplicated inside 'd' quint32 mPortId; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 8705224..ba5364c 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -23,8 +23,7 @@ PortGroup::PortGroup(QHostAddress ip, quint16 port) rpcController = new PbRpcController; rpcControllerStats = new PbRpcController; isGetStatsPending_ = false; - serviceStub = new OstProto::OstService::Stub(rpcChannel, - OstProto::OstService::STUB_OWNS_CHANNEL); + serviceStub = new OstProto::OstService::Stub(rpcChannel); // FIXME(LOW):Can't for my life figure out why this ain't working! //QMetaObject::connectSlotsByName(this); @@ -44,6 +43,9 @@ PortGroup::~PortGroup() // Disconnect and free rpc channel etc. PortGroup::disconnectFromHost(); delete serviceStub; + delete rpcControllerStats; + delete rpcController; + delete rpcChannel; } diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index 49aa539..b76fb15 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -11,15 +11,25 @@ PortGroupList::PortGroupList() PortGroup *pg; // TODO(LOW): Remove - new ModelTest(getStreamModel()); - new ModelTest(getPortModel()); - new ModelTest(getPortStatsModel()); + streamModelTester_ = new ModelTest(getStreamModel()); + portModelTester_ = new ModelTest(getPortModel()); + portStatsModelTester_ = new ModelTest(getPortStatsModel()); // Add the "Local" Port Group pg = new PortGroup; addPortGroup(*pg); } +PortGroupList::~PortGroupList() +{ + while (!mPortGroups.isEmpty()) + delete mPortGroups.takeFirst(); + + delete portStatsModelTester_; + delete portModelTester_; + delete streamModelTester_; +} + bool PortGroupList::isPortGroup(const QModelIndex& index) { return mPortGroupListModel.isPortGroup(index); diff --git a/client/portgrouplist.h b/client/portgrouplist.h index 3dd8f5f..e8d2433 100644 --- a/client/portgrouplist.h +++ b/client/portgrouplist.h @@ -21,13 +21,17 @@ class PortGroupList : public QObject { QList mPortGroups; PortModel mPortGroupListModel; - StreamModel mStreamListModel; - PortStatsModel mPortStatsModel; + StreamModel mStreamListModel; + PortStatsModel mPortStatsModel; + + QObject *streamModelTester_; + QObject *portModelTester_; + QObject *portStatsModelTester_; // Methods public: PortGroupList(); - + ~PortGroupList(); PortModel* getPortModel() { return &mPortGroupListModel; } PortStatsModel* getPortStatsModel() { return &mPortStatsModel; } diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 72b3d16..cc76c1f 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -6,8 +6,6 @@ PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent) : QAbstractTableModel(parent) { - QTimer *timer; - pgl = p; timer = new QTimer(); @@ -15,6 +13,12 @@ PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent) timer->start(1000); } +PortStatsModel::~PortStatsModel() +{ + timer->stop(); + delete timer; +} + int PortStatsModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h index 3baa7c2..0a2e3aa 100644 --- a/client/portstatsmodel.h +++ b/client/portstatsmodel.h @@ -4,6 +4,8 @@ #include #include +class QTimer; + typedef enum { // State e_STATE_START = 0, @@ -78,6 +80,7 @@ class PortStatsModel : public QAbstractTableModel public: PortStatsModel(PortGroupList *p, QObject *parent = 0); + ~PortStatsModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; @@ -109,6 +112,8 @@ class PortStatsModel : public QAbstractTableModel // Also it stores them as cumulative totals QList numPorts; + QTimer *timer; + void getDomainIndexes(const QModelIndex &index, uint &portGroupIdx, uint &portIdx) const; diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 22ae629..505891f 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -1,13 +1,15 @@ #include "portswindow.h" -#include "streamlistdelegate.h" -#include "streamconfigdialog.h" + #include #include +#include "streamconfigdialog.h" +#include "streamlistdelegate.h" + PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) : QWidget(parent) { - StreamListDelegate *delegate = new StreamListDelegate; + delegate = new StreamListDelegate; //slm = new StreamListModel(); //plm = new PortGroupList(); plm = pgl; @@ -72,6 +74,7 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) PortsWindow::~PortsWindow() { + delete delegate; } void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) diff --git a/client/portswindow.h b/client/portswindow.h index c6db222..e327c49 100644 --- a/client/portswindow.h +++ b/client/portswindow.h @@ -12,6 +12,7 @@ MED LOW */ +class QAbstractItemDelegate; class PortsWindow : public QWidget, private Ui::PortsWindow { @@ -26,6 +27,7 @@ public: private: QString lastNewPortGroup; + QAbstractItemDelegate *delegate; void updatePortViewActions(const QModelIndex& current); //void updateStreamViewActions(const QModelIndex& current); diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index eb948ba..faaef8f 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -62,6 +62,16 @@ ProtocolManager::ProtocolManager() populateNeighbourProtocols(); } +ProtocolManager::~ProtocolManager() +{ + numberToNameMap.clear(); + nameToNumberMap.clear(); + neighbourProtocols.clear(); + factory.clear(); + while (!protocolList.isEmpty()) + delete protocolList.takeFirst(); +} + void ProtocolManager::registerProtocol(int protoNumber, void *protoInstanceCreator) { diff --git a/common/protocolmanager.h b/common/protocolmanager.h index 86ccf5d..c80315e 100644 --- a/common/protocolmanager.h +++ b/common/protocolmanager.h @@ -19,6 +19,7 @@ class ProtocolManager public: ProtocolManager(); + ~ProtocolManager(); void registerProtocol(int protoNumber, void *protoInstanceCreator); diff --git a/common/streambase.cpp b/common/streambase.cpp index 671f4d3..a7320ee 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -50,9 +50,11 @@ StreamBase::StreamBase() : StreamBase::~StreamBase() { - delete mStreamId; - delete mCore; + currentFrameProtocols->destroy(); + delete currentFrameProtocols; delete mControl; + delete mCore; + delete mStreamId; } void StreamBase::protoDataCopyFrom(const OstProto::Stream &stream) diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index 73f6f51..c989946 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -10,6 +10,7 @@ RpcServer::RpcServer() isPending = false; pendingMethodId = -1; // don't care as long as isPending is false + controller_.Reset(); } RpcServer::~RpcServer() @@ -46,21 +47,22 @@ QString RpcServer::errorString() return errorString_; } -void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController) +void RpcServer::done(::google::protobuf::Message *request, + ::google::protobuf::Message *response) { - QIODevice *blob; - char msg[MSGBUF_SIZE]; - int len; + QIODevice *blob; + char msg[MSGBUF_SIZE]; + int len; //qDebug("In RpcServer::done"); - if (PbRpcController->Failed()) + if (controller_.Failed()) { qDebug("rpc failed"); goto _exit; } - blob = PbRpcController->binaryBlob(); + blob = controller_.binaryBlob(); if (blob) { len = blob->size(); @@ -85,17 +87,17 @@ void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcCo goto _exit; } - if (!resp->IsInitialized()) + if (!response->IsInitialized()) { qWarning("response missing required fields!!"); - qDebug(resp->InitializationErrorString().c_str()); + qDebug(response->InitializationErrorString().c_str()); qFatal("exiting"); goto _exit; } - resp->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg)); + response->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg)); - len = resp->ByteSize(); + len = response->ByteSize(); *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_RESPONSE); // type *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method @@ -105,14 +107,15 @@ void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcCo if (pendingMethodId != 12) { qDebug("Server(%s): sending %d bytes to client encoding <%s>", - __FUNCTION__, len + PB_HDR_SIZE, resp->DebugString().c_str()); + __FUNCTION__, len + PB_HDR_SIZE, response->DebugString().c_str()); //BUFDUMP(msg, len + 8); } clientSock->write(msg, PB_HDR_SIZE + len); _exit: - delete PbRpcController; + delete request; + delete response; isPending = false; } @@ -173,7 +176,6 @@ void RpcServer::when_dataAvail() static quint32 len; const ::google::protobuf::MethodDescriptor *methodDesc; ::google::protobuf::Message *req, *resp; - PbRpcController *controller; if (!parsing) { @@ -238,12 +240,12 @@ void RpcServer::when_dataAvail() //qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, //resp->DebugString().c_str()); - controller = new PbRpcController; + controller_.Reset(); //qDebug("before service->callmethod()"); - service->CallMethod(methodDesc, controller, req, resp, - NewCallback(this, &RpcServer::done, resp, controller)); + service->CallMethod(methodDesc, &controller_, req, resp, + NewCallback(this, &RpcServer::done, req, resp)); parsing = false; diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h index f4be419..9b8cd23 100644 --- a/rpc/rpcserver.h +++ b/rpc/rpcserver.h @@ -16,13 +16,14 @@ class RpcServer : public QObject { Q_OBJECT - QTcpServer *server; - QTcpSocket *clientSock; + QTcpServer *server; + QTcpSocket *clientSock; - ::google::protobuf::Service *service; + ::google::protobuf::Service *service; - bool isPending; - int pendingMethodId; + bool isPending; + int pendingMethodId; + PbRpcController controller_; QString errorString_; public: @@ -32,7 +33,8 @@ public: bool registerService(::google::protobuf::Service *service, quint16 tcpPortNum); QString errorString(); - void done(::google::protobuf::Message *resp, PbRpcController *controller); + void done(::google::protobuf::Message *req, + ::google::protobuf::Message *resp); private slots: void when_newConnection(); diff --git a/server/drone.cpp b/server/drone.cpp index 9dcccc8..0e03b29 100644 --- a/server/drone.cpp +++ b/server/drone.cpp @@ -20,6 +20,9 @@ Drone::Drone(QWidget *parent) Drone::~Drone() { trayIcon_->hide(); + + delete trayIcon_; + delete trayIconMenu_; delete rpcServer; delete service; } diff --git a/server/pcapport.cpp b/server/pcapport.cpp index ced12ab..ce576f2 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -195,6 +195,12 @@ _open_error: usingInternalHandle_ = false; } +PcapPort::PortTransmitter::~PortTransmitter() +{ + if (usingInternalStats_) + delete stats_; +} + void PcapPort::PortTransmitter::clearPacketList() { Q_ASSERT(!isRunning()); diff --git a/server/pcapport.h b/server/pcapport.h index 28e9499..423d15f 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -69,6 +69,7 @@ protected: { public: PortTransmitter(const char *device); + ~PortTransmitter(); void clearPacketList(); bool appendToPacketList(long sec, long usec, const uchar *packet, int length); diff --git a/server/portmanager.cpp b/server/portmanager.cpp index 1877234..bec541f 100644 --- a/server/portmanager.cpp +++ b/server/portmanager.cpp @@ -45,6 +45,8 @@ PortManager::PortManager() PortManager::~PortManager() { + while (!portList_.isEmpty()) + delete portList_.takeFirst(); } PortManager* PortManager::instance() diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp index b6e536d..8afefba 100644 --- a/server/winpcapport.cpp +++ b/server/winpcapport.cpp @@ -24,6 +24,8 @@ WinPcapPort::WinPcapPort(int id, const char *device) WinPcapPort::~WinPcapPort() { + delete monitorRx_; + delete monitorTx_; } OstProto::LinkState WinPcapPort::linkState() From 78a2de040b7e2e1fe7c993d67644f49b9060e4d0 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 10 Jan 2010 06:21:39 +0000 Subject: [PATCH 44/98] Enhancements - (Abs/Pcap/WinPcap)Port: Inter SendQueue Timing implemented using a dummy packet length of zero (this is not supported by the winpcap pcap_sendqueue_transmit() but since we don't use that API we are not affected) - (Abs/Pcap/WinPcap)Port: Loop Mode Timing across loop iterations implemented - Added the year 2010 to Copyright notice in the About dialog Fixes - (Win)PcapPort: Fixed the wrong rates when packets sent in 'burst' mode --- client/about.ui | 2 +- server/abstractport.cpp | 26 +++++++++++--------------- server/abstractport.h | 2 +- server/pcapport.cpp | 39 ++++++++++++++++++++++----------------- server/pcapport.h | 10 ++++++---- 5 files changed, 41 insertions(+), 38 deletions(-) diff --git a/client/about.ui b/client/about.ui index c7f914c..6ce0aed 100644 --- a/client/about.ui +++ b/client/about.ui @@ -51,7 +51,7 @@ p, li { white-space: pre-wrap; } - Copyright (c) 2007-2009 Srivats P. + Copyright (c) 2007-2010 Srivats P. Qt::AlignCenter diff --git a/server/abstractport.cpp b/server/abstractport.cpp index 7e71e0d..de2cecc 100644 --- a/server/abstractport.cpp +++ b/server/abstractport.cpp @@ -73,22 +73,18 @@ void AbstractPort::updatePacketList() int len; bool isVariable; uchar pktBuf[2000]; - long sec; - long usec; + long sec = 0; + long usec = 0; qDebug("In %s", __FUNCTION__); - clearPacketList(); - //returnToQIdx = -1; - // First sort the streams by ordinalValue qSort(streamList_); - sec = 0; - usec = 0; + clearPacketList(); + for (int i = 0; i < streamList_.size(); i++) { -//_restart: if (streamList_[i]->isEnabled()) { long numPackets, numBursts; @@ -139,18 +135,17 @@ void AbstractPort::updatePacketList() if (len <= 0) continue; + qDebug("q(%d, %d, %d) sec = %lu usec = %lu", + i, j, k, sec, usec); + + appendToPacketList(sec, usec, pktBuf, len); + usec += ipg; if (usec > 1000000) { sec++; usec -= 1000000; } - - qDebug("q(%d, %d, %d) sec = %lu usec = %lu", - i, j, k, sec, usec); - - appendToPacketList(sec, usec, pktBuf, len); - } // for (numPackets) usec += ibg; @@ -179,7 +174,8 @@ void AbstractPort::updatePacketList() returnToQIdx = 0; */ - setPacketListLoopMode(true); + setPacketListLoopMode(true, streamList_[i]->sendUnit() == + OstProto::StreamControl::e_su_bursts ? ibg : ipg); goto _stop_no_more_pkts; case ::OstProto::StreamControl::e_nw_goto_next: diff --git a/server/abstractport.h b/server/abstractport.h index e39d0f9..8df9edf 100644 --- a/server/abstractport.h +++ b/server/abstractport.h @@ -46,7 +46,7 @@ public: virtual void clearPacketList() = 0; virtual bool appendToPacketList(long sec, long usec, const uchar *packet, int length) = 0; - virtual void setPacketListLoopMode(bool loop) = 0; + virtual void setPacketListLoopMode(bool loop, long usecDelay) = 0; void updatePacketList(); virtual void startTransmit() = 0; diff --git a/server/pcapport.cpp b/server/pcapport.cpp index ce576f2..83ffb4c 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -177,6 +177,7 @@ PcapPort::PortTransmitter::PortTransmitter(const char *device) "This Win32 platform does not support performance counter"); #endif returnToQIdx_ = -1; + loopDelay_ = 0; stop_ = false; stats_ = new AbstractPort::PortStats; usingInternalStats_ = true; @@ -210,6 +211,7 @@ void PcapPort::PortTransmitter::clearPacketList() pcap_send_queue *sq = sendQueueList_.takeFirst(); pcap_sendqueue_destroy(sq); } + setPacketListLoopMode(false, 0); } bool PcapPort::PortTransmitter::appendToPacketList(long sec, long usec, @@ -223,24 +225,22 @@ bool PcapPort::PortTransmitter::appendToPacketList(long sec, long usec, pktHdr.ts.tv_sec = sec; pktHdr.ts.tv_usec = usec; - if (sendQueueList_.size()) - sendQ = sendQueueList_.last(); - else - sendQ = pcap_sendqueue_alloc(1*1024*1024); - - // Not enough space? Alloc another one! - if ((sendQ->len + length + sizeof(pcap_pkthdr)) > sendQ->maxlen) + sendQ = sendQueueList_.isEmpty() ? NULL : sendQueueList_.last(); + + if ((sendQ == NULL) || + (sendQ->len + sizeof(pcap_pkthdr) + length) > sendQ->maxlen) { - sendQueueList_.append(sendQ); - //! \todo (LOW): calculate sendqueue size sendQ = pcap_sendqueue_alloc(1*1024*1024); + sendQueueList_.append(sendQ); + + // Validate that the pkt will fit inside the new sendQ + Q_ASSERT((length + sizeof(pcap_pkthdr)) < sendQ->maxlen); } if (pcap_sendqueue_queue(sendQ, &pktHdr, (u_char*) packet) < 0) op = false; - sendQueueList_.append(sendQ); return op; } @@ -279,6 +279,8 @@ void PcapPort::PortTransmitter::run() const int kSyncTransmit = 1; int i; + qDebug("sendQueueList_.size = %d", sendQueueList_.size()); + for(i = 0; i < sendQueueList_.size(); i++) { int ret; @@ -286,17 +288,17 @@ _restart: ret = sendQueueTransmit(handle_, sendQueueList_.at(i), kSyncTransmit); if (ret < 0) + { + qDebug("error in sendQueueTransmit()"); return; - - //! \todo (HIGH): Timing between subsequent sendQueues + } } if (returnToQIdx_ >= 0) { i = returnToQIdx_; - //! \todo (HIGH) 1s fixed; Change this to ipg of last stream - QThread::usleep(1000000); + udelay(loopDelay_); goto _restart; } } @@ -327,11 +329,14 @@ int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p, return -2; } + // A pktLen of size 0 is used at the end of a sendQueue and before + // the next sendQueue - i.e. for inter sendQueue timing if(pktLen > 0) + { pcap_sendpacket(p, pkt, pktLen); - - stats_->txPkts++; - stats_->txBytes += pktLen; + stats_->txPkts++; + stats_->txBytes += pktLen; + } // Step to the next packet in the buffer hdr = (struct pcap_pkthdr*) ((uchar*)hdr + sizeof(*hdr) + pktLen); diff --git a/server/pcapport.h b/server/pcapport.h index 423d15f..bcef3cc 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -18,14 +18,14 @@ public: virtual void clearPacketList() { transmitter_->clearPacketList(); - setPacketListLoopMode(false); + setPacketListLoopMode(false, 0); } virtual bool appendToPacketList(long sec, long usec, const uchar *packet, int length) { return transmitter_->appendToPacketList(sec, usec, packet, length); } - virtual void setPacketListLoopMode(bool loop) { - transmitter_->setPacketListLoopMode(loop); + virtual void setPacketListLoopMode(bool loop, long usecDelay) { + transmitter_->setPacketListLoopMode(loop, usecDelay); } virtual void startTransmit() { @@ -73,8 +73,9 @@ protected: void clearPacketList(); bool appendToPacketList(long sec, long usec, const uchar *packet, int length); - void setPacketListLoopMode(bool loop) { + void setPacketListLoopMode(bool loop, long usecDelay) { returnToQIdx_ = loop ? 0 : -1; + loopDelay_ = usecDelay; } void setHandle(pcap_t *handle); void useExternalStats(AbstractPort::PortStats *stats); @@ -87,6 +88,7 @@ protected: quint64 ticksFreq_; QList sendQueueList_; int returnToQIdx_; + long loopDelay_; bool usingInternalStats_; AbstractPort::PortStats *stats_; bool usingInternalHandle_; From 70ca42fbb3fdea5506b16974343999fb8eff37ea Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 10 Jan 2010 14:40:33 +0000 Subject: [PATCH 45/98] Enhancements - Server now updates the "packet list" after every "apply" rather than before a "start transmit" (if dirty) - this better reflects user's expectation from these operations - Client disables the entire application and changes to a "Busy" cursor when "applying" stream configuration Fixes - UDP checksum no longer is zero but a valid value - Order of streams no longer gets messed up across a "apply" --- client/main.cpp | 13 +++++++++---- client/port.cpp | 4 ++-- client/portgroup.cpp | 21 ++++++++++++++++----- common/streambase.cpp | 9 ++++----- common/streambase.h | 4 ++-- common/udp.cpp | 1 + server/abstractport.cpp | 8 +++++++- server/abstractport.h | 1 + server/myservice.cpp | 5 ++++- server/pcapport.h | 3 +-- 10 files changed, 47 insertions(+), 22 deletions(-) diff --git a/client/main.cpp b/client/main.cpp index 994952a..53b43a6 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -2,11 +2,16 @@ #include +QMainWindow *mainWindow; + int main(int argc, char* argv[]) { - QApplication app(argc, argv); - MainWindow mainWin; + QApplication app(argc, argv); + int exitCode; - mainWin.show(); - return app.exec(); + mainWindow = new MainWindow; + mainWindow->show(); + exitCode = app.exec(); + delete mainWindow; + return exitCode; } diff --git a/client/port.cpp b/client/port.cpp index fd091f4..1606484 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -39,7 +39,7 @@ void Port::updateStreamOrdinalsFromIndex() void Port::reorderStreamsByOrdinals() { - qSort(mStreams); + qSort(mStreams.begin(), mStreams.end(), StreamBase::StreamLessThan); } bool Port::newStreamAt(int index) @@ -176,7 +176,7 @@ void Port::getModifiedStreamsSinceLastSync( void Port::when_syncComplete() { - qSort(mStreams); + //reorderStreamsByOrdinals(); mLastSyncStreamList.clear(); for (int i=0; i -#include -#include - #include "portgroup.h" +#include +#include +#include +#include +#include +#include + +extern QMainWindow *mainWindow; quint32 PortGroup::mPortGroupAllocId = 0; @@ -129,6 +133,9 @@ void PortGroup::when_configApply(int portIndex, uint *cookie) { OstProto::StreamIdList streamIdList; + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + mainWindow->setDisabled(true); + qDebug("applying 'deleted streams' ..."); streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); @@ -177,6 +184,10 @@ void PortGroup::when_configApply(int portIndex, uint *cookie) qDebug("apply completed"); mPorts[portIndex]->when_syncComplete(); delete cookie; + + mainWindow->setEnabled(true); + QApplication::restoreOverrideCursor(); + break; default: @@ -431,7 +442,7 @@ _exit: return; } -void PortGroup::processModifyStreamAck(OstProto::Ack */*ack*/) +void PortGroup::processModifyStreamAck(OstProto::Ack * /*ack*/) { qDebug("In %s", __FUNCTION__); diff --git a/common/streambase.cpp b/common/streambase.cpp index a7320ee..a09093b 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -113,11 +113,6 @@ ProtocolListIterator* StreamBase::createProtocolListIterator() const return new ProtocolListIterator(*currentFrameProtocols); } -bool StreamBase::operator < (const StreamBase &s) const -{ - return(mCore->ordinal() < s.mCore->ordinal()); -} - quint32 StreamBase::id() { return mStreamId->id(); @@ -380,3 +375,7 @@ int StreamBase::frameValue(uchar *buf, int bufMaxSize, int n) const return pktLen; } +bool StreamBase::StreamLessThan(StreamBase* stream1, StreamBase* stream2) +{ + return stream1->ordinal() < stream2->ordinal() ? true : false; +} diff --git a/common/streambase.h b/common/streambase.h index dd30232..5b40b1d 100644 --- a/common/streambase.h +++ b/common/streambase.h @@ -54,8 +54,6 @@ public: e_nw_goto_id }; - bool operator < (const StreamBase &s) const; - quint32 id(); bool setId(quint32 id); @@ -114,6 +112,8 @@ public: bool isFrameVariable() const; int frameValue(uchar *buf, int bufMaxSize, int n) const; + + static bool StreamLessThan(StreamBase* stream1, StreamBase* stream2); }; #endif diff --git a/common/udp.cpp b/common/udp.cpp index b83a07a..b755310 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -203,6 +203,7 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, else cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); qDebug("UDP cksum = %hu", cksum); + break; } default: cksum = 0; diff --git a/server/abstractport.cpp b/server/abstractport.cpp index de2cecc..e16b034 100644 --- a/server/abstractport.cpp +++ b/server/abstractport.cpp @@ -31,6 +31,12 @@ AbstractPort::~AbstractPort() { } +StreamBase* AbstractPort::streamAtIndex(int index) +{ + Q_ASSERT(index < streamList_.size()); + return streamList_.at(index); +} + StreamBase* AbstractPort::stream(int streamId) { for (int i = 0; i < streamList_.size(); i++) @@ -79,7 +85,7 @@ void AbstractPort::updatePacketList() qDebug("In %s", __FUNCTION__); // First sort the streams by ordinalValue - qSort(streamList_); + qSort(streamList_.begin(), streamList_.end(), StreamBase::StreamLessThan); clearPacketList(); diff --git a/server/abstractport.h b/server/abstractport.h index 8df9edf..87a8d25 100644 --- a/server/abstractport.h +++ b/server/abstractport.h @@ -34,6 +34,7 @@ public: void protoDataCopyInto(OstProto::Port *port) { port->CopyFrom(data_); } int streamCount() { return streamList_.size(); } + StreamBase* streamAtIndex(int index); StreamBase* stream(int streamId); bool addStream(StreamBase *stream); bool deleteStream(int streamId); diff --git a/server/myservice.cpp b/server/myservice.cpp index 123e9ce..a91be8f 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -88,7 +88,7 @@ void MyService::getStreamIdList(::google::protobuf::RpcController* controller, OstProto::StreamId *s; s = response->add_stream_id(); - s->set_id(portInfo[portId]->stream(i)->id()); + s->set_id(portInfo[portId]->streamAtIndex(i)->id()); } done->Run(); return; @@ -224,6 +224,9 @@ void MyService::modifyStream(::google::protobuf::RpcController* controller, } } + if (portInfo[portId]->isDirty()) + portInfo[portId]->updatePacketList(); + //! \todo(LOW): fill-in response "Ack"???? done->Run(); diff --git a/server/pcapport.h b/server/pcapport.h index bcef3cc..ed2ed70 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -29,8 +29,7 @@ public: } virtual void startTransmit() { - if (isDirty()) - updatePacketList(); + Q_ASSERT(!isDirty()); transmitter_->start(); } virtual void stopTransmit() { transmitter_->stop(); } From b28bcd3055db938df64fa94f86e698a0e02f3af5 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Tue, 9 Feb 2010 15:21:52 +0000 Subject: [PATCH 46/98] Implemented "exclusive control" for a port using bindconfig (Win32 only). Following changes done for the same - - OstProto service has a new method "modifyPort()" - At port init port.isExclusive is now set using a bindconfig query (Win32 only) - AbstractPort interface has 2 new pure virtual methods - hasExclusiveControl() and setExclusiveControl() - PcapPort does not support this functionality (yet) so these methods return false - WinPcapPort suppots this new functionality using bindconfig - Port's notes (specifying Rx/Tx limitations) are now set and updated based on hasExclusiveControl() - Presence of 'notes' on a port is indicated using a '*' after the port name in the port stats window - The tabwidget has been removed from Port Window | Stream View Pane - Ostinato Client has a new action in the port window's context menu for the same - Port Icon in the Port Window is decorated based on exclusive control --- client/icons/deco_exclusive.png | Bin 0 -> 793 bytes client/ostinato.qrc | 1 + client/port.cpp | 1 + client/port.h | 5 +- client/portgroup.cpp | 80 +++++++++++++++++++++++++++-- client/portgroup.h | 32 ++++++------ client/portmodel.cpp | 64 +++++++++++++----------- client/portmodel.h | 41 ++++++++------- client/portstatsmodel.cpp | 11 +++- client/portswindow.cpp | 30 +++++++++-- client/portswindow.h | 2 + client/portswindow.ui | 86 ++++++++++++-------------------- common/protocol.proto | 7 ++- rpc/pbrpcchannel.cpp | 8 +-- rpc/rpcserver.cpp | 2 +- server/abstractport.cpp | 20 +++++++- server/abstractport.h | 8 ++- server/myservice.cpp | 24 +++++++++ server/myservice.h | 4 ++ server/pcapport.cpp | 33 +++++++----- server/pcapport.h | 8 ++- server/winpcapport.cpp | 39 +++++++++++++++ server/winpcapport.h | 2 + 23 files changed, 356 insertions(+), 152 deletions(-) create mode 100644 client/icons/deco_exclusive.png diff --git a/client/icons/deco_exclusive.png b/client/icons/deco_exclusive.png new file mode 100644 index 0000000000000000000000000000000000000000..911da3f1d31fca4494a4beb22014e5c5c724c236 GIT binary patch literal 793 zcmV+!1LpjRP)`EB*FHYdKr%;k=xO&(k^EfNlSiKZ>5l+xr|%SFOV@6-ysFmD2F5 ze93OiS+LaQym;|2f6tbH%~V`D+ND?vc>4J^KSLxEMifJQ`8>*~y^+pGr&o-n=LJ zGWB(yB#;DR8&Lhqi{0(#wc#SwSB~jZKzIFx`8od>2Fo-Pfe7*M8^q#qw2yTxiXzd~ zRaz|F*rr78G`JZXG*YX~5K@5k>G@0HdlBo-6v1jHye?%qRwO@+-hO7J^4LlPG>@A1#{ zQFl4x7tnG)+cz_2Mq_f*H!U)kgg{iHqxT)Yr3ec@K!`)z_%h1c0Y2Eu(dMPkrhq5v zY+bKWfx|sTiOEB71HuwS*CDzA%ReBv4*7Zy7RM0n6`5#chfOJK`ze)Y6>d6Z?UmyNHH!3DdsP-ARyDo}1HO+>7_um7 zx_gj{+_aU_OUH_~Jd?KI#ICZujD`of2mDpCv_zFGE%6}tfL|j!WGu_i-u>4%{%d{$ X7`zMSfT21V00000NkvXXu0mjfkBx0` literal 0 HcmV?d00001 diff --git a/client/ostinato.qrc b/client/ostinato.qrc index ed5d604..5f4df48 100644 --- a/client/ostinato.qrc +++ b/client/ostinato.qrc @@ -12,6 +12,7 @@ icons/bullet_yellow.png icons/control_play.png icons/control_stop.png + icons/deco_exclusive.png icons/delete.png icons/magnifier.png icons/portgroup_add.png diff --git a/client/port.cpp b/client/port.cpp index 1606484..99e3112 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -22,6 +22,7 @@ Port::Port(quint32 id, quint32 portGroupId) Port::~Port() { + qDebug("%s", __FUNCTION__); while (!mStreams.isEmpty()) delete mStreams.takeFirst(); } diff --git a/client/port.h b/client/port.h index 2c36660..6c09e16 100644 --- a/client/port.h +++ b/client/port.h @@ -31,7 +31,6 @@ class Port : public QObject { public: enum AdminStatus { AdminDisable, AdminEnable }; - enum ControlMode { ControlShared, ControlExclusive }; // FIXME(HIGH): default args is a hack for QList operations on Port Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF); @@ -50,8 +49,8 @@ public: { return QString().fromStdString(d.notes()); } AdminStatus adminStatus() { return (d.is_enabled()?AdminEnable:AdminDisable); } - ControlMode controlMode() - { return (d.is_exclusive_control()?ControlExclusive:ControlShared); } + bool hasExclusiveControl() + { return d.is_exclusive_control(); } //void setAdminEnable(AdminStatus status) { mAdminStatus = status; } void setAlias(QString &alias) { mUserAlias = alias; } diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 769b9bb..f55470b 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -32,7 +32,7 @@ PortGroup::PortGroup(QHostAddress ip, quint16 port) // FIXME(LOW):Can't for my life figure out why this ain't working! //QMetaObject::connectSlotsByName(this); connect(rpcChannel, SIGNAL(stateChanged(QAbstractSocket::SocketState)), - this, SLOT(on_rpcChannel_stateChanged())); + this, SLOT(on_rpcChannel_stateChanged(QAbstractSocket::SocketState))); connect(rpcChannel, SIGNAL(connected()), this, SLOT(on_rpcChannel_connected())); connect(rpcChannel, SIGNAL(disconnected()), @@ -56,9 +56,9 @@ PortGroup::~PortGroup() // ------------------------------------------------ // Slots // ------------------------------------------------ -void PortGroup::on_rpcChannel_stateChanged() +void PortGroup::on_rpcChannel_stateChanged(QAbstractSocket::SocketState state) { - qDebug("state changed"); + qDebug("state changed %d", state); emit portGroupDataChanged(mPortGroupId); } @@ -275,6 +275,80 @@ _error_exit: delete portConfigList; } +void PortGroup::modifyPort(int portIndex, bool isExclusive) +{ + OstProto::PortConfigList portConfigList; + OstProto::Port *port; + OstProto::Ack *ack; + + qDebug("%s: portIndex = %d", __FUNCTION__, portIndex); + + Q_ASSERT(portIndex < mPorts.size()); + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + mainWindow->setDisabled(true); + + port = portConfigList.add_port(); + port->mutable_port_id()->set_id(mPorts[portIndex]->id()); + port->set_is_exclusive_control(isExclusive); + + ack = new OstProto::Ack; + rpcController->Reset(); + serviceStub->modifyPort(rpcController, &portConfigList, ack, + NewCallback(this, &PortGroup::processModifyPortAck, portIndex, ack)); +} + +void PortGroup::processModifyPortAck(int portIndex, OstProto::Ack *ack) +{ + OstProto::PortIdList portIdList; + OstProto::PortId *portId; + OstProto::PortConfigList *portConfigList; + + qDebug("In %s", __FUNCTION__); + + portId = portIdList.add_port_id(); + portId->set_id(mPorts[portIndex]->id()); + + portConfigList = new OstProto::PortConfigList; + + rpcController->Reset(); + serviceStub->getPortConfig(rpcController, &portIdList, portConfigList, + NewCallback(this, &PortGroup::processUpdatedPortConfig, + portConfigList)); + + delete ack; +} + +void PortGroup::processUpdatedPortConfig(OstProto::PortConfigList *portConfigList) +{ + qDebug("In %s", __FUNCTION__); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _exit; + } + + if (portConfigList->port_size() != 1) + qDebug("port size = %d (expected = 1)", portConfigList->port_size()); + + for(int i = 0; i < portConfigList->port_size(); i++) + { + uint id; + + id = portConfigList->port(i).port_id().id(); + // FIXME: don't mix port id & index into mPorts[] + mPorts[id]->updatePortConfig(portConfigList->mutable_port(i)); + } + + emit portGroupDataChanged(mPortGroupId); + +_exit: + mainWindow->setEnabled(true); + QApplication::restoreOverrideCursor(); + delete portConfigList; +} + void PortGroup::getStreamIdList(int portIndex, OstProto::StreamIdList *streamIdList) { diff --git a/client/portgroup.h b/client/portgroup.h index 4566b46..f4bc502 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -23,21 +23,19 @@ class PortGroup : public QObject { Q_OBJECT private: - quint32 mPortGroupId; - static quint32 mPortGroupAllocId; - QString mUserAlias; // user defined -#if 0 // PB - QTcpSocket *mpSocket; - QHostAddress mServerAddress; - quint16 mServerPort; -#endif - PbRpcChannel *rpcChannel; - PbRpcController *rpcController; - PbRpcController *rpcControllerStats; - bool isGetStatsPending_; - ::OstProto::OstService::Stub *serviceStub; + static quint32 mPortGroupAllocId; + quint32 mPortGroupId; + QString mUserAlias; // user defined + + PbRpcChannel *rpcChannel; + PbRpcController *rpcController; + PbRpcController *rpcControllerStats; + bool isGetStatsPending_; + + ::OstProto::OstService::Stub *serviceStub; + + ::OstProto::PortIdList portIdList; - ::OstProto::PortIdList portIdList; public: // FIXME(HIGH): member access QList mPorts; @@ -67,6 +65,10 @@ public: void processPortIdList(OstProto::PortIdList *portIdList); void processPortConfigList(OstProto::PortConfigList *portConfigList); + void modifyPort(int portId, bool isExclusive); + void processModifyPortAck(int portIndex, OstProto::Ack *ack); + void processUpdatedPortConfig(OstProto::PortConfigList *portConfigList); + void getStreamIdList(int portIndex = 0, OstProto::StreamIdList *streamIdList = NULL); void getStreamConfigList(int portIndex = 0, @@ -98,7 +100,7 @@ signals: void statsChanged(quint32 portGroupId); private slots: - void on_rpcChannel_stateChanged(); + void on_rpcChannel_stateChanged(QAbstractSocket::SocketState state); void on_rpcChannel_connected(); void on_rpcChannel_disconnected(); void on_rpcChannel_error(QAbstractSocket::SocketError socketError); diff --git a/client/portmodel.cpp b/client/portmodel.cpp index 241090d..cb62664 100644 --- a/client/portmodel.cpp +++ b/client/portmodel.cpp @@ -1,6 +1,8 @@ #include "portmodel.h" #include "portgrouplist.h" + #include +#include #if 0 #define DBG0(x) qDebug(x) @@ -14,6 +16,23 @@ PortModel::PortModel(PortGroupList *p, QObject *parent) : QAbstractItemModel(parent) { pgl = p; + + portIconFactory[OstProto::LinkStateUnknown][false] = + QIcon(":/icons/bullet_white.png"); + portIconFactory[OstProto::LinkStateDown][false] = + QIcon(":/icons/bullet_red.png"); + portIconFactory[OstProto::LinkStateUp][false] = + QIcon(":/icons/bullet_green.png"); + + for (int linkState = 0; linkState < kLinkStatesCount; linkState++) + { + QPixmap pixmap(":/icons/deco_exclusive.png"); + QPainter painter(&pixmap); + QIcon icon = portIconFactory[linkState][false]; + + painter.drawPixmap(0, 0, icon.pixmap(QSize(32,32))); + portIconFactory[linkState][true] = QIcon(pixmap); + } } int PortModel::rowCount(const QModelIndex &parent) const @@ -123,38 +142,27 @@ QVariant PortModel::data(const QModelIndex &index, int role) const } else { + if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) + { + DBG0("Exit PortModel data 4\n"); + return QVariant(); + } + + Port *port = pgl->mPortGroups.at(parent.row())->mPorts[index.row()]; + // Non Top Level - Port if ((role == Qt::DisplayRole)) { - DBG0("Exit PortModel data 4\n"); - if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) - return QVariant(); - - return QString("Port %1: %2 [%3] (%4)"). - arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()]->id()). - arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()]->name()). - arg(QHostAddress("0.0.0.0").toString()). // FIXME(LOW) - arg(pgl->mPortGroups.at( - parent.row())->mPorts[index.row()]->description()); + // FIXME(LOW) - IP Address below + return QString("Port %1: %2 [%3] (%4)") + .arg(port->id()) + .arg(port->name()) + .arg(QHostAddress("0.0.0.0").toString()) + .arg(port->description()); } else if ((role == Qt::DecorationRole)) { - DBG0("Exit PortModel data 5\n"); - if (pgl->mPortGroups.at(parent.row())->numPorts() == 0) - return QVariant(); - switch(pgl->mPortGroups.at(parent.row())->mPorts[index.row()]->linkState()) - { - case OstProto::LinkStateUnknown: - return QIcon(":/icons/bullet_white.png"); - case OstProto::LinkStateDown: - return QIcon(":/icons/bullet_red.png"); - case OstProto::LinkStateUp: - return QIcon(":/icons/bullet_green.png"); - default: - qFatal("unexpected/unimplemented port oper state"); - } + return portIconFactory[port->linkState()][port->hasExclusiveControl()]; } else { @@ -235,7 +243,7 @@ QModelIndex PortModel::parent(const QModelIndex &index) const bool PortModel::isPortGroup(const QModelIndex& index) { - if ((index.internalId() & 0xFFFF) == 0xFFFF) + if (index.isValid() && ((index.internalId() & 0xFFFF) == 0xFFFF)) return true; else return false; @@ -243,7 +251,7 @@ bool PortModel::isPortGroup(const QModelIndex& index) bool PortModel::isPort(const QModelIndex& index) { - if ((index.internalId() & 0xFFFF) != 0xFFFF) + if (index.isValid() && ((index.internalId() & 0xFFFF) != 0xFFFF)) return true; else return false; diff --git a/client/portmodel.h b/client/portmodel.h index 7f3b821..566785c 100644 --- a/client/portmodel.h +++ b/client/portmodel.h @@ -2,6 +2,7 @@ #define _PORT_MODEL_H #include +#include class PortGroupList; class PortGroup; @@ -12,24 +13,29 @@ class PortModel : public QAbstractItemModel friend class PortGroupList; +public: + PortModel(PortGroupList *p, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QModelIndex index (int row, int col, + const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + + bool isPortGroup(const QModelIndex& index); + bool isPort(const QModelIndex& index); + quint32 portGroupId(const QModelIndex& index); + quint32 portId(const QModelIndex& index); + +private: PortGroupList *pgl; - - public: - PortModel(PortGroupList *p, QObject *parent = 0); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QModelIndex index (int row, int col, const QModelIndex & parent = QModelIndex() ) const; - QModelIndex parent(const QModelIndex &index) const; - - bool isPortGroup(const QModelIndex& index); - bool isPort(const QModelIndex& index); - quint32 portGroupId(const QModelIndex& index); - quint32 portId(const QModelIndex& index); - + static const int kLinkStatesCount = 3; + static const int kExclusiveStatesCount = 2; + QIcon portIconFactory[kLinkStatesCount][kExclusiveStatesCount]; private slots: void when_portGroupDataChanged(int portGroupId, int portId); @@ -45,7 +51,6 @@ private slots: void triggerLayoutAboutToBeChanged(); void triggerLayoutChanged(); #endif - }; #endif diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index cc76c1f..80241cf 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -193,9 +193,18 @@ QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, in if (orientation == Qt::Horizontal) { uint portGroupIdx, portIdx; + QString portName; getDomainIndexes(index(0, section), portGroupIdx, portIdx); - return QString("Port %1-%2").arg(portGroupIdx).arg(portIdx); + portName = QString("Port %1-%2").arg(portGroupIdx).arg(portIdx); + if (portGroupIdx < (uint) pgl->mPortGroups.size() + && portIdx < (uint) pgl->mPortGroups.at(portGroupIdx)->mPorts.size()) + { + if (!pgl->mPortGroups.at(portGroupIdx)->mPorts[portIdx]->notes() + .isEmpty()) + portName += " *"; + } + return portName; } else return PortStatName.at(section); diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 505891f..bc52e91 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -16,6 +16,8 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) setupUi(this); + tvPortList->header()->hide(); + tvStreamList->setItemDelegate(delegate); tvStreamList->verticalHeader()->setDefaultSectionSize( @@ -27,6 +29,8 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) tvPortList->addAction(actionConnect_Port_Group); tvPortList->addAction(actionDisconnect_Port_Group); + tvPortList->addAction(actionExclusive_Control); + tvStreamList->addAction(actionNew_Stream); tvStreamList->addAction(actionEdit_Stream); tvStreamList->addAction(actionDelete_Stream); @@ -210,6 +214,8 @@ void PortsWindow::updatePortViewActions(const QModelIndex& current) actionDelete_Port_Group->setDisabled(true); actionConnect_Port_Group->setDisabled(true); actionDisconnect_Port_Group->setDisabled(true); + + actionExclusive_Control->setDisabled(true); goto _EXIT; } @@ -219,6 +225,9 @@ void PortsWindow::updatePortViewActions(const QModelIndex& current) if (plm->isPortGroup(current)) { actionDelete_Port_Group->setEnabled(true); + + actionExclusive_Control->setDisabled(true); + switch(plm->portGroup(current).state()) { case QAbstractSocket::UnconnectedState: @@ -247,9 +256,15 @@ void PortsWindow::updatePortViewActions(const QModelIndex& current) } else if (plm->isPort(current)) { - actionDelete_Port_Group->setEnabled(false); - actionConnect_Port_Group->setEnabled(false); - actionDisconnect_Port_Group->setEnabled(false); + actionDelete_Port_Group->setDisabled(true); + actionConnect_Port_Group->setDisabled(true); + actionDisconnect_Port_Group->setDisabled(true); + + actionExclusive_Control->setEnabled(true); + if (plm->port(current).hasExclusiveControl()) + actionExclusive_Control->setChecked(true); + else + actionExclusive_Control->setChecked(false); } _EXIT: @@ -346,6 +361,15 @@ void PortsWindow::on_actionDisconnect_Port_Group_triggered() if (current.isValid()) plm->portGroup(current).disconnectFromHost(); } + +void PortsWindow::on_actionExclusive_Control_triggered(bool checked) +{ + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + + if (plm->isPort(current)) + plm->portGroup(current.parent()).modifyPort(current.row(), checked); +} + #if 0 void PortsWindow::on_actionNew_Stream_triggered() { diff --git a/client/portswindow.h b/client/portswindow.h index e327c49..6389887 100644 --- a/client/portswindow.h +++ b/client/portswindow.h @@ -51,6 +51,8 @@ private slots: void on_actionConnect_Port_Group_triggered(); void on_actionDisconnect_Port_Group_triggered(); + void on_actionExclusive_Control_triggered(bool checked); + void on_actionNew_Stream_triggered(); void on_actionEdit_Stream_triggered(); void on_actionDelete_Stream_triggered(); diff --git a/client/portswindow.ui b/client/portswindow.ui index 9e461a2..17361d4 100644 --- a/client/portswindow.ui +++ b/client/portswindow.ui @@ -6,7 +6,7 @@ 0 0 689 - 254 + 352 @@ -34,7 +34,10 @@ 0 - + + + 6 + 0 @@ -47,13 +50,7 @@ 0 - - 6 - - - 6 - - + @@ -77,7 +74,7 @@ - + QFrame::StyledPanel @@ -129,52 +126,23 @@ - - - - 0 + + + + Qt::ActionsContextMenu + + + QFrame::StyledPanel + + + 1 + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows - - - Control - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::ActionsContextMenu - - - QFrame::NoFrame - - - 0 - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - - -
@@ -254,6 +222,14 @@ Edit Stream + + + true + + + Exclusive Control (EXPERIMENTAL) + + diff --git a/common/protocol.proto b/common/protocol.proto index 86ceb59..d1205f7 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -1,9 +1,7 @@ -// stream.proto - package OstProto; message StreamId { - required uint32 id = 1; + required uint32 id = 1; } message StreamCore { @@ -136,7 +134,7 @@ message PortConfigList { } message StreamConfigList { - required PortId port_id = 1; + required PortId port_id = 1; repeated Stream stream = 2; } @@ -188,6 +186,7 @@ message PortStatsList { service OstService { rpc getPortIdList(Void) returns (PortIdList); rpc getPortConfig(PortIdList) returns (PortConfigList); + rpc modifyPort(PortConfigList) returns (Ack); rpc getStreamIdList(PortId) returns (StreamIdList); rpc getStreamConfig(StreamIdList) returns (StreamConfigList); diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index a06d14e..6268320 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -64,7 +64,7 @@ void PbRpcChannel::CallMethod( ::google::protobuf::Closure* done) { char msg[MSGBUF_SIZE]; - int len; + int len; bool ret; if (isPending) @@ -80,6 +80,7 @@ void PbRpcChannel::CallMethod( call.done = done; pendingCallList.append(call); + qDebug("pendingCallList size = %d", pendingCallList.size()); Q_ASSERT(pendingCallList.size() < 100); @@ -113,7 +114,7 @@ void PbRpcChannel::CallMethod( *((quint32*)(&msg[4])) = HTONL(len); // len // Avoid printing stats since it happens every couple of seconds - if (pendingMethodId != 12) + if (pendingMethodId != 13) { qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, PB_HDR_SIZE + len, req->DebugString().c_str()); @@ -230,7 +231,7 @@ void PbRpcChannel::on_mpSocket_readyRead() response->ParseFromArray((void*) msg, len); // Avoid printing stats - if (method != 12) + if (method != 13) { qDebug("client(%s): Parsed as %s", __FUNCTION__, response->DebugString().c_str()); @@ -262,6 +263,7 @@ void PbRpcChannel::on_mpSocket_readyRead() if (pendingCallList.size()) { RpcCall call = pendingCallList.takeFirst(); + qDebug("RpcChannel: executing queued method %d", call.method->index()); CallMethod(call.method, call.controller, call.request, call.response, call.done); } diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index c989946..bb212ad 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -104,7 +104,7 @@ void RpcServer::done(::google::protobuf::Message *request, *((quint32*)(&msg[4])) = HTONL(len); // len // Avoid printing stats since it happens once every couple of seconds - if (pendingMethodId != 12) + if (pendingMethodId != 13) { qDebug("Server(%s): sending %d bytes to client encoding <%s>", __FUNCTION__, len + PB_HDR_SIZE, response->DebugString().c_str()); diff --git a/server/abstractport.cpp b/server/abstractport.cpp index e16b034..7d2c0cf 100644 --- a/server/abstractport.cpp +++ b/server/abstractport.cpp @@ -13,7 +13,6 @@ AbstractPort::AbstractPort(int id, const char *device) //! \todo (LOW) admin enable/disable of port data_.set_is_enabled(true); - //! \todo (HIGH) port exclusive control data_.set_is_exclusive_control(false); isSendQueueDirty_ = true; @@ -23,12 +22,29 @@ AbstractPort::AbstractPort(int id, const char *device) resetStats(); } +AbstractPort::~AbstractPort() +{ +} + void AbstractPort::init() { } -AbstractPort::~AbstractPort() +bool AbstractPort::modify(const OstProto::Port &port) { + bool ret = false; + + //! \todo Use reflection to find out which fields are set + if (port.has_is_exclusive_control()) + { + bool val = port.is_exclusive_control(); + + ret = setExclusiveControl(val); + if (ret) + data_.set_is_exclusive_control(val); + } + + return ret; } StreamBase* AbstractPort::streamAtIndex(int index) diff --git a/server/abstractport.h b/server/abstractport.h index 87a8d25..ba13d25 100644 --- a/server/abstractport.h +++ b/server/abstractport.h @@ -33,6 +33,12 @@ public: int id() { return data_.port_id().id(); } void protoDataCopyInto(OstProto::Port *port) { port->CopyFrom(data_); } + bool modify(const OstProto::Port &port); + + virtual OstProto::LinkState linkState() { return linkState_; } + virtual bool hasExclusiveControl() = 0; + virtual bool setExclusiveControl(bool exclusive) = 0; + int streamCount() { return streamList_.size(); } StreamBase* streamAtIndex(int index); StreamBase* stream(int streamId); @@ -42,8 +48,6 @@ public: bool isDirty() { return isSendQueueDirty_; } void setDirty() { isSendQueueDirty_ = true; } - virtual OstProto::LinkState linkState() { return linkState_; } - virtual void clearPacketList() = 0; virtual bool appendToPacketList(long sec, long usec, const uchar *packet, int length) = 0; diff --git a/server/myservice.cpp b/server/myservice.cpp index a91be8f..6a250a0 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -69,6 +69,30 @@ void MyService::getPortConfig(::google::protobuf::RpcController* /*controller*/, done->Run(); } +void MyService::modifyPort(::google::protobuf::RpcController* /*controller*/, + const ::OstProto::PortConfigList* request, + ::OstProto::Ack* /*response*/, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __PRETTY_FUNCTION__); + + for (int i = 0; i < request->port_size(); i++) + { + OstProto::Port port; + int id; + + port = request->port(i); + id = port.port_id().id(); + if (id < portInfo.size()) + { + portInfo[id]->modify(port); + } + } + + //! \todo (LOW): fill-in response "Ack"???? + done->Run(); +} + void MyService::getStreamIdList(::google::protobuf::RpcController* controller, const ::OstProto::PortId* request, ::OstProto::StreamIdList* response, diff --git a/server/myservice.h b/server/myservice.h index a813367..4122c5a 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -25,6 +25,10 @@ public: const ::OstProto::PortIdList* request, ::OstProto::PortConfigList* response, ::google::protobuf::Closure* done); + void MyService::modifyPort(::google::protobuf::RpcController* /*controller*/, + const ::OstProto::PortConfigList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); virtual void getStreamIdList(::google::protobuf::RpcController* controller, const ::OstProto::PortId* request, ::OstProto::StreamIdList* response, diff --git a/server/pcapport.cpp b/server/pcapport.cpp index 83ffb4c..8315fa8 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -44,24 +44,12 @@ PcapPort::PcapPort(int id, const char *device) void PcapPort::init() { - QString notes; - - if (!monitorRx_->isDirectional() && !data_.is_exclusive_control()) - notes.append("Rx Frames/Bytes: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
"); - if (!monitorTx_->isDirectional()) - { transmitter_->useExternalStats(&stats_); - notes.append("Tx Frames/Bytes: Only Ostinato Tx pkts (Tx by others NOT included)
"); - } transmitter_->setHandle(monitorRx_->handle()); - if (!notes.isEmpty()) - data_.set_notes(QString("Limitation(s)" - "

%1
" - "Rx/Tx Rates are also subject to above limitation(s)

"). - arg(notes).toStdString()); + updateNotes(); monitorRx_->start(); monitorTx_->start(); @@ -75,6 +63,25 @@ PcapPort::~PcapPort() delete monitorRx_; } +void PcapPort::updateNotes() +{ + QString notes; + + if (!monitorRx_->isDirectional() && !hasExclusiveControl()) + notes.append("Rx Frames/Bytes: Includes non Ostinato Tx pkts also (Tx by Ostinato are not included)
"); + + if (!monitorTx_->isDirectional() && !hasExclusiveControl()) + notes.append("Tx Frames/Bytes: Only Ostinato Tx pkts (Tx by others NOT included)
"); + + if (notes.isEmpty()) + data_.set_notes(""); + else + data_.set_notes(QString("Limitation(s)" + "

%1
" + "Rx/Tx Rates are also subject to above limitation(s)

"). + arg(notes).toStdString()); +} + PcapPort::PortMonitor::PortMonitor(const char *device, Direction direction, AbstractPort::PortStats *stats) { diff --git a/server/pcapport.h b/server/pcapport.h index ed2ed70..cd91889 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -16,6 +16,9 @@ public: void init(); + virtual bool hasExclusiveControl() { return false; } + virtual bool setExclusiveControl(bool exclusive) { return false; } + virtual void clearPacketList() { transmitter_->clearPacketList(); setPacketListLoopMode(false, 0); @@ -114,11 +117,14 @@ protected: PortMonitor *monitorRx_; PortMonitor *monitorTx_; + + void updateNotes(); + private: PortTransmitter *transmitter_; PortCapturer *capturer_; - static pcap_if_t *deviceList_; + static pcap_if_t *deviceList_; }; #endif diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp index 8afefba..4598489 100644 --- a/server/winpcapport.cpp +++ b/server/winpcapport.cpp @@ -1,5 +1,7 @@ #include "winpcapport.h" +#include + #ifdef Q_OS_WIN32 const uint OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114; @@ -20,6 +22,8 @@ WinPcapPort::WinPcapPort(int id, const char *device) sizeof(uint)); if (!linkStateOid_) qFatal("failed to alloc oidData"); + + data_.set_is_exclusive_control(hasExclusiveControl()); } WinPcapPort::~WinPcapPort() @@ -53,6 +57,41 @@ OstProto::LinkState WinPcapPort::linkState() return linkState_; } +bool WinPcapPort::hasExclusiveControl() +{ + QString portName(adapter_->Name + strlen("\\Device\\NPF_")); + int exitCode; + + qDebug("%s: %s", __FUNCTION__, portName.toAscii().constData()); + + exitCode = QProcess::execute("bindconfig.exe", + QStringList() << "comp" << portName); + + qDebug("%s: exit code %d", __FUNCTION__, exitCode); + + if (exitCode == 0) + return true; + else + return false; +} + +bool WinPcapPort::setExclusiveControl(bool exclusive) +{ + QString portName(adapter_->Name + strlen("\\Device\\NPF_")); + QString status; + + qDebug("%s: %s", __FUNCTION__, portName.toAscii().constData()); + + status = exclusive ? "disable" : "enable"; + + QProcess::execute("bindconfig.exe", + QStringList() << "comp" << portName << status); + + updateNotes(); + + return (exclusive == hasExclusiveControl()); +} + WinPcapPort::PortMonitor::PortMonitor(const char *device, Direction direction, AbstractPort::PortStats *stats) : PcapPort::PortMonitor(device, direction, stats) diff --git a/server/winpcapport.h b/server/winpcapport.h index 80a83c9..dc0c84d 100644 --- a/server/winpcapport.h +++ b/server/winpcapport.h @@ -16,6 +16,8 @@ public: ~WinPcapPort(); virtual OstProto::LinkState linkState(); + virtual bool hasExclusiveControl(); + virtual bool setExclusiveControl(bool exclusive); protected: class PortMonitor: public PcapPort::PortMonitor From 2581562ec506ed472fdb712328b52cf1ebd3dd1c Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 17 Feb 2010 15:26:42 +0000 Subject: [PATCH 47/98] Fixes - Queued RPC calls would cause crashes due to invalid pointers to request/response and/or controller; this has been fixed - PbRpcController now takes ownership of request and response messages and will delete them when it itself is being deleted - This design mandates that request and response messages for each RPC call have to be allocated on the heap. - The convention for the Closure 'done' call now is to allocate and pass a pointer to the controller object to it which will delete it after use; this requires that controller itself be also allocated on the heap (NOTE: this is just a convention - not mandatory) - All existing RPC calls (in portgroup.cpp) have been changed to follow the above convention - Reordering of queued RPC calls has been fixed - PortManager is now destroyed at exit; because of this fix the per port temporary capture files are auto-removed at exit - WinPcapPort destructor no longer deletes the monitor threads because the parent class PcapPort already does it - Capture does not automatically (and incorrectly) stop after one packet if started immediately after a View Capture operation - User is prompted to stop transmit on a port first if he tries to apply configuration changes on a port in 'transmit' state --- client/port.cpp | 1 + client/port.h | 12 +- client/portgroup.cpp | 748 ++++++++++++++++++--------------------- client/portgroup.h | 52 ++- client/portgrouplist.cpp | 7 +- client/portswindow.cpp | 8 + rpc/pbrpcchannel.cpp | 12 +- rpc/pbrpccontroller.h | 29 +- rpc/rpcserver.cpp | 19 +- rpc/rpcserver.h | 4 +- server/myservice.cpp | 3 + server/pcapport.cpp | 13 +- server/pcapport.h | 4 +- server/winpcapport.cpp | 2 - 14 files changed, 441 insertions(+), 473 deletions(-) diff --git a/client/port.cpp b/client/port.cpp index 99e3112..565af93 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -18,6 +18,7 @@ Port::Port(quint32 id, quint32 portGroupId) d.mutable_port_id()->set_id(id); stats.mutable_port_id()->set_id(id); mPortGroupId = portGroupId; + capFile_ = NULL; } Port::~Port() diff --git a/client/port.h b/client/port.h index 6c09e16..6e2e9d3 100644 --- a/client/port.h +++ b/client/port.h @@ -1,9 +1,10 @@ #ifndef _PORT_H #define _PORT_H -#include -#include #include +#include +#include + #include "stream.h" //class StreamModel; @@ -16,6 +17,7 @@ class Port : public QObject { OstProto::Port d; OstProto::PortStats stats; + QTemporaryFile *capFile_; // FIXME(HI): consider removing mPortId as it is duplicated inside 'd' quint32 mPortId; @@ -66,6 +68,12 @@ public: { return stats.state().link_state(); } OstProto::PortStats getStats() { return stats; } + QTemporaryFile* getCaptureFile() + { + delete capFile_; + capFile_ = new QTemporaryFile(); + return capFile_; + } // FIXME(MED): naming inconsistency - PortConfig/Stream; also retVal void updatePortConfig(OstProto::Port *port); diff --git a/client/portgroup.cpp b/client/portgroup.cpp index f55470b..7531ef6 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -7,26 +7,24 @@ #include #include +using ::google::protobuf::NewCallback; + extern QMainWindow *mainWindow; -quint32 PortGroup::mPortGroupAllocId = 0; +quint32 PortGroup::mPortGroupAllocId = 0; PortGroup::PortGroup(QHostAddress ip, quint16 port) { // Allocate an id for self mPortGroupId = PortGroup::mPortGroupAllocId++; - rpcChannel = new PbRpcChannel(ip, port); + portIdList_ = new OstProto::PortIdList; + portStatsList_ = new OstProto::PortStatsList; - /*! - \todo (HIGH) RPC Controller should be allocated and deleted for each RPC invocation - as implemented currently, if a RPC is invoked before the previous completes, - rpc controller is overwritten due to the Reset() call - maybe we need to pass the - pointer to the controller to the callback function also? - */ - rpcController = new PbRpcController; - rpcControllerStats = new PbRpcController; + statsController = new PbRpcController(portIdList_, portStatsList_); isGetStatsPending_ = false; + + rpcChannel = new PbRpcChannel(ip, port); serviceStub = new OstProto::OstService::Stub(rpcChannel); // FIXME(LOW):Can't for my life figure out why this ain't working! @@ -47,9 +45,8 @@ PortGroup::~PortGroup() // Disconnect and free rpc channel etc. PortGroup::disconnectFromHost(); delete serviceStub; - delete rpcControllerStats; - delete rpcController; delete rpcChannel; + delete statsController; } @@ -64,17 +61,17 @@ void PortGroup::on_rpcChannel_stateChanged(QAbstractSocket::SocketState state) void PortGroup::on_rpcChannel_connected() { - OstProto::Void void_; - OstProto::PortIdList *portIdList; + OstProto::Void *void_ = new OstProto::Void; + OstProto::PortIdList *portIdList = new OstProto::PortIdList; qDebug("connected\n"); emit portGroupDataChanged(mPortGroupId); qDebug("requesting portlist ..."); - portIdList = new OstProto::PortIdList(); - rpcController->Reset(); - serviceStub->getPortIdList(rpcController, &void_, portIdList, - NewCallback(this, &PortGroup::processPortIdList, portIdList)); + + PbRpcController *controller = new PbRpcController(void_, portIdList); + serviceStub->getPortIdList(controller, void_, portIdList, + NewCallback(this, &PortGroup::processPortIdList, controller)); } void PortGroup::on_rpcChannel_disconnected() @@ -95,112 +92,16 @@ void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) emit portGroupDataChanged(mPortGroupId); } -void PortGroup::when_configApply(int portIndex, uint *cookie) +void PortGroup::processPortIdList(PbRpcController *controller) { - uint *op; - OstProto::Ack *ack; + OstProto::PortIdList *portIdList + = static_cast(controller->response()); - Q_ASSERT(portIndex < mPorts.size()); + Q_ASSERT(portIdList != NULL); - if (state() != QAbstractSocket::ConnectedState) - { - if (cookie != NULL) - delete cookie; - return; - } - - if (cookie == NULL) - { - // cookie[0]: op [0 - delete, 1 - add, 2 - modify, 3 - Done!] - // cookie[1]: *ack - cookie = new uint[2]; - ack = new OstProto::Ack; - - cookie[0] = (uint) 0; - cookie[1] = (uint) ack; - } - else - { - ack = (OstProto::Ack*) cookie[1]; - } - - Q_ASSERT(cookie != NULL); - op = &cookie[0]; - - switch (*op) - { - case 0: - { - OstProto::StreamIdList streamIdList; - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - mainWindow->setDisabled(true); - - qDebug("applying 'deleted streams' ..."); - - streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - mPorts[portIndex]->getDeletedStreamsSinceLastSync(streamIdList); - - (*op)++; - rpcController->Reset(); - serviceStub->deleteStream(rpcController, &streamIdList, ack, - ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); - break; - } - - case 1: - { - OstProto::StreamIdList streamIdList; - - qDebug("applying 'new streams' ..."); - - streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - mPorts[portIndex]->getNewStreamsSinceLastSync(streamIdList); - - (*op)++; - rpcController->Reset(); - serviceStub->addStream(rpcController, &streamIdList, ack, - ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); - break; - } - - case 2: - { - OstProto::StreamConfigList streamConfigList; - - qDebug("applying 'modified streams' ..."); - - streamConfigList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - mPorts[portIndex]->getModifiedStreamsSinceLastSync(streamConfigList); - - (*op)++; - rpcController->Reset(); - serviceStub->modifyStream(rpcController, &streamConfigList, ack, - ::google::protobuf::NewCallback(this, &PortGroup::when_configApply, portIndex, cookie)); - break; - } - - case 3: - qDebug("apply completed"); - mPorts[portIndex]->when_syncComplete(); - delete cookie; - - mainWindow->setEnabled(true); - QApplication::restoreOverrideCursor(); - - break; - - default: - qDebug("%s: Unknown Op!!!", __FUNCTION__); - break; - } -} - -void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) -{ qDebug("got a portlist ..."); - if (rpcController->Failed()) + if (controller->Failed()) { qDebug("%s: rpc failed", __FUNCTION__); goto _error_exit; @@ -221,32 +122,37 @@ void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) emit portListChanged(mPortGroupId); - this->portIdList.CopyFrom(*portIdList); + portIdList_->CopyFrom(*portIdList); // Request PortConfigList { - OstProto::PortConfigList *portConfigList; - qDebug("requesting port config list ..."); - portConfigList = new OstProto::PortConfigList(); - rpcController->Reset(); - serviceStub->getPortConfig(rpcController, - portIdList, portConfigList, NewCallback(this, - &PortGroup::processPortConfigList, portConfigList)); - } + OstProto::PortIdList *portIdList2 = new OstProto::PortIdList(); + OstProto::PortConfigList *portConfigList = new OstProto::PortConfigList(); + PbRpcController *controller2 = new PbRpcController(portIdList2, + portConfigList); - goto _exit; + portIdList2->CopyFrom(*portIdList); + + serviceStub->getPortConfig(controller, portIdList2, portConfigList, + NewCallback(this, &PortGroup::processPortConfigList, controller2)); + + goto _exit; + } _error_exit: _exit: - delete portIdList; + delete controller; } -void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) +void PortGroup::processPortConfigList(PbRpcController *controller) { + OstProto::PortConfigList *portConfigList + = static_cast(controller->response()); + qDebug("In %s", __FUNCTION__); - if (rpcController->Failed()) + if (controller->Failed()) { qDebug("%s: rpc failed", __FUNCTION__); goto _error_exit; @@ -272,14 +178,89 @@ void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) getStreamIdList(); _error_exit: - delete portConfigList; + delete controller; +} + +void PortGroup::when_configApply(int portIndex) +{ + OstProto::StreamIdList *streamIdList; + OstProto::StreamConfigList *streamConfigList; + OstProto::Ack *ack; + PbRpcController *controller; + + Q_ASSERT(portIndex < mPorts.size()); + + if (state() != QAbstractSocket::ConnectedState) + return; + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + mainWindow->setDisabled(true); + + qDebug("applying 'deleted streams' ..."); + streamIdList = new OstProto::StreamIdList; + ack = new OstProto::Ack; + controller = new PbRpcController(streamIdList, ack); + + streamIdList->mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getDeletedStreamsSinceLastSync(*streamIdList); + + serviceStub->deleteStream(controller, streamIdList, ack, + NewCallback(this, &PortGroup::processDeleteStreamAck, controller)); + + qDebug("applying 'new streams' ..."); + streamIdList = new OstProto::StreamIdList; + ack = new OstProto::Ack; + controller = new PbRpcController(streamIdList, ack); + + streamIdList->mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getNewStreamsSinceLastSync(*streamIdList); + + serviceStub->addStream(controller, streamIdList, ack, + NewCallback(this, &PortGroup::processAddStreamAck, controller)); + + qDebug("applying 'modified streams' ..."); + streamConfigList = new OstProto::StreamConfigList; + ack = new OstProto::Ack; + controller = new PbRpcController(streamConfigList, ack); + + streamConfigList->mutable_port_id()->set_id(mPorts[portIndex]->id()); + mPorts[portIndex]->getModifiedStreamsSinceLastSync(*streamConfigList); + + serviceStub->modifyStream(controller, streamConfigList, ack, + NewCallback(this, &PortGroup::processModifyStreamAck, + portIndex, controller)); +} + +void PortGroup::processAddStreamAck(PbRpcController *controller) +{ + qDebug("In %s", __FUNCTION__); + delete controller; +} + +void PortGroup::processDeleteStreamAck(PbRpcController *controller) +{ + qDebug("In %s", __FUNCTION__); + delete controller; +} + +void PortGroup::processModifyStreamAck(int portIndex, + PbRpcController *controller) +{ + qDebug("In %s", __FUNCTION__); + + qDebug("apply completed"); + mPorts[portIndex]->when_syncComplete(); + + mainWindow->setEnabled(true); + QApplication::restoreOverrideCursor(); + + delete controller; } void PortGroup::modifyPort(int portIndex, bool isExclusive) { - OstProto::PortConfigList portConfigList; - OstProto::Port *port; - OstProto::Ack *ack; + OstProto::PortConfigList *portConfigList = new OstProto::PortConfigList; + OstProto::Ack *ack = new OstProto::Ack; qDebug("%s: portIndex = %d", __FUNCTION__, portIndex); @@ -288,42 +269,51 @@ void PortGroup::modifyPort(int portIndex, bool isExclusive) QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); mainWindow->setDisabled(true); - port = portConfigList.add_port(); + OstProto::Port *port = portConfigList->add_port(); port->mutable_port_id()->set_id(mPorts[portIndex]->id()); port->set_is_exclusive_control(isExclusive); - ack = new OstProto::Ack; - rpcController->Reset(); - serviceStub->modifyPort(rpcController, &portConfigList, ack, - NewCallback(this, &PortGroup::processModifyPortAck, portIndex, ack)); + PbRpcController *controller = new PbRpcController(portConfigList, ack); + serviceStub->modifyPort(controller, portConfigList, ack, + NewCallback(this, &PortGroup::processModifyPortAck, controller)); } -void PortGroup::processModifyPortAck(int portIndex, OstProto::Ack *ack) -{ - OstProto::PortIdList portIdList; - OstProto::PortId *portId; - OstProto::PortConfigList *portConfigList; - - qDebug("In %s", __FUNCTION__); - - portId = portIdList.add_port_id(); - portId->set_id(mPorts[portIndex]->id()); - - portConfigList = new OstProto::PortConfigList; - - rpcController->Reset(); - serviceStub->getPortConfig(rpcController, &portIdList, portConfigList, - NewCallback(this, &PortGroup::processUpdatedPortConfig, - portConfigList)); - - delete ack; -} - -void PortGroup::processUpdatedPortConfig(OstProto::PortConfigList *portConfigList) +void PortGroup::processModifyPortAck(PbRpcController *controller) { qDebug("In %s", __FUNCTION__); - if (rpcController->Failed()) + if (controller->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _exit; + } + + { + OstProto::PortIdList *portIdList = new OstProto::PortIdList; + OstProto::PortConfigList *portConfigList = new OstProto::PortConfigList; + PbRpcController *controller2 = new PbRpcController(portIdList, + portConfigList); + + OstProto::PortId *portId = portIdList->add_port_id(); + portId->CopyFrom(static_cast + (controller->request())->mutable_port(0)->port_id()); + + serviceStub->getPortConfig(controller, portIdList, portConfigList, + NewCallback(this, &PortGroup::processUpdatedPortConfig, + controller2)); + } +_exit: + delete controller; +} + +void PortGroup::processUpdatedPortConfig(PbRpcController *controller) +{ + OstProto::PortConfigList *portConfigList + = static_cast(controller->response()); + + qDebug("In %s", __FUNCTION__); + + if (controller->Failed()) { qDebug("%s: rpc failed", __FUNCTION__); goto _exit; @@ -346,47 +336,47 @@ void PortGroup::processUpdatedPortConfig(OstProto::PortConfigList *portConfigLis _exit: mainWindow->setEnabled(true); QApplication::restoreOverrideCursor(); - delete portConfigList; + delete controller; } -void PortGroup::getStreamIdList(int portIndex, - OstProto::StreamIdList *streamIdList) +void PortGroup::getStreamIdList() { - ::OstProto::PortId portId; - - qDebug("In %s", __FUNCTION__); - - if (streamIdList == NULL) + for (int portIndex = 0; portIndex < numPorts(); portIndex++) { - // First invocation (uses default params) - - // request StreamIdList for first port + OstProto::PortId *portId = new OstProto::PortId; + OstProto::StreamIdList *streamIdList = new OstProto::StreamIdList; + PbRpcController *controller = new PbRpcController(portId, streamIdList); - Q_ASSERT(portIndex == 0); - Q_ASSERT(numPorts() > 0); - streamIdList = new ::OstProto::StreamIdList(); + portId->set_id(mPorts[portIndex]->id()); - goto _request; + serviceStub->getStreamIdList(controller, portId, streamIdList, + NewCallback(this, &PortGroup::processStreamIdList, + portIndex, controller)); } +} - qDebug("got a streamIdlist ..."); +void PortGroup::processStreamIdList(int portIndex, PbRpcController *controller) +{ + OstProto::StreamIdList *streamIdList + = static_cast(controller->response()); - if (rpcController->Failed()) + qDebug("In %s (portIndex = %d)", __FUNCTION__, portIndex); + + if (controller->Failed()) { qDebug("%s: rpc failed", __FUNCTION__); - goto _next_port; // FIXME(MED): Partial RPC + goto _exit; } Q_ASSERT(portIndex < numPorts()); if (streamIdList->port_id().id() != mPorts[portIndex]->id()) { - qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", - __FUNCTION__, streamIdList->port_id().id(), mPorts[portIndex]->id(), - portIndex); - goto _next_port; // FIXME(MED): Partial RPC + qDebug("Invalid portId %d (expected %d) received for portIndex %d", + streamIdList->port_id().id(), mPorts[portIndex]->id(), portIndex); + goto _exit; } - // FIXME(MED): need to mPorts.clear()??? for(int i = 0; i < streamIdList->stream_id_size(); i++) { uint streamId; @@ -395,82 +385,69 @@ void PortGroup::getStreamIdList(int portIndex, mPorts[portIndex]->insertStream(streamId); } -_next_port: - // FIXME(HI): ideally we shd use signals/slots but this means - // we will have to use Port* instead of Port with QList<> - - // need to find a way for this mPorts[portIndex]->when_syncComplete(); - portIndex++; - if (portIndex >= numPorts()) + + // Are we done for all ports? + if (numPorts() && portIndex >= (numPorts()-1)) { - // We're done for all ports !!! - // FIXME(HI): some way to reset streammodel - - delete streamIdList; - - if (numPorts() > 0) - getStreamConfigList(); - - goto _exit; + getStreamConfigList(); } -_request: - portId.set_id(mPorts[portIndex]->id()); - streamIdList->Clear(); - - rpcController->Reset(); - serviceStub->getStreamIdList(rpcController, &portId, streamIdList, - NewCallback(this, &PortGroup::getStreamIdList, - portIndex, streamIdList)); - - goto _exit; - - - _exit: - return; + delete controller; } -void PortGroup::getStreamConfigList(int portIndex, - OstProto::StreamConfigList *streamConfigList) +void PortGroup::getStreamConfigList() { - OstProto::StreamIdList streamIdList; + qDebug("requesting stream config list ..."); + + for (int portIndex = 0; portIndex < numPorts(); portIndex++) + { + OstProto::StreamIdList *streamIdList = new OstProto::StreamIdList; + OstProto::StreamConfigList *streamConfigList + = new OstProto::StreamConfigList; + PbRpcController *controller = new PbRpcController( + streamIdList, streamConfigList); + + streamIdList->mutable_port_id()->set_id(mPorts[portIndex]->id()); + for (int j = 0; j < mPorts[portIndex]->numStreams(); j++) + { + OstProto::StreamId *s = streamIdList->add_stream_id(); + s->set_id(mPorts[portIndex]->streamByIndex(j)->id()); + } + + serviceStub->getStreamConfig(controller, streamIdList, streamConfigList, + NewCallback(this, &PortGroup::processStreamConfigList, + portIndex, controller)); + } +} + +void PortGroup::processStreamConfigList(int portIndex, + PbRpcController *controller) +{ + OstProto::StreamConfigList *streamConfigList + = static_cast(controller->response()); qDebug("In %s", __PRETTY_FUNCTION__); - if (streamConfigList == NULL) - { - // First invocation using default params - // - request for first port + Q_ASSERT(portIndex < numPorts()); - Q_ASSERT(portIndex == 0); - Q_ASSERT(numPorts() > 0); - - streamConfigList = new OstProto::StreamConfigList; - - goto _request; - } - - qDebug("got a streamconfiglist"); - - if (rpcController->Failed()) + if (controller->Failed()) { qDebug("%s: rpc failed", __FUNCTION__); - goto _next_port; + goto _exit; } Q_ASSERT(portIndex < numPorts()); if (streamConfigList->port_id().id() != mPorts[portIndex]->id()) { - qDebug("%s: Invalid portId %d (expected %d) received for portIndex %d", - __FUNCTION__, streamConfigList->port_id().id(), - mPorts[portIndex]->id(), portIndex); - goto _next_port; // FIXME(MED): Partial RPC + qDebug("Invalid portId %d (expected %d) received for portIndex %d", + streamConfigList->port_id().id(), mPorts[portIndex]->id(), portIndex); + goto _exit; } - // FIXME(MED): need to mStreams.clear()??? for(int i = 0; i < streamConfigList->stream_size(); i++) { uint streamId; @@ -480,84 +457,53 @@ void PortGroup::getStreamConfigList(int portIndex, streamConfigList->mutable_stream(i)); } -_next_port: - portIndex++; - + // Are we done for all ports? if (portIndex >= numPorts()) { - // We're done for all ports !!! - // FIXME(HI): some way to reset streammodel - - delete streamConfigList; - goto _exit; } -_request: - qDebug("requesting stream config list ..."); - - streamIdList.Clear(); - streamIdList.mutable_port_id()->set_id(mPorts[portIndex]->id()); - for (int j = 0; j < mPorts[portIndex]->numStreams(); j++) - { - OstProto::StreamId *s; - - s = streamIdList.add_stream_id(); - s->set_id(mPorts[portIndex]->streamByIndex(j)->id()); - } - streamConfigList->Clear(); - - rpcController->Reset(); - serviceStub->getStreamConfig(rpcController, - &streamIdList, streamConfigList, NewCallback(this, - &PortGroup::getStreamConfigList, portIndex, streamConfigList)); - _exit: - return; -} - -void PortGroup::processModifyStreamAck(OstProto::Ack * /*ack*/) -{ - qDebug("In %s", __FUNCTION__); - - qDebug("Modify Successful!!"); - - // TODO(HI): Apply Button should now be disabled???!!!!??? + delete controller; } void PortGroup::startTx(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; - qDebug("In %s", __FUNCTION__); if (state() != QAbstractSocket::ConnectedState) - return; + goto _exit; - ack = new OstProto::Ack; if (portList == NULL) goto _exit; - else + { + OstProto::PortIdList *portIdList = new OstProto::PortIdList; + OstProto::Ack *ack = new OstProto::Ack; + PbRpcController *controller = new PbRpcController(portIdList, ack); + for (int i = 0; i < portList->size(); i++) { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); + OstProto::PortId *portId = portIdList->add_port_id(); portId->set_id(portList->at(i)); } - } - serviceStub->startTx(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStartTxAck, ack)); + serviceStub->startTx(controller, portIdList, ack, + NewCallback(this, &PortGroup::processStartTxAck, controller)); + } _exit: return; } +void PortGroup::processStartTxAck(PbRpcController *controller) +{ + qDebug("In %s", __FUNCTION__); + + delete controller; +} + void PortGroup::stopTx(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; qDebug("In %s", __FUNCTION__); @@ -566,28 +512,33 @@ void PortGroup::stopTx(QList *portList) if ((portList == NULL) || (portList->size() == 0)) goto _exit; - - ack = new OstProto::Ack; - - for (int i = 0; i < portList->size(); i++) { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } + OstProto::PortIdList *portIdList = new OstProto::PortIdList; + OstProto::Ack *ack = new OstProto::Ack; + PbRpcController *controller = new PbRpcController(portIdList, ack); - rpcController->Reset(); - serviceStub->stopTx(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStopTxAck, ack)); + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId = portIdList->add_port_id(); + portId->set_id(portList->at(i)); + } + + serviceStub->stopTx(controller, portIdList, ack, + NewCallback(this, &PortGroup::processStopTxAck, controller)); + } _exit: return; } +void PortGroup::processStopTxAck(PbRpcController *controller) +{ + qDebug("In %s", __FUNCTION__); + + delete controller; +} + void PortGroup::startCapture(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; - qDebug("In %s", __FUNCTION__); if (state() != QAbstractSocket::ConnectedState) @@ -596,27 +547,33 @@ void PortGroup::startCapture(QList *portList) if ((portList == NULL) || (portList->size() == 0)) goto _exit; - ack = new OstProto::Ack; - - for (int i = 0; i < portList->size(); i++) { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } + OstProto::PortIdList *portIdList = new OstProto::PortIdList; + OstProto::Ack *ack = new OstProto::Ack; + PbRpcController *controller = new PbRpcController(portIdList, ack); - rpcController->Reset(); - serviceStub->startCapture(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStartCaptureAck, ack)); + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId = portIdList->add_port_id(); + portId->set_id(portList->at(i)); + } + + serviceStub->startCapture(controller, portIdList, ack, + NewCallback(this, &PortGroup::processStartCaptureAck, controller)); + } _exit: return; } +void PortGroup::processStartCaptureAck(PbRpcController *controller) +{ + qDebug("In %s", __FUNCTION__); + + delete controller; +} + void PortGroup::stopCapture(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; - qDebug("In %s", __FUNCTION__); if (state() != QAbstractSocket::ConnectedState) @@ -625,25 +582,33 @@ void PortGroup::stopCapture(QList *portList) if ((portList == NULL) || (portList->size() == 0)) goto _exit; - ack = new OstProto::Ack; - for (int i = 0; i < portList->size(); i++) { - OstProto::PortId *portId; - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); - } + OstProto::PortIdList *portIdList = new OstProto::PortIdList; + OstProto::Ack *ack = new OstProto::Ack; + PbRpcController *controller = new PbRpcController(portIdList, ack); - rpcController->Reset(); - serviceStub->stopCapture(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processStopCaptureAck, ack)); + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId = portIdList->add_port_id(); + portId->set_id(portList->at(i)); + } + + serviceStub->stopCapture(controller, portIdList, ack, + NewCallback(this, &PortGroup::processStopCaptureAck, controller)); + } _exit: return; } +void PortGroup::processStopCaptureAck(PbRpcController *controller) +{ + qDebug("In %s", __FUNCTION__); + + delete controller; +} + void PortGroup::viewCapture(QList *portList) { - static QTemporaryFile *capFile = NULL; - qDebug("In %s", __FUNCTION__); if (state() != QAbstractSocket::ConnectedState) @@ -652,62 +617,31 @@ void PortGroup::viewCapture(QList *portList) if ((portList == NULL) || (portList->size() != 1)) goto _exit; - if (capFile) - delete capFile; - - /*! \todo (MED) unable to reuse the same file 'coz capFile->resize(0) is - not working - it fails everytime */ - capFile = new QTemporaryFile(); - capFile->open(); - qDebug("Temp CapFile = %s", capFile->fileName().toAscii().constData()); for (int i = 0; i < portList->size(); i++) { - OstProto::PortId portId; - OstProto::CaptureBuffer *buf; + OstProto::PortId *portId = new OstProto::PortId; + OstProto::CaptureBuffer *buf = new OstProto::CaptureBuffer; + PbRpcController *controller = new PbRpcController(portId, buf); + QFile *capFile = mPorts[portList->at(i)]->getCaptureFile(); - portId.set_id(portList->at(i)); + portId->set_id(portList->at(i)); - buf = new OstProto::CaptureBuffer; - rpcController->Reset(); - rpcController->setBinaryBlob(capFile); - serviceStub->getCaptureBuffer(rpcController, &portId, buf, - NewCallback(this, &PortGroup::processViewCaptureAck, buf, (QFile*) capFile)); + capFile->open(QIODevice::ReadWrite|QIODevice::Truncate); + qDebug("Temp CapFile = %s", capFile->fileName().toAscii().constData()); + controller->setBinaryBlob(capFile); + + serviceStub->getCaptureBuffer(controller, portId, buf, + NewCallback(this, &PortGroup::processViewCaptureAck, controller)); } _exit: return; } -void PortGroup::processStartTxAck(OstProto::Ack *ack) +void PortGroup::processViewCaptureAck(PbRpcController *controller) { - qDebug("In %s", __FUNCTION__); + QFile *capFile = static_cast(controller->binaryBlob()); - delete ack; -} - -void PortGroup::processStopTxAck(OstProto::Ack *ack) -{ - qDebug("In %s", __FUNCTION__); - - delete ack; -} - -void PortGroup::processStartCaptureAck(OstProto::Ack *ack) -{ - qDebug("In %s", __FUNCTION__); - - delete ack; -} - -void PortGroup::processStopCaptureAck(OstProto::Ack *ack) -{ - qDebug("In %s", __FUNCTION__); - - delete ack; -} - -void PortGroup::processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile) -{ #ifdef Q_OS_WIN32 QString viewer("C:/Program Files/Wireshark/wireshark.exe"); #else @@ -722,90 +656,90 @@ void PortGroup::processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFi if (!QProcess::startDetached(viewer, QStringList() << capFile->fileName())) qDebug("Failed starting Wireshark"); - delete buf; + delete controller; } void PortGroup::getPortStats() { - OstProto::PortStatsList *portStatsList; - //qDebug("In %s", __FUNCTION__); if (state() != QAbstractSocket::ConnectedState) - return; + goto _exit; if (isGetStatsPending_) - return; + goto _exit; - portStatsList = new OstProto::PortStatsList; - rpcControllerStats->Reset(); + statsController->Reset(); isGetStatsPending_ = true; - serviceStub->getStats(rpcControllerStats, &portIdList, portStatsList, - NewCallback(this, &PortGroup::processPortStatsList, portStatsList)); + serviceStub->getStats(statsController, + static_cast(statsController->request()), + static_cast(statsController->response()), + NewCallback(this, &PortGroup::processPortStatsList)); + +_exit: + return; } -void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList) +void PortGroup::processPortStatsList() { //qDebug("In %s", __FUNCTION__); - if (rpcControllerStats->Failed()) + if (statsController->Failed()) { qDebug("%s: rpc failed", __FUNCTION__); goto _error_exit; } - for(int i = 0; i < portStatsList->port_stats_size(); i++) + for(int i = 0; i < portStatsList_->port_stats_size(); i++) { - uint id; - - id = portStatsList->port_stats(i).port_id().id(); + uint id = portStatsList_->port_stats(i).port_id().id(); // FIXME: don't mix port id & index into mPorts[] - mPorts[id]->updateStats(portStatsList->mutable_port_stats(i)); + mPorts[id]->updateStats(portStatsList_->mutable_port_stats(i)); } emit statsChanged(mPortGroupId); _error_exit: - delete portStatsList; isGetStatsPending_ = false; } void PortGroup::clearPortStats(QList *portList) { - OstProto::PortIdList portIdList; - OstProto::Ack *ack; - qDebug("In %s", __FUNCTION__); if (state() != QAbstractSocket::ConnectedState) - return; + goto _exit; - ack = new OstProto::Ack; - if (portList == NULL) - portIdList.CopyFrom(this->portIdList); - else { - for (int i = 0; i < portList->size(); i++) + OstProto::PortIdList *portIdList = new OstProto::PortIdList; + OstProto::Ack *ack = new OstProto::Ack; + PbRpcController *controller = new PbRpcController(portIdList, ack); + + if (portList == NULL) + portIdList->CopyFrom(*portIdList_); + else { - OstProto::PortId *portId; - - portId = portIdList.add_port_id(); - portId->set_id(portList->at(i)); + for (int i = 0; i < portList->size(); i++) + { + OstProto::PortId *portId = portIdList->add_port_id(); + portId->set_id(portList->at(i)); + } } - } - rpcController->Reset(); - serviceStub->clearStats(rpcController, &portIdList, ack, - NewCallback(this, &PortGroup::processClearStatsAck, ack)); + serviceStub->clearStats(controller, portIdList, ack, + NewCallback(this, &PortGroup::processClearStatsAck, controller)); + } +_exit: + return; } -void PortGroup::processClearStatsAck(OstProto::Ack *ack) +void PortGroup::processClearStatsAck(PbRpcController *controller) { qDebug("In %s", __FUNCTION__); // Refresh stats immediately after a stats clear/reset getPortStats(); - delete ack; + delete controller; } diff --git a/client/portgroup.h b/client/portgroup.h index f4bc502..88e96f7 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -28,13 +28,13 @@ private: QString mUserAlias; // user defined PbRpcChannel *rpcChannel; - PbRpcController *rpcController; - PbRpcController *rpcControllerStats; + PbRpcController *statsController; bool isGetStatsPending_; - ::OstProto::OstService::Stub *serviceStub; + OstProto::OstService::Stub *serviceStub; - ::OstProto::PortIdList portIdList; + OstProto::PortIdList *portIdList_; + OstProto::PortStatsList *portStatsList_; public: // FIXME(HIGH): member access QList mPorts; @@ -62,36 +62,40 @@ public: QAbstractSocket::SocketState state() const { return rpcChannel->state(); } - void processPortIdList(OstProto::PortIdList *portIdList); - void processPortConfigList(OstProto::PortConfigList *portConfigList); + void processPortIdList(PbRpcController *controller); + void processPortConfigList(PbRpcController *controller); + + void processAddStreamAck(PbRpcController *controller); + void processDeleteStreamAck(PbRpcController *controller); + void processModifyStreamAck(int portIndex, PbRpcController *controller); void modifyPort(int portId, bool isExclusive); - void processModifyPortAck(int portIndex, OstProto::Ack *ack); - void processUpdatedPortConfig(OstProto::PortConfigList *portConfigList); + void processModifyPortAck(PbRpcController *controller); + void processUpdatedPortConfig(PbRpcController *controller); - void getStreamIdList(int portIndex = 0, - OstProto::StreamIdList *streamIdList = NULL); - void getStreamConfigList(int portIndex = 0, - OstProto::StreamConfigList *streamConfigList = NULL); + void getStreamIdList(); + void processStreamIdList(int portIndex, PbRpcController *controller); + void getStreamConfigList(); + void processStreamConfigList(int portIndex, PbRpcController *controller); void processModifyStreamAck(OstProto::Ack *ack); void startTx(QList *portList = NULL); - void processStartTxAck(OstProto::Ack *ack); + void processStartTxAck(PbRpcController *controller); void stopTx(QList *portList = NULL); - void processStopTxAck(OstProto::Ack *ack); + void processStopTxAck(PbRpcController *controller); void startCapture(QList *portList = NULL); - void processStartCaptureAck(OstProto::Ack *ack); + void processStartCaptureAck(PbRpcController *controller); void stopCapture(QList *portList = NULL); - void processStopCaptureAck(OstProto::Ack *ack); + void processStopCaptureAck(PbRpcController *controller); void viewCapture(QList *portList = NULL); - void processViewCaptureAck(OstProto::CaptureBuffer *buf, QFile *capFile); + void processViewCaptureAck(PbRpcController *controller); void getPortStats(); - void processPortStatsList(OstProto::PortStatsList *portStatsList); + void processPortStatsList(); void clearPortStats(QList *portList = NULL); - void processClearStatsAck(OstProto::Ack *ack); + void processClearStatsAck(PbRpcController *controller); signals: void portGroupDataChanged(int portGroupId, int portId = 0xFFFF); @@ -106,16 +110,8 @@ private slots: void on_rpcChannel_error(QAbstractSocket::SocketError socketError); public slots: - void when_configApply(int portIndex, uint *cookie = NULL); -#if 0 // PB - void on_rpcChannel_when_dataAvail(); -#endif + void when_configApply(int portIndex); -private: -#if 0 // PB - void ProcessCapabilityInfo(const char *msg, qint32 size); - void ProcessMsg(const char *msg, quint32 size); -#endif }; #endif diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index b76fb15..6d8a079 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -22,12 +22,13 @@ PortGroupList::PortGroupList() PortGroupList::~PortGroupList() { - while (!mPortGroups.isEmpty()) - delete mPortGroups.takeFirst(); - delete portStatsModelTester_; delete portModelTester_; delete streamModelTester_; + + while (!mPortGroups.isEmpty()) + delete mPortGroups.takeFirst(); + } bool PortGroupList::isPortGroup(const QModelIndex& index) diff --git a/client/portswindow.cpp b/client/portswindow.cpp index bc52e91..f3b4760 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "streamconfigdialog.h" #include "streamlistdelegate.h" @@ -289,6 +290,13 @@ void PortsWindow::on_pbApply_clicked() goto _exit; } + if (plm->port(curPort).getStats().state().is_transmit_on()) + { + QMessageBox::information(0, "Configuration Change", + "Please stop transmit on the port before applying any changes"); + goto _exit; + } + curPortGroup = plm->getPortModel()->parent(curPort); if (!curPortGroup.isValid()) { diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index 6268320..9b5997f 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -70,8 +70,9 @@ void PbRpcChannel::CallMethod( if (isPending) { RpcCall call; - qDebug("RpcChannel: queueing method %d since %d is pending", - method->index(), pendingMethodId); + qDebug("RpcChannel: queueing method %d since %d is pending; " + "queued message = <%s>", + method->index(), pendingMethodId, req->DebugString().c_str()); call.method = method; call.controller = controller; @@ -252,18 +253,19 @@ void PbRpcChannel::on_mpSocket_readyRead() } + done->Run(); + pendingMethodId = -1; controller = NULL; response = NULL; isPending = false; parsing = false; - done->Run(); - if (pendingCallList.size()) { RpcCall call = pendingCallList.takeFirst(); - qDebug("RpcChannel: executing queued method %d", call.method->index()); + qDebug("RpcChannel: executing queued method %d <%s>", + call.method->index(), call.request->DebugString().c_str()); CallMethod(call.method, call.controller, call.request, call.response, call.done); } diff --git a/rpc/pbrpccontroller.h b/rpc/pbrpccontroller.h index 6eef8cd..50260d7 100644 --- a/rpc/pbrpccontroller.h +++ b/rpc/pbrpccontroller.h @@ -5,17 +5,26 @@ class QIODevice; +/*! +PbRpcController takes ownership of the 'request' and 'response' messages and +will delete them when it itself is destroyed +*/ class PbRpcController : public ::google::protobuf::RpcController { - bool failed; - QIODevice *blob; - std::string errStr; - public: - PbRpcController() { Reset(); } + PbRpcController(::google::protobuf::Message *request, + ::google::protobuf::Message *response) { + request_ = request; + response_ = response; + Reset(); + } + ~PbRpcController() { delete request_; delete response_; } + + ::google::protobuf::Message* request() { return request_; } + ::google::protobuf::Message* response() { return response_; } // Client Side Methods - void Reset() { failed=false; blob = NULL; } + void Reset() { failed = false; blob = NULL; } bool Failed() const { return failed; } void StartCancel() { /*! \todo (MED) */} std::string ErrorText() const { return errStr; } @@ -31,6 +40,14 @@ public: // srivatsp added QIODevice* binaryBlob() { return blob; }; void setBinaryBlob(QIODevice *binaryBlob) { blob = binaryBlob; }; + +private: + bool failed; + QIODevice *blob; + std::string errStr; + ::google::protobuf::Message *request_; + ::google::protobuf::Message *response_; + }; #endif diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index bb212ad..36d96e9 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -10,7 +10,6 @@ RpcServer::RpcServer() isPending = false; pendingMethodId = -1; // don't care as long as isPending is false - controller_.Reset(); } RpcServer::~RpcServer() @@ -47,22 +46,22 @@ QString RpcServer::errorString() return errorString_; } -void RpcServer::done(::google::protobuf::Message *request, - ::google::protobuf::Message *response) +void RpcServer::done(PbRpcController *controller) { + google::protobuf::Message *response = controller->response(); QIODevice *blob; char msg[MSGBUF_SIZE]; int len; //qDebug("In RpcServer::done"); - if (controller_.Failed()) + if (controller->Failed()) { qDebug("rpc failed"); goto _exit; } - blob = controller_.binaryBlob(); + blob = controller->binaryBlob(); if (blob) { len = blob->size(); @@ -114,8 +113,7 @@ void RpcServer::done(::google::protobuf::Message *request, clientSock->write(msg, PB_HDR_SIZE + len); _exit: - delete request; - delete response; + delete controller; isPending = false; } @@ -176,6 +174,7 @@ void RpcServer::when_dataAvail() static quint32 len; const ::google::protobuf::MethodDescriptor *methodDesc; ::google::protobuf::Message *req, *resp; + PbRpcController *controller; if (!parsing) { @@ -240,12 +239,12 @@ void RpcServer::when_dataAvail() //qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, //resp->DebugString().c_str()); - controller_.Reset(); + controller = new PbRpcController(req, resp); //qDebug("before service->callmethod()"); - service->CallMethod(methodDesc, &controller_, req, resp, - NewCallback(this, &RpcServer::done, req, resp)); + service->CallMethod(methodDesc, controller, req, resp, + google::protobuf::NewCallback(this, &RpcServer::done, controller)); parsing = false; diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h index 9b8cd23..0872373 100644 --- a/rpc/rpcserver.h +++ b/rpc/rpcserver.h @@ -23,7 +23,6 @@ class RpcServer : public QObject bool isPending; int pendingMethodId; - PbRpcController controller_; QString errorString_; public: @@ -33,8 +32,7 @@ public: bool registerService(::google::protobuf::Service *service, quint16 tcpPortNum); QString errorString(); - void done(::google::protobuf::Message *req, - ::google::protobuf::Message *resp); + void done(PbRpcController *controller); private slots: void when_newConnection(); diff --git a/server/myservice.cpp b/server/myservice.cpp index 6a250a0..3699cfd 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -25,6 +25,9 @@ MyService::MyService() MyService::~MyService() { + //! \todo Use a singleton destroyer instead + // http://www.research.ibm.com/designpatterns/pubs/ph-jun96.txt + delete PortManager::instance(); } void MyService::getPortIdList(::google::protobuf::RpcController* /*controller*/, diff --git a/server/pcapport.cpp b/server/pcapport.cpp index 8315fa8..8486702 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -57,6 +57,7 @@ void PcapPort::init() PcapPort::~PcapPort() { + qDebug("In %s", __FUNCTION__); delete capturer_; delete transmitter_; delete monitorTx_; @@ -296,7 +297,8 @@ _restart: if (ret < 0) { - qDebug("error in sendQueueTransmit()"); + qDebug("error %d in sendQueueTransmit()", ret); + stop_ = false; return; } } @@ -312,7 +314,8 @@ _restart: void PcapPort::PortTransmitter::stop() { - stop_ = true; + if (isRunning()) + stop_ = true; } int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p, @@ -332,7 +335,6 @@ int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p, if (stop_) { - stop_ = false; return -2; } @@ -453,7 +455,6 @@ void PcapPort::PortCapturer::run() if (stop_) { qDebug("user requested capture stop\n"); - stop_ = false; break; } } @@ -461,11 +462,13 @@ void PcapPort::PortCapturer::run() pcap_close(handle_); dumpHandle_ = NULL; handle_ = NULL; + stop_ = false; } void PcapPort::PortCapturer::stop() { - stop_ = true; + if (isRunning()) + stop_ = true; } QFile* PcapPort::PortCapturer::captureFile() diff --git a/server/pcapport.h b/server/pcapport.h index cd91889..5a1ef3f 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -95,7 +95,7 @@ protected: AbstractPort::PortStats *stats_; bool usingInternalHandle_; pcap_t *handle_; - bool stop_; + volatile bool stop_; }; class PortCapturer: public QThread @@ -109,7 +109,7 @@ protected: private: QString device_; - bool stop_; + volatile bool stop_; QTemporaryFile capFile_; pcap_t *handle_; pcap_dumper_t *dumpHandle_; diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp index 4598489..b9ddfdf 100644 --- a/server/winpcapport.cpp +++ b/server/winpcapport.cpp @@ -28,8 +28,6 @@ WinPcapPort::WinPcapPort(int id, const char *device) WinPcapPort::~WinPcapPort() { - delete monitorRx_; - delete monitorTx_; } OstProto::LinkState WinPcapPort::linkState() From 3281eb8f2018943918b89e533d2b2fec2c711d79 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 6 Mar 2010 09:20:22 +0000 Subject: [PATCH 48/98] - Build files cleanup - Top level Makefile now has a 'release' target - pcap_set_direction() is no longer invoked in case of Win32 as older versions of WinPcap do not support this API - MyService::modifyPort() declaration modified to fix the error reported by newer gcc compiler --- Makefile | 13 ++++++++----- client/ostinato.pro | 27 ++++++++++++++++++++------- server/drone.pro | 31 ++++++++++++++++++++++--------- server/myservice.h | 2 +- server/pcapport.cpp | 9 ++++++++- 5 files changed, 59 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 574c0a1..698cf1b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ -all: +release: QMAKE_CONFIG=-config release + +all release: qmake $(MAKE) -C rpc $(MAKE) -C common $(MAKE) -C server @@ -17,7 +19,8 @@ distclean: $(MAKE) -C client $@ qmake: - cd rpc && qmake && cd .. - cd common && qmake && cd .. - cd server && qmake && cd .. - cd client && qmake && cd .. + cd rpc && qmake $(QMAKE_CONFIG) && cd .. + cd common && qmake $(QMAKE_CONFIG) && cd .. + cd server && qmake $(QMAKE_CONFIG) && cd .. + cd client && qmake $(QMAKE_CONFIG) && cd .. + diff --git a/client/ostinato.pro b/client/ostinato.pro index a644eb9..c24cec0 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -1,14 +1,27 @@ TEMPLATE = app -CONFIG += qt debug +CONFIG += qt QT += network script INCLUDEPATH += "../rpc/" "../common/" LIBS += -lprotobuf -win32:LIBS += -L"../common/debug" -lostproto -unix: LIBS += -L"../common" -lostproto -win32:LIBS += -L"../rpc/debug" -lpbrpc -unix:LIBS += -L"../rpc" -lpbrpc -win32:POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" -unix:POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a" +win32 { + CONFIG(debug, debug|release) { + LIBS += -L"../common/debug" -lostproto + LIBS += -L"../rpc/debug" -lpbrpc + POST_TARGETDEPS += \ + "../common/debug/libostproto.a" \ + "../rpc/debug/libpbrpc.a" + } else { + LIBS += -L"../common/release" -lostproto + LIBS += -L"../rpc/release" -lpbrpc + POST_TARGETDEPS += \ + "../common/release/libostproto.a" \ + "../rpc/release/libpbrpc.a" + } +} else { + LIBS += -L"../common" -lostproto + LIBS += -L"../rpc" -lpbrpc + POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a" +} RESOURCES += ostinato.qrc HEADERS += \ dumpview.h \ diff --git a/server/drone.pro b/server/drone.pro index 5fc71d5..b0ae7d2 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -1,17 +1,30 @@ TEMPLATE = app -CONFIG += qt debug +CONFIG += qt QT += network script DEFINES += HAVE_REMOTE WPCAP INCLUDEPATH += "../rpc" -win32:LIBS += -lwpcap -lpacket -unix:LIBS += -lpcap -win32:LIBS += -L"../common/debug" -lostproto -unix:LIBS += -L"../common" -lostproto -win32:LIBS += -L"../rpc/debug" -lpbrpc -unix:LIBS += -L"../rpc" -lpbrpc +win32 { + LIBS += -lwpcap -lpacket + CONFIG(debug, debug|release) { + LIBS += -L"../common/debug" -lostproto + LIBS += -L"../rpc/debug" -lpbrpc + POST_TARGETDEPS += \ + "../common/debug/libostproto.a" \ + "../rpc/debug/libpbrpc.a" + } else { + LIBS += -L"../common/release" -lostproto + LIBS += -L"../rpc/release" -lpbrpc + POST_TARGETDEPS += \ + "../common/release/libostproto.a" \ + "../rpc/release/libpbrpc.a" + } +} else { + LIBS += -lpcap + LIBS += -L"../common" -lostproto + LIBS += -L"../rpc" -lpbrpc + POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a" +} LIBS += -lprotobuf -win32:POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a" -unix:POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a" RESOURCES += drone.qrc HEADERS += drone.h FORMS += drone.ui diff --git a/server/myservice.h b/server/myservice.h index 4122c5a..b292151 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -25,7 +25,7 @@ public: const ::OstProto::PortIdList* request, ::OstProto::PortConfigList* response, ::google::protobuf::Closure* done); - void MyService::modifyPort(::google::protobuf::RpcController* /*controller*/, + virtual void modifyPort(::google::protobuf::RpcController* /*controller*/, const ::OstProto::PortConfigList* request, ::OstProto::Ack* response, ::google::protobuf::Closure* done); diff --git a/server/pcapport.cpp b/server/pcapport.cpp index 8486702..96a33b6 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -97,7 +97,13 @@ PcapPort::PortMonitor::PortMonitor(const char *device, Direction direction, if (handle_ == NULL) goto _open_error; - +#ifdef Q_OS_WIN32 + // pcap_setdirection() API is not supported in Windows. + // NOTE: WinPcap 4.1.1 and above exports a dummy API that returns -1 + // but since we would like to work with previous versions of WinPcap + // also, we assume the API does not exist + ret = -1; +#else switch (direction_) { case kDirectionRx: @@ -109,6 +115,7 @@ PcapPort::PortMonitor::PortMonitor(const char *device, Direction direction, default: Q_ASSERT(false); } +#endif if (ret < 0) goto _set_direction_error; From f64d901729d8dcdbe0684169b6c6c4227e0e3806 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 13 Mar 2010 05:46:24 +0000 Subject: [PATCH 49/98] - Top level Makefile - The default 'all' target no longer has 'qmake' as prerequisite; 'make qmake' shd be done manually on a pristine codebase - eol's changed from dos-style to unix-style - Trivial changes in sample.h/sample.cpp - Implemented ARP protocol --- Makefile | 55 +- client/streamconfigdialog.cpp | 9 +- common/arp.cpp | 925 ++++++++++++++++++++++++++++++++++ common/arp.h | 101 ++++ common/arp.proto | 48 ++ common/arp.ui | 518 +++++++++++++++++++ common/intcombobox.h | 31 ++ common/ostproto.pro | 4 + common/protocolmanager.cpp | 27 +- common/sample.cpp | 2 +- common/sample.h | 6 +- 11 files changed, 1679 insertions(+), 47 deletions(-) create mode 100644 common/arp.cpp create mode 100644 common/arp.h create mode 100644 common/arp.proto create mode 100644 common/arp.ui create mode 100644 common/intcombobox.h diff --git a/Makefile b/Makefile index 698cf1b..ccbc2b8 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,29 @@ -release: QMAKE_CONFIG=-config release - -all release: qmake - $(MAKE) -C rpc - $(MAKE) -C common - $(MAKE) -C server - $(MAKE) -C client - -clean: - $(MAKE) -C rpc $@ - $(MAKE) -C common $@ - $(MAKE) -C server $@ - $(MAKE) -C client $@ - -distclean: - $(MAKE) -C rpc $@ - $(MAKE) -C common $@ - $(MAKE) -C server $@ - $(MAKE) -C client $@ - -qmake: - cd rpc && qmake $(QMAKE_CONFIG) && cd .. - cd common && qmake $(QMAKE_CONFIG) && cd .. - cd server && qmake $(QMAKE_CONFIG) && cd .. - cd client && qmake $(QMAKE_CONFIG) && cd .. - +release: QMAKE_CONFIG=-config release + +all: + $(MAKE) -C rpc + $(MAKE) -C common + $(MAKE) -C server + $(MAKE) -C client + +release: qmake all + + +clean: + $(MAKE) -C rpc $@ + $(MAKE) -C common $@ + $(MAKE) -C server $@ + $(MAKE) -C client $@ + +distclean: + $(MAKE) -C rpc $@ + $(MAKE) -C common $@ + $(MAKE) -C server $@ + $(MAKE) -C client $@ + +qmake: + cd rpc && qmake $(QMAKE_CONFIG) && cd .. + cd common && qmake $(QMAKE_CONFIG) && cd .. + cd server && qmake $(QMAKE_CONFIG) && cd .. + cd client && qmake $(QMAKE_CONFIG) && cd .. + diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 3c75c3f..61aa7b9 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -123,8 +123,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // TODO(MED): - //! \todo Implement then enable these protocols - ARP, IPv6, ICMP, IGMP - rbL3Arp->setHidden(true); + //! \todo Implement then enable these protocols - IPv6, ICMP, IGMP rbL3Ipv6->setHidden(true); rbL4Icmp->setHidden(true); rbL4Igmp->setHidden(true); @@ -179,7 +178,7 @@ void StreamConfigDialog::setupUiExtra() bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone); bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF); - bgProto[ProtoL3]->addButton(rbL3Arp, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Arp, OstProto::Protocol::kArpFieldNumber); bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther); #endif @@ -191,8 +190,8 @@ void StreamConfigDialog::setupUiExtra() bgProto[ProtoL4]->addButton(rbL4None, 0); bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); - bgProto[ProtoL4]->addButton(rbL4Icmp, 0xFFFF); - bgProto[ProtoL4]->addButton(rbL4Igmp, 0xFFFF); + bgProto[ProtoL4]->addButton(rbL4Icmp, OstProto::Protocol::kIcmpFieldNumber); + bgProto[ProtoL4]->addButton(rbL4Igmp, OstProto::Protocol::kIgmpFieldNumber); bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther); #endif diff --git a/common/arp.cpp b/common/arp.cpp new file mode 100644 index 0000000..5fb146b --- /dev/null +++ b/common/arp.cpp @@ -0,0 +1,925 @@ +#include +#include + +#include "arp.h" + +ArpConfigForm::ArpConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + opCodeCombo->setValidator(new QIntValidator(0, 0xFFFF, this)); + opCodeCombo->addItem(1, "ARP Request"); + opCodeCombo->addItem(2, "ARP Reply"); + + connect(senderHwAddrMode, SIGNAL(currentIndexChanged(int)), + SLOT(on_senderHwAddrMode_currentIndexChanged(int))); + connect(senderProtoAddrMode, SIGNAL(currentIndexChanged(int)), + SLOT(on_senderProtoAddrMode_currentIndexChanged(int))); + connect(targetHwAddrMode, SIGNAL(currentIndexChanged(int)), + SLOT(on_targetHwAddrMode_currentIndexChanged(int))); + connect(targetProtoAddrMode, SIGNAL(currentIndexChanged(int)), + SLOT(on_targetProtoAddrMode_currentIndexChanged(int))); +} + +void ArpConfigForm::on_senderHwAddrMode_currentIndexChanged(int index) +{ + if (index == OstProto::Arp::kFixed) + senderHwAddrCount->setDisabled(true); + else + senderHwAddrCount->setEnabled(true); +} + +void ArpConfigForm::on_targetHwAddrMode_currentIndexChanged(int index) +{ + if (index == OstProto::Arp::kFixed) + targetHwAddrCount->setDisabled(true); + else + targetHwAddrCount->setEnabled(true); +} + +void ArpConfigForm::on_senderProtoAddrMode_currentIndexChanged(int index) +{ + if (index == OstProto::Arp::kFixedHost) + { + senderProtoAddrCount->setDisabled(true); + senderProtoAddrMask->setDisabled(true); + } + else + { + senderProtoAddrCount->setEnabled(true); + senderProtoAddrMask->setEnabled(true); + } +} + +void ArpConfigForm::on_targetProtoAddrMode_currentIndexChanged(int index) +{ + if (index == OstProto::Arp::kFixedHost) + { + targetProtoAddrCount->setDisabled(true); + targetProtoAddrMask->setDisabled(true); + } + else + { + targetProtoAddrCount->setEnabled(true); + targetProtoAddrMask->setEnabled(true); + } +} + +ArpProtocol::ArpProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) +{ + configForm = NULL; +} + +ArpProtocol::~ArpProtocol() +{ + delete configForm; +} + +AbstractProtocol* ArpProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) +{ + return new ArpProtocol(stream, parent); +} + +quint32 ArpProtocol::protocolNumber() const +{ + return OstProto::Protocol::kArpFieldNumber; +} + +void ArpProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const +{ + protocol.MutableExtension(OstProto::arp)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void ArpProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::arp)) + data.MergeFrom(protocol.GetExtension(OstProto::arp)); +} + +QString ArpProtocol::name() const +{ + return QString("Address Resolution Protocol"); +} + +QString ArpProtocol::shortName() const +{ + return QString("ARP"); +} + +/*! + Return the ProtocolIdType for your protocol \n + + If your protocol doesn't have a protocolId field, you don't need to + reimplement this method - the base class implementation will do the + right thing +*/ +#if 0 +AbstractProtocol::ProtocolIdType ArpProtocol::protocolIdType() const +{ + return ProtocolIdIp; +} +#endif + +/*! + Return the protocolId for your protocol based on the 'type' requested \n + + If not all types are valid for your protocol, handle the valid type(s) + and for the remaining fallback to the base class implementation; if your + protocol doesn't have a protocolId at all, you don't need to reimplement + this method - the base class will do the right thing +*/ +quint32 ArpProtocol::protocolId(ProtocolIdType type) const +{ + switch(type) + { + case ProtocolIdEth: return 0x0806; + default:break; + } + + return AbstractProtocol::protocolId(type); +} + +int ArpProtocol::fieldCount() const +{ + return arp_fieldCount; +} + +AbstractProtocol::FieldFlags ArpProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case arp_hwType: + case arp_protoType: + + case arp_hwAddrLen: + case arp_protoAddrLen: + + case arp_opCode: + + case arp_senderHwAddr: + case arp_senderProtoAddr: + case arp_targetHwAddr: + case arp_targetProtoAddr: + break; + + case arp_senderHwAddrMode: + case arp_senderHwAddrCount: + + case arp_senderProtoAddrMode: + case arp_senderProtoAddrCount: + case arp_senderProtoAddrMask: + + case arp_targetHwAddrMode: + case arp_targetHwAddrCount: + + case arp_targetProtoAddrMode: + case arp_targetProtoAddrCount: + case arp_targetProtoAddrMask: + flags |= FieldIsMeta; + break; + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return flags; +} + +QVariant ArpProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case arp_hwType: + { + switch(attrib) + { + case FieldName: + return QString("Hardware Type"); + case FieldValue: + return data.hw_type(); + case FieldTextValue: + return QString("%1").arg(data.hw_type()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.hw_type(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + + case arp_protoType: + { + switch(attrib) + { + case FieldName: + return QString("Protocol Type"); + case FieldValue: + return data.proto_type(); + case FieldTextValue: + return QString("%1").arg(data.proto_type(), 4, BASE_HEX, + QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.proto_type(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + + case arp_hwAddrLen: + { + switch(attrib) + { + case FieldName: + return QString("Hardware Address Length"); + case FieldValue: + return data.hw_addr_len(); + case FieldTextValue: + return QString("%1").arg(data.hw_addr_len()); + case FieldFrameValue: + return QByteArray(1, (char) data.hw_addr_len()); + default: + break; + } + break; + } + + case arp_protoAddrLen: + { + switch(attrib) + { + case FieldName: + return QString("Protocol Address Length"); + case FieldValue: + return data.proto_addr_len(); + case FieldTextValue: + return QString("%1").arg(data.proto_addr_len()); + case FieldFrameValue: + return QByteArray(1, (char) data.proto_addr_len()); + default: + break; + } + break; + } + + case arp_opCode: + { + switch(attrib) + { + case FieldName: + return QString("Operation Code"); + case FieldValue: + return data.op_code(); + case FieldTextValue: + return QString("%1").arg(data.op_code()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.op_code(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + + case arp_senderHwAddr: + { + int u; + const int hwAddrStep = 1; + quint64 hwAddr = 0; + + switch (data.sender_hw_addr_mode()) + { + case OstProto::Arp::kFixed: + hwAddr = data.sender_hw_addr(); + break; + case OstProto::Arp::kIncrement: + u = (streamIndex % data.sender_hw_addr_count()) * + hwAddrStep; + hwAddr = data.sender_hw_addr() + u; + break; + case OstProto::Arp::kDecrement: + u = (streamIndex % data.sender_hw_addr_count()) * + hwAddrStep; + hwAddr = data.sender_hw_addr() - u; + break; + default: + qWarning("Unhandled hw_addr_mode %d", + data.sender_hw_addr_mode()); + } + + switch(attrib) + { + case FieldName: + return QString("Sender Hardware Address"); + case FieldValue: + return hwAddr; + case FieldTextValue: + return uintToHexStr(hwAddr, 6); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(8); + qToBigEndian((quint64) hwAddr, (uchar*) fv.data()); + fv.remove(0, 2); + return fv; + } + default: + break; + } + break; + } + + case arp_senderProtoAddr: + { + int u; + quint32 subnet, host, protoAddr = 0; + + switch(data.sender_proto_addr_mode()) + { + case OstProto::Arp::kFixedHost: + protoAddr = data.sender_proto_addr(); + break; + case OstProto::Arp::kIncrementHost: + u = streamIndex % data.sender_proto_addr_count(); + subnet = data.sender_proto_addr() + & data.sender_proto_addr_mask(); + host = (((data.sender_proto_addr() + & ~data.sender_proto_addr_mask()) + u) + & ~data.sender_proto_addr_mask()); + protoAddr = subnet | host; + break; + case OstProto::Arp::kDecrementHost: + u = streamIndex % data.sender_proto_addr_count(); + subnet = data.sender_proto_addr() + & data.sender_proto_addr_mask(); + host = (((data.sender_proto_addr() + & ~data.sender_proto_addr_mask()) - u) + & ~data.sender_proto_addr_mask()); + protoAddr = subnet | host; + break; + case OstProto::Arp::kRandomHost: + subnet = data.sender_proto_addr() + & data.sender_proto_addr_mask(); + host = (qrand() & ~data.sender_proto_addr_mask()); + protoAddr = subnet | host; + break; + default: + qWarning("Unhandled sender_proto_addr_mode = %d", + data.sender_proto_addr_mode()); + } + + switch(attrib) + { + case FieldName: + return QString("Sender Protocol Address"); + case FieldValue: + return protoAddr; + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) protoAddr, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QHostAddress(protoAddr).toString(); + default: + break; + } + break; + } + + case arp_targetHwAddr: + { + int u; + const int hwAddrStep = 1; + quint64 hwAddr = 0; + + switch (data.target_hw_addr_mode()) + { + case OstProto::Arp::kFixed: + hwAddr = data.target_hw_addr(); + break; + case OstProto::Arp::kIncrement: + u = (streamIndex % data.target_hw_addr_count()) * + hwAddrStep; + hwAddr = data.target_hw_addr() + u; + break; + case OstProto::Arp::kDecrement: + u = (streamIndex % data.target_hw_addr_count()) * + hwAddrStep; + hwAddr = data.target_hw_addr() - u; + break; + default: + qWarning("Unhandled hw_addr_mode %d", + data.target_hw_addr_mode()); + } + + switch(attrib) + { + case FieldName: + return QString("Target Hardware Address"); + case FieldValue: + return hwAddr; + case FieldTextValue: + return uintToHexStr(hwAddr, 6); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(8); + qToBigEndian((quint64) hwAddr, (uchar*) fv.data()); + fv.remove(0, 2); + return fv; + } + default: + break; + } + break; + } + + case arp_targetProtoAddr: + { + int u; + quint32 subnet, host, protoAddr = 0; + + switch(data.target_proto_addr_mode()) + { + case OstProto::Arp::kFixed: + protoAddr = data.target_proto_addr(); + break; + case OstProto::Arp::kIncrementHost: + u = streamIndex % data.target_proto_addr_count(); + subnet = data.target_proto_addr() + & data.target_proto_addr_mask(); + host = (((data.target_proto_addr() + & ~data.target_proto_addr_mask()) + u) + & ~data.target_proto_addr_mask()); + protoAddr = subnet | host; + break; + case OstProto::Arp::kDecrementHost: + u = streamIndex % data.target_proto_addr_count(); + subnet = data.target_proto_addr() + & data.target_proto_addr_mask(); + host = (((data.target_proto_addr() + & ~data.target_proto_addr_mask()) - u) + & ~data.target_proto_addr_mask()); + protoAddr = subnet | host; + break; + case OstProto::Arp::kRandomHost: + subnet = data.target_proto_addr() + & data.target_proto_addr_mask(); + host = (qrand() & ~data.target_proto_addr_mask()); + protoAddr = subnet | host; + break; + default: + qWarning("Unhandled target_proto_addr_mode = %d", + data.target_proto_addr_mode()); + } + + switch(attrib) + { + case FieldName: + return QString("Target Protocol Address"); + case FieldValue: + return protoAddr; + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) protoAddr, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QHostAddress(protoAddr).toString(); + default: + break; + } + break; + } + + // Meta fields + case arp_senderHwAddrMode: + switch(attrib) + { + case FieldName: + return QString("Sender Hardware Address Mode"); + case FieldValue: + return data.sender_hw_addr_mode(); + default: + break; + } + break; + case arp_senderHwAddrCount: + switch(attrib) + { + case FieldName: + return QString("Sender Hardware Address Count"); + case FieldValue: + return data.sender_hw_addr_count(); + default: + break; + } + break; + case arp_senderProtoAddrMode: + switch(attrib) + { + case FieldName: + return QString("Sender Protocol Address Mode"); + case FieldValue: + return data.sender_proto_addr_mode(); + default: + break; + } + break; + case arp_senderProtoAddrCount: + switch(attrib) + { + case FieldName: + return QString("Sender Protocol Address Count"); + case FieldValue: + return data.sender_proto_addr_count(); + default: + break; + } + break; + case arp_senderProtoAddrMask: + switch(attrib) + { + case FieldName: + return QString("Sender Protocol Address Mask"); + case FieldValue: + return data.sender_proto_addr_mask(); + default: + break; + } + break; + + case arp_targetHwAddrMode: + switch(attrib) + { + case FieldName: + return QString("Target Hardware Address Mode"); + case FieldValue: + return data.target_hw_addr_mode(); + default: + break; + } + break; + case arp_targetHwAddrCount: + switch(attrib) + { + case FieldName: + return QString("Target Hardware Address Count"); + case FieldValue: + return data.target_hw_addr_count(); + default: + break; + } + break; + case arp_targetProtoAddrMode: + switch(attrib) + { + case FieldName: + return QString("Target Protocol Address Mode"); + case FieldValue: + return data.target_proto_addr_mode(); + default: + break; + } + break; + case arp_targetProtoAddrCount: + switch(attrib) + { + case FieldName: + return QString("Target Protocol Address Count"); + case FieldValue: + return data.target_proto_addr_count(); + default: + break; + } + break; + case arp_targetProtoAddrMask: + switch(attrib) + { + case FieldName: + return QString("Target Protocol Address Mask"); + case FieldValue: + return data.target_proto_addr_mask(); + default: + break; + } + break; + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool ArpProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + bool isOk = false; + + if (attrib != FieldValue) + goto _exit; + + switch (index) + { + case arp_hwType: + { + uint hwType = value.toUInt(&isOk); + if (isOk) + data.set_hw_type(hwType); + break; + } + case arp_protoType: + { + uint protoType = value.toUInt(&isOk); + if (isOk) + data.set_proto_type(protoType); + break; + } + case arp_hwAddrLen: + { + uint hwAddrLen = value.toUInt(&isOk); + if (isOk) + data.set_hw_addr_len(hwAddrLen); + break; + } + case arp_protoAddrLen: + { + uint protoAddrLen = value.toUInt(&isOk); + if (isOk) + data.set_proto_addr_len(protoAddrLen); + break; + } + case arp_opCode: + { + uint opCode = value.toUInt(&isOk); + if (isOk) + data.set_op_code(opCode); + break; + } + + case arp_senderHwAddr: + { + quint64 hwAddr = value.toULongLong(&isOk); + if (isOk) + data.set_sender_hw_addr(hwAddr); + break; + } + case arp_senderHwAddrMode: + { + uint mode = value.toUInt(&isOk); + if (isOk && data.HwAddrMode_IsValid(mode)) + data.set_sender_hw_addr_mode((OstProto::Arp::HwAddrMode) mode); + break; + } + case arp_senderHwAddrCount: + { + uint count = value.toUInt(&isOk); + if (isOk) + data.set_sender_hw_addr_count(count); + break; + } + + case arp_senderProtoAddr: + { + uint protoAddr = value.toUInt(&isOk); + if (isOk) + data.set_sender_proto_addr(protoAddr); + break; + } + case arp_senderProtoAddrMode: + { + uint mode = value.toUInt(&isOk); + if (isOk && data.ProtoAddrMode_IsValid(mode)) + data.set_sender_proto_addr_mode( + (OstProto::Arp::ProtoAddrMode)mode); + break; + } + case arp_senderProtoAddrCount: + { + uint count = value.toUInt(&isOk); + if (isOk) + data.set_sender_proto_addr_count(count); + break; + } + case arp_senderProtoAddrMask: + { + uint mask = value.toUInt(&isOk); + if (isOk) + data.set_sender_proto_addr_mask(mask); + break; + } + + case arp_targetHwAddr: + { + quint64 hwAddr = value.toULongLong(&isOk); + if (isOk) + data.set_target_hw_addr(hwAddr); + break; + } + case arp_targetHwAddrMode: + { + uint mode = value.toUInt(&isOk); + if (isOk && data.HwAddrMode_IsValid(mode)) + data.set_target_hw_addr_mode((OstProto::Arp::HwAddrMode)mode); + break; + } + case arp_targetHwAddrCount: + { + uint count = value.toUInt(&isOk); + if (isOk) + data.set_target_hw_addr_count(count); + break; + } + + case arp_targetProtoAddr: + { + uint protoAddr = value.toUInt(&isOk); + if (isOk) + data.set_target_proto_addr(protoAddr); + break; + } + case arp_targetProtoAddrMode: + { + uint mode = value.toUInt(&isOk); + if (isOk && data.ProtoAddrMode_IsValid(mode)) + data.set_target_proto_addr_mode( + (OstProto::Arp::ProtoAddrMode)mode); + break; + } + case arp_targetProtoAddrCount: + { + uint count = value.toUInt(&isOk); + if (isOk) + data.set_target_proto_addr_count(count); + break; + } + case arp_targetProtoAddrMask: + { + uint mask = value.toUInt(&isOk); + if (isOk) + data.set_target_proto_addr_mask(mask); + break; + } + + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + +_exit: + return isOk; +} + +/*! + If your protocol has any variable fields, return true \n + + Otherwise you don't need to reimplement this method - the base class always + returns false +*/ +bool ArpProtocol::isProtocolFrameValueVariable() const +{ + return true; +} + +QWidget* ArpProtocol::configWidget() +{ + if (configForm == NULL) + { + configForm = new ArpConfigForm; + loadConfigWidget(); + } + + return configForm; +} + +void ArpProtocol::loadConfigWidget() +{ + configWidget(); + + configForm->hwType->setText( + fieldData(arp_hwType, FieldValue).toString()); + configForm->protoType->setText(uintToHexStr( + fieldData(arp_protoType, FieldValue).toUInt(), 2)); + configForm->hwAddrLen->setText( + fieldData(arp_hwAddrLen, FieldValue).toString()); + configForm->protoAddrLen->setText( + fieldData(arp_protoAddrLen, FieldValue).toString()); + + configForm->opCodeCombo->setValue( + fieldData(arp_opCode, FieldValue).toUInt()); + + configForm->senderHwAddr->setText(uintToHexStr( + fieldData(arp_senderHwAddr, FieldValue).toULongLong(), 6)); + configForm->senderHwAddrMode->setCurrentIndex( + fieldData(arp_senderHwAddrMode, FieldValue).toUInt()); + configForm->senderHwAddrCount->setText( + fieldData(arp_senderHwAddrCount, FieldValue).toString()); + + configForm->senderProtoAddr->setText(QHostAddress( + fieldData(arp_senderProtoAddr, FieldValue).toUInt()).toString()); + configForm->senderProtoAddrMode->setCurrentIndex( + fieldData(arp_senderProtoAddrMode, FieldValue).toUInt()); + configForm->senderProtoAddrCount->setText( + fieldData(arp_senderProtoAddrCount, FieldValue).toString()); + configForm->senderProtoAddrMask->setText(QHostAddress( + fieldData(arp_senderProtoAddrMask, FieldValue).toUInt()).toString()); + + configForm->targetHwAddr->setText(uintToHexStr( + fieldData(arp_targetHwAddr, FieldValue).toULongLong(), 6)); + configForm->targetHwAddrMode->setCurrentIndex( + fieldData(arp_targetHwAddrMode, FieldValue).toUInt()); + configForm->targetHwAddrCount->setText( + fieldData(arp_targetHwAddrCount, FieldValue).toString()); + + configForm->targetProtoAddr->setText(QHostAddress( + fieldData(arp_targetProtoAddr, FieldValue).toUInt()).toString()); + configForm->targetProtoAddrMode->setCurrentIndex( + fieldData(arp_targetProtoAddrMode, FieldValue).toUInt()); + configForm->targetProtoAddrCount->setText( + fieldData(arp_targetProtoAddrCount, FieldValue).toString()); + configForm->targetProtoAddrMask->setText(QHostAddress( + fieldData(arp_targetProtoAddrMask, FieldValue).toUInt()).toString()); + +} + +void ArpProtocol::storeConfigWidget() +{ + bool isOk; + + configWidget(); + + setFieldData(arp_hwType, configForm->hwType->text()); + setFieldData(arp_protoType, configForm->protoType->text().toUInt( + &isOk, BASE_HEX)); + setFieldData(arp_hwAddrLen, configForm->hwAddrLen->text()); + setFieldData(arp_protoAddrLen, configForm->protoAddrLen->text()); + + setFieldData(arp_opCode, configForm->opCodeCombo->currentValue()); + + setFieldData(arp_senderHwAddr, configForm->senderHwAddr->text() + .remove(QChar(' ')).toULongLong(&isOk, BASE_HEX)); + setFieldData(arp_senderHwAddrMode, + configForm->senderHwAddrMode->currentIndex()); + setFieldData(arp_senderHwAddrCount, configForm->senderHwAddrCount->text()); + + setFieldData(arp_senderProtoAddr, QHostAddress( + configForm->senderProtoAddr->text()).toIPv4Address()); + setFieldData(arp_senderProtoAddrMode, + configForm->senderProtoAddrMode->currentIndex()); + setFieldData(arp_senderProtoAddrCount, + configForm->senderProtoAddrCount->text()); + setFieldData(arp_senderProtoAddrMask, QHostAddress( + configForm->senderProtoAddrMask->text()).toIPv4Address()); + + setFieldData(arp_targetHwAddr, configForm->targetHwAddr->text() + .remove(QChar(' ')).toULongLong(&isOk, BASE_HEX)); + setFieldData(arp_targetHwAddrMode, + configForm->targetHwAddrMode->currentIndex()); + setFieldData(arp_targetHwAddrCount, configForm->targetHwAddrCount->text()); + + setFieldData(arp_targetProtoAddr, QHostAddress( + configForm->targetProtoAddr->text()).toIPv4Address()); + setFieldData(arp_targetProtoAddrMode, + configForm->targetProtoAddrMode->currentIndex()); + setFieldData(arp_targetProtoAddrCount, + configForm->targetProtoAddrCount->text()); + setFieldData(arp_targetProtoAddrMask, QHostAddress( + configForm->targetProtoAddrMask->text()).toIPv4Address()); +} + diff --git a/common/arp.h b/common/arp.h new file mode 100644 index 0000000..6f6c256 --- /dev/null +++ b/common/arp.h @@ -0,0 +1,101 @@ +#ifndef _ARP_H +#define _ARP_H + +#include "arp.pb.h" +#include "ui_arp.h" + +#include "abstractprotocol.h" + +/* +Arp Protocol Frame Format - + +------+------+------+------+------+---------+-------+---------+-------+ + | HTYP | PTYP | HLEN | PLEN | OPER | SHA | SPA | THA | TPA | + | (2) | (2) | (1) | (1) | (2) | (6) | (4) | (6) | (4) | + +------+------+------+------+------+---------+-------+---------+-------+ +Figures in brackets represent field width in bytes +*/ + +class ArpConfigForm : public QWidget, public Ui::Arp +{ + Q_OBJECT +public: + ArpConfigForm(QWidget *parent = 0); +private slots: + void on_senderHwAddrMode_currentIndexChanged(int index); + void on_senderProtoAddrMode_currentIndexChanged(int index); + void on_targetHwAddrMode_currentIndexChanged(int index); + void on_targetProtoAddrMode_currentIndexChanged(int index); +}; + +class ArpProtocol : public AbstractProtocol +{ +private: + OstProto::Arp data; + ArpConfigForm *configForm; + enum arpfield + { + // Frame Fields + arp_hwType, + arp_protoType, + + arp_hwAddrLen, + arp_protoAddrLen, + + arp_opCode, + + arp_senderHwAddr, + arp_senderProtoAddr, + arp_targetHwAddr, + arp_targetProtoAddr, + + // Meta Fields + arp_senderHwAddrMode, + arp_senderHwAddrCount, + + arp_senderProtoAddrMode, + arp_senderProtoAddrCount, + arp_senderProtoAddrMask, + + arp_targetHwAddrMode, + arp_targetHwAddrCount, + + arp_targetProtoAddrMode, + arp_targetProtoAddrCount, + arp_targetProtoAddrMask, + + + arp_fieldCount + }; + +public: + ArpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~ArpProtocol(); + + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + + virtual quint32 protocolId(ProtocolIdType type) const; + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual bool isProtocolFrameValueVariable() const; + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/arp.proto b/common/arp.proto new file mode 100644 index 0000000..9491a6c --- /dev/null +++ b/common/arp.proto @@ -0,0 +1,48 @@ +import "protocol.proto"; + +package OstProto; + +// ARP Protocol +message Arp { + + enum HwAddrMode { + kFixed = 0; + kIncrement = 1; + kDecrement = 2; + } + + enum ProtoAddrMode { + kFixedHost = 0; + kIncrementHost = 1; + kDecrementHost = 2; + kRandomHost = 3; + } + + optional uint32 hw_type = 1 [default = 1]; + optional uint32 proto_type = 2 [default = 0x800]; + optional uint32 hw_addr_len = 3 [default = 6]; + optional uint32 proto_addr_len = 4 [default = 4]; + optional uint32 op_code = 5 [default = 1]; // 1 => ARP Request + + optional uint64 sender_hw_addr = 6; + optional HwAddrMode sender_hw_addr_mode = 7 [default = kFixed]; + optional uint32 sender_hw_addr_count = 8 [default = 16]; + + optional uint32 sender_proto_addr = 9; + optional ProtoAddrMode sender_proto_addr_mode = 10 [default = kFixedHost]; + optional uint32 sender_proto_addr_count = 11 [default = 16]; + optional fixed32 sender_proto_addr_mask = 12 [default = 0xFFFFFF00]; + + optional uint64 target_hw_addr = 13; + optional HwAddrMode target_hw_addr_mode = 14 [default = kFixed]; + optional uint32 target_hw_addr_count = 15 [default = 16]; + + optional uint32 target_proto_addr = 16; + optional ProtoAddrMode target_proto_addr_mode = 17 [default = kFixedHost]; + optional uint32 target_proto_addr_count = 18 [default = 16]; + optional fixed32 target_proto_addr_mask = 19 [default = 0xFFFFFF00]; +} + +extend Protocol { + optional Arp arp = 131; +} diff --git a/common/arp.ui b/common/arp.ui new file mode 100644 index 0000000..6f4c847 --- /dev/null +++ b/common/arp.ui @@ -0,0 +1,518 @@ + + Arp + + + + 0 + 0 + 528 + 286 + + + + Form + + + + + + + + + + + + Hardware Type + + + hwType + + + + + + + false + + + + + + + Hardware Address Length + + + hwAddrLen + + + + + + + false + + + + + + + Protocol Type + + + protoType + + + + + + + false + + + + + + + Protocol Address Length + + + protoAddrLen + + + + + + + false + + + + + + + + + + + + + + + + Operation Code + + + + + + + + 1 + 0 + + + + true + + + QComboBox::NoInsert + + + + + + + Qt::Horizontal + + + + 161 + 20 + + + + + + + + + + + + + + false + + + + + + Qt::Horizontal + + + + 101 + 20 + + + + + + + + Address + + + + + + + Mode + + + + + + + Count + + + + + + + Mask + + + + + + + Sender Hardware + + + senderHwAddr + + + + + + + >HH HH HH HH HH HH; + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + + + + false + + + + 255 + 0 + + + + + + + + + + + Sender Protocol + + + senderProtoAddr + + + + + + + 009.009.009.009; + + + ... + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment Host + + + + + Decrement Host + + + + + Random Host + + + + + + + + false + + + + 255 + 0 + + + + + + + + + + + false + + + 009.009.009.009; + + + ... + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Target Hardware + + + targetHwAddr + + + + + + + + 120 + 0 + + + + >HH HH HH HH HH HH; + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment + + + + + Decrement + + + + + + + + false + + + + 255 + 0 + + + + + + + 0 + + + + + + + Target Protocol + + + targetProtoAddr + + + + + + + 000.000.000.000; + + + ... + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment Host + + + + + Decrement Host + + + + + Random Host + + + + + + + + false + + + + 255 + 0 + + + + + + + + + + + false + + + 009.009.009.009; + + + ... + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Qt::Vertical + + + + 20 + 61 + + + + + + + + + IntComboBox + QComboBox +
intcombobox.h
+
+
+ + hwType + protoType + hwAddrLen + protoAddrLen + senderHwAddr + senderHwAddrMode + senderHwAddrCount + senderProtoAddr + senderProtoAddrMode + senderProtoAddrCount + senderProtoAddrMask + targetHwAddr + targetHwAddrMode + targetHwAddrCount + targetProtoAddr + targetProtoAddrMode + targetProtoAddrCount + targetProtoAddrMask + + + +
diff --git a/common/intcombobox.h b/common/intcombobox.h new file mode 100644 index 0000000..44d33c2 --- /dev/null +++ b/common/intcombobox.h @@ -0,0 +1,31 @@ +#include + +class IntComboBox : public QComboBox +{ +public: + IntComboBox(QWidget *parent = 0) + : QComboBox(parent) + { + } + void addItem(int value, const QString &text) + { + QComboBox::addItem(QString("%1 - %2").arg(value).arg(text), value); + } + int currentValue() + { + bool isOk; + int index = findText(currentText()); + if (index >= 0) + return itemData(index).toInt(); + else + return currentText().toInt(&isOk, 0); + } + void setValue(int value) + { + int index = findData(value); + if (index >= 0) + setCurrentIndex(index); + else + setEditText(QString().setNum(value)); + } +}; diff --git a/common/ostproto.pro b/common/ostproto.pro index b3c37bb..703c4aa 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -11,6 +11,7 @@ FORMS += \ llc.ui \ snap.ui \ vlan.ui \ + arp.ui \ ip4.ui \ tcp.ui \ udp.ui \ @@ -29,6 +30,7 @@ PROTOS += \ vlan.proto \ svlan.proto \ vlanstack.proto \ + arp.proto \ ip4.proto \ tcp.proto \ udp.proto \ @@ -52,6 +54,7 @@ HEADERS += \ vlan.h \ svlan.h \ vlanstack.h \ + arp.h \ ip4.h \ tcp.h \ udp.h \ @@ -71,6 +74,7 @@ SOURCES += \ snap.cpp \ vlan.cpp \ svlan.cpp \ + arp.cpp \ ip4.cpp \ tcp.cpp \ udp.cpp \ diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index faaef8f..0322344 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -12,6 +12,7 @@ #include "dot2snap.h" #include "vlan.h" #include "vlanstack.h" +#include "arp.h" #include "ip4.h" #include "tcp.h" #include "udp.h" @@ -28,36 +29,38 @@ ProtocolManager::ProtocolManager() registerProtocol(OstProto::Protocol::kMacFieldNumber, (void*) MacProtocol::createInstance); registerProtocol(OstProto::Protocol::kPayloadFieldNumber, - (void*) PayloadProtocol::createInstance); + (void*) PayloadProtocol::createInstance); registerProtocol(OstProto::Protocol::kEth2FieldNumber, - (void*) Eth2Protocol::createInstance); + (void*) Eth2Protocol::createInstance); registerProtocol(OstProto::Protocol::kDot3FieldNumber, - (void*) Dot3Protocol::createInstance); + (void*) Dot3Protocol::createInstance); registerProtocol(OstProto::Protocol::kLlcFieldNumber, - (void*) LlcProtocol::createInstance); + (void*) LlcProtocol::createInstance); registerProtocol(OstProto::Protocol::kSnapFieldNumber, - (void*) SnapProtocol::createInstance); + (void*) SnapProtocol::createInstance); registerProtocol(OstProto::Protocol::kDot2LlcFieldNumber, (void*) Dot2LlcProtocol::createInstance); registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber, (void*) Dot2SnapProtocol::createInstance); registerProtocol(OstProto::Protocol::kSvlanFieldNumber, - (void*) SVlanProtocol::createInstance); + (void*) SVlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanFieldNumber, - (void*) VlanProtocol::createInstance); + (void*) VlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanStackFieldNumber, (void*) VlanStackProtocol::createInstance); + registerProtocol(OstProto::Protocol::kArpFieldNumber, + (void*) ArpProtocol::createInstance); registerProtocol(OstProto::Protocol::kIp4FieldNumber, - (void*) Ip4Protocol::createInstance); + (void*) Ip4Protocol::createInstance); registerProtocol(OstProto::Protocol::kTcpFieldNumber, - (void*) TcpProtocol::createInstance); + (void*) TcpProtocol::createInstance); registerProtocol(OstProto::Protocol::kUdpFieldNumber, - (void*) UdpProtocol::createInstance); + (void*) UdpProtocol::createInstance); registerProtocol(OstProto::Protocol::kUserScriptFieldNumber, - (void*) UserScriptProtocol::createInstance); + (void*) UserScriptProtocol::createInstance); registerProtocol(OstProto::Protocol::kSampleFieldNumber, - (void*) SampleProtocol::createInstance); + (void*) SampleProtocol::createInstance); populateNeighbourProtocols(); } diff --git a/common/sample.cpp b/common/sample.cpp index 0b7da64..f44b979 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -84,7 +84,7 @@ quint32 SampleProtocol::protocolId(ProtocolIdType type) const return AbstractProtocol::protocolId(type); } -int SampleProtocol::fieldCount() const +int SampleProtocol::fieldCount() const { return sample_fieldCount; } diff --git a/common/sample.h b/common/sample.h index 55f549e..443d8c3 100644 --- a/common/sample.h +++ b/common/sample.h @@ -1,11 +1,11 @@ #ifndef _SAMPLE_H #define _SAMPLE_H -#include "abstractprotocol.h" - #include "sample.pb.h" #include "ui_sample.h" +#include "abstractprotocol.h" + /* Sample Protocol Frame Format - +-----+------+------+------+------+------+ @@ -61,7 +61,7 @@ public: virtual QString name() const; virtual QString shortName() const; - virtual int fieldCount() const; + virtual int fieldCount() const; virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, From 4dc3d2d7f90d3d10c8593524866be4df74739a4f Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 17 Mar 2010 15:47:56 +0000 Subject: [PATCH 50/98] - Added TODO instruction comments to the sample protocol - Implemented ICMP protocol builder - Added #ifdefs to intcombobox.h to prevent multiple inclusion --- client/streamconfigdialog.cpp | 3 +- common/icmp.cpp | 400 ++++++++++++++++++++++++++++++++++ common/icmp.h | 75 +++++++ common/icmp.proto | 19 ++ common/icmp.ui | 144 ++++++++++++ common/intcombobox.h | 5 + common/ostproto.pro | 4 + common/protocolmanager.cpp | 3 + common/sample.cpp | 48 +++- 9 files changed, 689 insertions(+), 12 deletions(-) create mode 100644 common/icmp.cpp create mode 100644 common/icmp.h create mode 100644 common/icmp.proto create mode 100644 common/icmp.ui diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 61aa7b9..41c9732 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -123,9 +123,8 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // TODO(MED): - //! \todo Implement then enable these protocols - IPv6, ICMP, IGMP + //! \todo Implement then enable these protocols - IPv6, IGMP rbL3Ipv6->setHidden(true); - rbL4Icmp->setHidden(true); rbL4Igmp->setHidden(true); //! \todo Enable navigation of streams pbPrev->setDisabled(true); diff --git a/common/icmp.cpp b/common/icmp.cpp new file mode 100644 index 0000000..32d0fb5 --- /dev/null +++ b/common/icmp.cpp @@ -0,0 +1,400 @@ +#include + +#include "icmp.h" + +IcmpConfigForm::IcmpConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + typeCombo->setValidator(new QIntValidator(0, 0xFF, this)); + typeCombo->addItem(0, "Echo Reply"); + typeCombo->addItem(3, "Destination Unreachable"); + typeCombo->addItem(4, "Source Quench"); + typeCombo->addItem(5, "Redirect"); + typeCombo->addItem(8, "Echo Request"); + typeCombo->addItem(11, "Time Exceeded"); + typeCombo->addItem(12, "Parameter Problem"); + typeCombo->addItem(13, "Timestamp Request"); + typeCombo->addItem(14, "Timestamp Reply"); + typeCombo->addItem(17, "Address Mask Request"); + typeCombo->addItem(18, "Address Mask Reply"); + + idEdit->setValidator(new QIntValidator(0, 0xFFFF, this)); + seqEdit->setValidator(new QIntValidator(0, 0xFFFF, this)); +} + +IcmpProtocol::IcmpProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) +{ + configForm = NULL; +} + +IcmpProtocol::~IcmpProtocol() +{ + delete configForm; +} + +AbstractProtocol* IcmpProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) +{ + return new IcmpProtocol(stream, parent); +} + +quint32 IcmpProtocol::protocolNumber() const +{ + return OstProto::Protocol::kIcmpFieldNumber; +} + +void IcmpProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const +{ + protocol.MutableExtension(OstProto::icmp)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void IcmpProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::icmp)) + data.MergeFrom(protocol.GetExtension(OstProto::icmp)); +} + +QString IcmpProtocol::name() const +{ + return QString("Internet Control Message Protocol"); +} + +QString IcmpProtocol::shortName() const +{ + return QString("ICMP"); +} + +quint32 IcmpProtocol::protocolId(ProtocolIdType type) const +{ + switch(type) + { + case ProtocolIdIp: return 0x1; + default:break; + } + + return AbstractProtocol::protocolId(type); +} + +int IcmpProtocol::fieldCount() const +{ + return icmp_fieldCount; +} + +AbstractProtocol::FieldFlags IcmpProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case icmp_type: + case icmp_code: + break; + + case icmp_checksum: + flags |= FieldIsCksum; + break; + + case icmp_identifier: + case icmp_sequence: + break; + + case icmp_is_override_checksum: + flags |= FieldIsMeta; + break; + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return flags; +} + +QVariant IcmpProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case icmp_type: + { + unsigned char type = data.type() & 0xFF; + + switch(attrib) + { + case FieldName: + return QString("Type"); + case FieldValue: + return type; + case FieldTextValue: + return QString("%1").arg((uint) type); + case FieldFrameValue: + return QByteArray(1, type); + default: + break; + } + break; + + } + case icmp_code: + { + unsigned char code = data.code() & 0xFF; + + switch(attrib) + { + case FieldName: + return QString("code"); + case FieldValue: + return code; + case FieldTextValue: + return QString("%1").arg((uint)code); + case FieldFrameValue: + return QByteArray(1, code); + default: + break; + } + break; + + } + case icmp_checksum: + { + quint16 cksum; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + if (data.is_override_checksum()) + { + cksum = data.checksum(); + } + else + { + quint16 cks; + quint32 sum = 0; + + cks = protocolFrameCksum(streamIndex, CksumIp); + sum += (quint16) ~cks; + cks = protocolFramePayloadCksum(streamIndex, CksumIp); + sum += (quint16) ~cks; + + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); + + cksum = (~sum) & 0xFFFF; + } + break; + default: + cksum = 0; // avoid the 'maybe used unitialized' warning + break; + } + printf("%s: attrib = %d, cksum = %d\n", __FUNCTION__, attrib, cksum); + + switch(attrib) + { + case FieldName: + return QString("Checksum"); + case FieldValue: + return cksum; + case FieldFrameValue: + { + QByteArray fv; + + fv.resize(2); + qToBigEndian(cksum, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("0x%1").arg( + cksum, 4, BASE_HEX, QChar('0'));; + case FieldBitSize: + return 16; + default: + break; + } + break; + } + case icmp_identifier: + { + switch(attrib) + { + case FieldName: + return QString("Identifier"); + case FieldValue: + return data.identifier(); + case FieldTextValue: + return QString("%1").arg(data.identifier()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.identifier(), + (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + case icmp_sequence: + { + switch(attrib) + { + case FieldName: + return QString("Sequence"); + case FieldValue: + return data.sequence(); + case FieldTextValue: + return QString("%1").arg(data.sequence()); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) data.sequence(), (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + + + // Meta fields + case icmp_is_override_checksum: + { + switch(attrib) + { + case FieldValue: + return data.is_override_checksum(); + default: + break; + } + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool IcmpProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + bool isOk = false; + + if (attrib != FieldValue) + goto _exit; + + switch (index) + { + case icmp_type: + { + uint type = value.toUInt(&isOk); + if (isOk) + data.set_type(type & 0xFF); + break; + } + case icmp_code: + { + uint code = value.toUInt(&isOk); + if (isOk) + data.set_code(code & 0xFF); + break; + } + case icmp_checksum: + { + uint csum = value.toUInt(&isOk); + if (isOk) + data.set_checksum(csum); + break; + } + case icmp_identifier: + { + uint id = value.toUInt(&isOk); + if (isOk) + data.set_identifier(id); + break; + } + case icmp_sequence: + { + uint seq = value.toUInt(&isOk); + if (isOk) + data.set_sequence(seq); + break; + } + case icmp_is_override_checksum: + { + bool ovr = value.toBool(); + data.set_is_override_checksum(ovr); + isOk = true; + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + +_exit: + return isOk; +} + +QWidget* IcmpProtocol::configWidget() +{ + if (configForm == NULL) + { + configForm = new IcmpConfigForm; + loadConfigWidget(); + } + + return configForm; +} + +void IcmpProtocol::loadConfigWidget() +{ + configWidget(); + + configForm->typeCombo->setValue(fieldData(icmp_type, FieldValue).toUInt()); + configForm->codeEdit->setText(fieldData(icmp_code, FieldValue).toString()); + + configForm->overrideCksum->setChecked( + fieldData(icmp_is_override_checksum, FieldValue).toBool()); + configForm->cksumEdit->setText(uintToHexStr( + fieldData(icmp_checksum, FieldValue).toUInt(), 2)); + + configForm->idEdit->setText( + fieldData(icmp_identifier, FieldValue).toString()); + configForm->seqEdit->setText( + fieldData(icmp_sequence, FieldValue).toString()); + +} + +void IcmpProtocol::storeConfigWidget() +{ + bool isOk; + + configWidget(); + setFieldData(icmp_type, configForm->typeCombo->currentValue()); + setFieldData(icmp_code, configForm->codeEdit->text()); + + setFieldData(icmp_is_override_checksum, + configForm->overrideCksum->isChecked()); + setFieldData(icmp_checksum, configForm->cksumEdit->text().toUInt(&isOk, BASE_HEX)); + + setFieldData(icmp_identifier, configForm->idEdit->text()); + setFieldData(icmp_sequence, configForm->seqEdit->text()); +} + diff --git a/common/icmp.h b/common/icmp.h new file mode 100644 index 0000000..3a9fba6 --- /dev/null +++ b/common/icmp.h @@ -0,0 +1,75 @@ +#ifndef _ICMP_H +#define _ICMP_H + +#include "icmp.pb.h" +#include "ui_icmp.h" + +#include "abstractprotocol.h" + +/* +Icmp Protocol Frame Format - + +-----+------+------+-----+-----+ + | TYP | CODE | CSUM | ID | SEQ | + | (1) | (1) | (2) | (2) | (2) | + +-----+------+------+-----+-----+ +Figures in brackets represent field width in bytes +*/ + +class IcmpConfigForm : public QWidget, public Ui::Icmp +{ + Q_OBJECT +public: + IcmpConfigForm(QWidget *parent = 0); +private slots: +}; + +class IcmpProtocol : public AbstractProtocol +{ +private: + OstProto::Icmp data; + IcmpConfigForm *configForm; + enum icmpfield + { + // Frame Fields + icmp_type = 0, + icmp_code, + icmp_checksum, + icmp_identifier, + icmp_sequence, + + // Meta Fields + icmp_is_override_checksum, + + icmp_fieldCount + }; + +public: + IcmpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~IcmpProtocol(); + + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + + virtual quint32 protocolId(ProtocolIdType type) const; + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/icmp.proto b/common/icmp.proto new file mode 100644 index 0000000..72dcd38 --- /dev/null +++ b/common/icmp.proto @@ -0,0 +1,19 @@ +import "protocol.proto"; + +package OstProto; + +// Icmp Protocol +message Icmp { + + optional bool is_override_checksum = 1; + + optional uint32 type = 2 [default = 0x8]; // echo request + optional uint32 code = 3; + optional uint32 checksum = 4; + optional uint32 identifier = 5 [default = 1234]; + optional uint32 sequence = 6; +} + +extend Protocol { + optional Icmp icmp = 142; +} diff --git a/common/icmp.ui b/common/icmp.ui new file mode 100644 index 0000000..bf54421 --- /dev/null +++ b/common/icmp.ui @@ -0,0 +1,144 @@ + + Icmp + + + + 0 + 0 + 258 + 168 + + + + Form + + + + + + Type + + + typeCombo + + + + + + + + + + Code + + + codeEdit + + + + + + + + + + Checksum + + + + + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Identifier + + + idEdit + + + + + + + + + + Sequence + + + seqEdit + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + IntComboBox + QComboBox +
intcombobox.h
+
+
+ + typeCombo + codeEdit + overrideCksum + cksumEdit + idEdit + seqEdit + + + + + overrideCksum + toggled(bool) + cksumEdit + setEnabled(bool) + + + 33 + 70 + + + 96 + 71 + + + + +
diff --git a/common/intcombobox.h b/common/intcombobox.h index 44d33c2..ca62511 100644 --- a/common/intcombobox.h +++ b/common/intcombobox.h @@ -1,3 +1,6 @@ +#ifndef __INT_COMBO_BOX +#define __INT_COMBO_BOX + #include class IntComboBox : public QComboBox @@ -29,3 +32,5 @@ public: setEditText(QString().setNum(value)); } }; + +#endif diff --git a/common/ostproto.pro b/common/ostproto.pro index 703c4aa..e2b9cb3 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -13,6 +13,7 @@ FORMS += \ vlan.ui \ arp.ui \ ip4.ui \ + icmp.ui \ tcp.ui \ udp.ui \ userscript.ui \ @@ -32,6 +33,7 @@ PROTOS += \ vlanstack.proto \ arp.proto \ ip4.proto \ + icmp.proto \ tcp.proto \ udp.proto \ userscript.proto \ @@ -56,6 +58,7 @@ HEADERS += \ vlanstack.h \ arp.h \ ip4.h \ + icmp.h \ tcp.h \ udp.h \ userscript.h \ @@ -76,6 +79,7 @@ SOURCES += \ svlan.cpp \ arp.cpp \ ip4.cpp \ + icmp.cpp \ tcp.cpp \ udp.cpp \ userscript.cpp \ diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 0322344..f65c9b2 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -14,6 +14,7 @@ #include "vlanstack.h" #include "arp.h" #include "ip4.h" +#include "icmp.h" #include "tcp.h" #include "udp.h" #include "userscript.h" @@ -52,6 +53,8 @@ ProtocolManager::ProtocolManager() (void*) ArpProtocol::createInstance); registerProtocol(OstProto::Protocol::kIp4FieldNumber, (void*) Ip4Protocol::createInstance); + registerProtocol(OstProto::Protocol::kIcmpFieldNumber, + (void*) IcmpProtocol::createInstance); registerProtocol(OstProto::Protocol::kTcpFieldNumber, (void*) TcpProtocol::createInstance); registerProtocol(OstProto::Protocol::kUdpFieldNumber, diff --git a/common/sample.cpp b/common/sample.cpp index f44b979..a37ba49 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -54,7 +54,7 @@ QString SampleProtocol::shortName() const } /*! - Return the ProtocolIdType for your protocol \n + TODO Return the ProtocolIdType for your protocol \n If your protocol doesn't have a protocolId field, you don't need to reimplement this method - the base class implementation will do the @@ -66,7 +66,7 @@ AbstractProtocol::ProtocolIdType SampleProtocol::protocolIdType() const } /*! - Return the protocolId for your protoocol based on the 'type' requested \n + TODO Return the protocolId for your protoocol based on the 'type' requested \n If not all types are valid for your protocol, handle the valid type(s) and for the remaining fallback to the base class implementation; if your @@ -89,6 +89,11 @@ int SampleProtocol::fieldCount() const return sample_fieldCount; } +/*! + TODO Edit this function to return the appropriate flags for each field \n + + See AbstractProtocol::FieldFlags for more info +*/ AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const { AbstractProtocol::FieldFlags flags; @@ -123,6 +128,11 @@ AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const return flags; } +/*! +TODO: Edit this function to return the data for each field + +See AbstractProtocol::fieldData() for more info +*/ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { @@ -213,12 +223,11 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, case FieldValue: case FieldFrameValue: case FieldTextValue: - { if (data.is_override_checksum()) cksum = data.checksum(); else cksum = protocolFrameCksum(streamIndex, CksumIp); - } + break; default: cksum = 0; // avoid the 'maybe used unitialized' warning break; @@ -257,7 +266,9 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, case FieldValue: return data.x(); case FieldTextValue: + // Use the following line for display in decimal return QString("%1").arg(data.x()); + // Use the following line for display in hexa-decimal //return QString("%1").arg(data.x(), 8, BASE_HEX, QChar('0')); case FieldFrameValue: { @@ -280,13 +291,15 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, case FieldValue: return data.y(); case FieldTextValue: + // Use the following line for display in decimal //return QString("%1").arg(data.y()); - return QString("%1").arg(data.y(), 8, BASE_HEX, QChar('0')); + // Use the following line for display in hexa-decimal + return QString("%1").arg(data.y(), 4, BASE_HEX, QChar('0')); case FieldFrameValue: { QByteArray fv; - fv.resize(4); - qToBigEndian((quint32) data.y(), (uchar*) fv.data()); + fv.resize(2); + qToBigEndian((quint16) data.y(), (uchar*) fv.data()); return fv; } default: @@ -317,6 +330,11 @@ QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, return AbstractProtocol::fieldData(index, attrib, streamIndex); } +/*! +TODO: Edit this function to set the data for each field + +See AbstractProtocol::setFieldData() for more info +*/ bool SampleProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { @@ -387,7 +405,7 @@ _exit: } /*! - Return the protocol frame size in bytes\n + TODO: Return the protocol frame size in bytes\n If your protocol has a fixed size - you don't need to reimplement this; the base class implementation is good enough @@ -398,7 +416,7 @@ int SampleProtocol::protocolFrameSize(int streamIndex) const } /*! - If your protocol has any variable fields, return true \n + TODO: If your protocol has any variable fields, return true \n Otherwise you don't need to reimplement this method - the base class always returns false @@ -409,7 +427,7 @@ bool SampleProtocol::isProtocolFrameValueVariable() const } /*! - If your protocol frame size can vary across pkts of the same stream, + TODO: If your protocol frame size can vary across pkts of the same stream, return true \n Otherwise you don't need to reimplement this method - the base class always @@ -431,6 +449,11 @@ QWidget* SampleProtocol::configWidget() return configForm; } +/*! +TODO: Edit this function to load each field's data into the config Widget + +See AbstractProtocol::loadConfigWidget() for more info +*/ void SampleProtocol::loadConfigWidget() { configWidget(); @@ -451,6 +474,11 @@ void SampleProtocol::loadConfigWidget() } +/*! +TODO: Edit this function to store each field's data from the config Widget + +See AbstractProtocol::storeConfigWidget() for more info +*/ void SampleProtocol::storeConfigWidget() { bool isOk; From cbf114c29da28eea888acddcfab775672020d7f5 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 24 Mar 2010 15:56:11 +0000 Subject: [PATCH 51/98] - Added version/revision info to both client and server UI - Top level 'make clean' and 'make distclean' now do not stop in case of errors - 'make distclean' now removes the object_script.* generated files - Added the Logo to the About dialog and also the application icon --- Makefile | 16 ++--- client/about.ui | 155 +++++++++++++++++++++++++++--------------- client/icons/logo.ico | Bin 0 -> 2238 bytes client/icons/logo.png | Bin 0 -> 18467 bytes client/icons/name.png | Bin 0 -> 2813 bytes client/mainwindow.cpp | 5 ++ client/ostinato.pro | 6 ++ client/ostinato.qrc | 2 + client/ostinato.rc | 1 + common/ostproto.pro | 2 + server/drone.cpp | 4 ++ server/drone.pro | 3 + server/drone.ui | 10 +++ version.pri | 16 +++++ 14 files changed, 159 insertions(+), 61 deletions(-) create mode 100644 client/icons/logo.ico create mode 100644 client/icons/logo.png create mode 100644 client/icons/name.png create mode 100644 client/ostinato.rc create mode 100644 version.pri diff --git a/Makefile b/Makefile index ccbc2b8..557a682 100644 --- a/Makefile +++ b/Makefile @@ -10,16 +10,16 @@ release: qmake all clean: - $(MAKE) -C rpc $@ - $(MAKE) -C common $@ - $(MAKE) -C server $@ - $(MAKE) -C client $@ + -$(MAKE) -C client $@ + -$(MAKE) -C server $@ + -$(MAKE) -C common $@ + -$(MAKE) -C rpc $@ distclean: - $(MAKE) -C rpc $@ - $(MAKE) -C common $@ - $(MAKE) -C server $@ - $(MAKE) -C client $@ + -$(MAKE) -C client $@ + -$(MAKE) -C server $@ + -$(MAKE) -C common $@ + -$(MAKE) -C rpc $@ qmake: cd rpc && qmake $(QMAKE_CONFIG) && cd .. diff --git a/client/about.ui b/client/about.ui index 6ce0aed..5dab03e 100644 --- a/client/about.ui +++ b/client/about.ui @@ -5,10 +5,16 @@ 0 0 - 400 - 300 + 456 + 303 + + + 0 + 0 + + About @@ -19,62 +25,103 @@ QFrame::Box - QFrame::Raised + QFrame::Sunken - - - Qt::Vertical - - - - 360 - 51 - - - + + + + + + 0 + 0 + + + + + + + :/icons/logo.png + + + false + + + Qt::AlignCenter + + + + + + + + + Qt::Vertical + + + + 20 + 21 + + + + + + + + + + + :/icons/name.png + + + Qt::AlignCenter + + + + + + + Version/Revision Placeholder + + + Qt::AlignCenter + + + + + + + Copyright (c) 2007-2010 Srivats P. + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 21 + + + + + + + - + - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:29pt; font-weight:600;">Ostinato</span></p></body></html> - - - Qt::AlignCenter - - - - - - - Copyright (c) 2007-2010 Srivats P. - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Icons (c): Mark James (http://www.famfamfam.com/lab/icons/silk/) + Logo (c): Dhiman Sengupta +Icons (c): Mark James (http://www.famfamfam.com/lab/icons/silk/) Qt::AlignCenter @@ -96,7 +143,9 @@ p, li { white-space: pre-wrap; } - + + + buttonBox diff --git a/client/icons/logo.ico b/client/icons/logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..28f1f06cad620b6892b31cb1a0f9178a960c1c5b GIT binary patch literal 2238 zcmeHI(NP;Q5PfH%AQUIE6PZhnTzo!pn*2crm=2%<=m4kyN`MaFFMmJ<;0k~aC;=J( zo^-Nd!VLMzOnz98tkdq(?%OBb9FXx>Rp7tEZv`v@_{BjN#vH-_mStH6V+?w|9)`mq zb5$6PMp#){!RqQN*4EZA9*?oUzK)HJ4Qy_1Vry#)+uPgN+1bJF?k@KB_OQRdkAs5) z93CFx=;#Q?$HzE1Il<}aDbCK$aDIM{i;D|fUS47{nc(W`3fI@yxVgE(?d>h@?(T4Z ze~*WU2RuGLzD4;x_O8IY0{=h(|94xGC=#k^Uc;L%pkKSEo}w>XnnLGp>U^GKOlYkG zO6b9#5I_!8Oke4M6*eMfL^?~}>r}o{_$VMtPnJ_a&F2`8%=`GnEQ9Cr;mIj!7eiL= z`GW2M`1}Ik`jH~cC^`*H4wxCB5HM2x{LzPKMbfYY%t}Djv3^slRz=rAX@N3jkSweh z!omp|eL3cQ7b?X=($rr+ZIZA~z$UxSim)+O_VesYp>1ZsH4L$IJP znn6Fzjt7$)-!M+*Y^sftd%8kOmYU6oHXi#TBq-VuBRQUG;cUCf%|5*;Vnr?sQ3A gQ2T;&6*BTBEr&UnQ=;}Gol!bh@O*#gKyjDi?yfKQe~b|lk^v{# z`kHfGR5^p$54hf!qdw@R08-*^YaVJ6Ja{Sq&iM%MWNC3Hce( zSw_bV0Khf)?*=71sQm--B!Ro6w!6BMrMstzs|CQ*)05T4(az1x#My$?$<-?7T#yg| zAP2}wh-!G{o_@Ch6Mvl#-*l_AqRpy>#Ukg+I;t>C28*in#mfP3a73Y&B|+xu5*U)O zgK#RM*s2nuqKT5twUP8dSg2)`6FiE-jEX#2Y%y(U9okughqnNC<;<*eU7zoWqc;dM z9w!?D>mJ9B2c6O~rb2Oa8zh@j1n1HqS?jP?3>UyUfD1fNt|?wfW*)D?7J2y*>Q`tM zg1SGIFA`{++R>edRlflu?Ej_Hu(IKG7AKT?I0d*S09eL-?Lsw0E3BTnw>(I8Ct8}g z(-`%EDNk`IRmiG!eSO@K^@9Ovg;WN@C7v|(NiN&p&%-Zvhk;lNDex>fvMeU-?S%SuoXEKoYk&O|eI@Rpt+Lkw^8%mhm|mM4R^O`Z zeGM$Sf;4(jW*d=uaKNWRV+K0Ri5I1A_wy%<^b?TRLa9lclyG|C0AHj#*g{k;@lc67 z1GsERPf)1=|hv`jgerYgJPS3ns zgYoWL+(XT9#2x&0h)uR$v+8+)@$jXmOJ3w3s7tSdimx95?`c|^u)OIU8ipd-hFG+KcA3#u=sCPV##r16t#3kkVeeAU7?x5TbZd2BGaeBG(V=-$&Yye zda$^(0U49abUYo(CrBr#=D-pgM}i>1@E&f!g{P#j)9Srm)ghkBiYaazo&-k$y=1K& z6N;xn!NT{H2jWq4*PlEin;7QA15O=o3v_xm#DLl!7kje;e=UkUBznf|R(*-SYJ-KH zejgZyUcY~|(5uh5So+zJ15WI%iN&;Y$A-n=v7YI7*(w939@9PpF~-eN&CK0vEEB zKi7k%L&sWypa|t8{XmngPO0WB1zO&|o*oVQCd^SK=pCG|bU{}dry9jm0B+L1x)PdD zhl?N)Z~&BM;q3=wa6obbOug@(2!`xfBV1}JMubh<_hqeKQiL)-(FYS zY4dXeU3SmAok^Q=spqPcLUV^f1qi{87(xJ^aC-0{JS?ENRh1GJ$S^Mf2<{caX0R*Q zkQ`*Xz=A@dp1fJg%c`$#hzUaw?wSFR;Cb*XV$lgPqd|#KhJ#QbvoFUl`d3lmM#iXl zI^-885x30ceXysQ9yy=i5jaPwkk}qftxfcrX zZFogMZf?wud>`cHMw{_+&~DFsQWQk3V24S_Hmwe$58DG}&fmKyrX!lPN2yQI!yeT`p&2*uY~aPO8W%A7gOA2eBc>zjlI_acJ)p0CQhv30GkjQg z;tOYRWMuSRW@+T5Ac)7>`R*cei?@1&Et>_CkrL}9enL%6I}6Xd-($VyOYDf6R|JAc z$|%18wa+gY`ey}@C3m|rHEFn}kw06t>H;E6)S&4q=>p(o)QKAgr zD$Vk+A5`^LZRMKPF1rlyKsQdTNTHOgFLQg8Hjrud@_|njp@<*Fofa;FTZ@?xRBWK{~>t1=TKVg|C^rbz^nb%+0%du9Q z4XijRy^7FH`i)QOzaRl=@+#@RlAN!o_p1OjX`*YclrY!V6iAFP{jGA-r`2Pi9)IIi zR!=Fl#>ED>s?uG(DbTXx=UC10FY3MHNoxv#m8Hg7-&tKDa|m{M^>5N!3TTXj0jQPF ztzx`(EW98pAR45*&o=wh!bSYV&z-0DN!?y6vhWXdNT$}UM5V@zI}Z;QK<_~y(q@6m z%NXU)KR-F~{TXz(5cX}4h}s%aewpL#M*dIF(2`-_Jf%!vb` zT~!b@WOXp^$iWjt+GmV~r}^JDueOH`Cm2MHFVsctBk#L0i+sT&ZqxmJn zx83G$QIsR=6!iO&IEaA4$@?=$wb=n2GH$23(<S^mlycO zRg8sfOvo<(?(UC#C7R$u187u4oAa}js62||3|;+#q-g6<7XU!^`^4UFU~f}gnG?_f zwniayUy_nzKX3T+Vxio?&nth1W0yt{hNwIDa*^&ZBq7I#)`V+Cg<%k{f9LeHcOPO% z{<6b23~nt+y2DN4+!or;gysb6>nyXQ!O1>Y-%gq?W#fst}aEG{Y2>x zN`24ta@u-9YB3{qQDxbGZWG$tDX~5XjH=mAA1o5a>ZsmO-k4MWoru0?=b5rP+?%Fc^& zT6t5({a5K5*MU6;y~$a1+V+2bNorRcx+=FX^80E)0-%BsElsev>UX+JJ`gJvhO;o$ z@Sx%i-ra4D;ZSOjcDe=Oz#D+)hK0UWUcwRP^8K=j^Nf*LPK^x`kQpLH zvi{f2ak-4!0uzg+Ol9KDSzJm_rO7t5^y>LeVB4WdpNMUz~M zH}0xvV|4~bI%%rD$x%Fz;o>sgZdOpEog5z{$-%5+(d#$((iqR~Y}iqpnFqrEAiN4U zKn;O`MHk;X>~Bb!Uh0LsOHIh%W6$rF0iQw3O~k~WEE(x9L-kY_p3weI8QU`?eqL@x z<#}WRboZ2^4!5)f3fmJYO77Nee>j&nHW_fWf4`zd_s0T%gtOFePmS?S5+nVN6|M6@ zr|;~mXKtuQTjbW{u;)^ZsamYsby9%`<^6-{ip9)fr2x6fLiY3NWD zL117Y5k~JBe#??C{(Ij$_hasdO?uOJ%hobpXr|O}EsA&dnzxp54+EYU#s0I5b~FMO z4a)^{j8{bbhH8nBzItt%snCmze1B-lU&TXqS% z_dt*}y2HZ>%T=U+EG995?ayBQ-EC=>b~^Vo`94+ddtFIk^O!jY+f+7prNgpajfh;J z6Ff_Bms<0iikZ*JR2iX+psl|$tjHx3)d0)4WW&F(kN=7!&knfjKWGS;*>g^XFw4zz`{wh z0WYDTGahz-bqoc^zyqj%EX-pNll(XYV^dy1HkcA1BV~r5>J@WA65KJt%pp9}jQ=jn8{>&3GP!F%b!$r%m9q~8-8NAZ3-&A} zE;U`yhO}G^Tlg5m2p0p~-#?ukY~ACVnH*P>5>K^z<|X1vkUZh0n8@W zh%Je3UwS?Uv(@gZ?$V9eF;>lh`Qrv?*Ay5HBZ4muBSdErRFJ^!MS^)ZYx|tylFJVu zy*)!S-)yx>r&*W1AGqg?`~Y6%d^RQqTnb}tniXvgOf1#xT(xd$6qobG--v)%5!KTN zK8yR;=!eY$I=4I%C?{K(D;bMNZEf0uAi1n8@3uMAFJ( z-JirZtKYhr_y(p(!g@-guh*q+XJgWp>##~ZV8H!;(aeQ~C8+)*JL^{t1Al)zeFBgh zCu|z`#p;?NLK3OXr8i0-8)Z!jA8OO!z^5K)G18Dro8mog)CWbHYbnv)2^s3^@RRl( zD22}>46r3CX3_Nah{p1X9Sikac)cR-CXZ!njLGR9gi-kjxYUkv2d5@Oxm**oh*zuR z1ngxkwhPsU@~Gz77H36K!~as&a<(!c_1pa4scp+sQz&KhicR@4e&%Uw_Y|I_45%!9 zJCd{)I6ZP+=;vv{CkfUJ--f(r)4HW*xf6e=WxSqvpvWg}#qBkP$!c39UAED@r2viR zdW`TcpC&!8O_jD{HL2~V%TXt>%Z1n-uECSSV)$hCs=(f1Nr}kPnXbu6@fJ&~@lzS2 zIUU&U)CtMFQS2$E-h0Q$;WKAG``OGPY{|s8Ew`q-#*(4&O(YMeLhg03h0oHjxxJ z%QSQGkp0~T)a^P;0RXG-+ugd{fv7sh?g|#PQ>~?yu-GZ7WZIg{o?Nv$9P#j}i@Kq(4<11!@)C078lgnQNIGi@SUlQc;kWztp zd^gu$UZrWdf2mOrFiMUEfEhQq|Dlf__#}yh1bqs-CHTWI?Si0e8pYqd$4( zL6o{^rqji%$XZ8YgD^$$GP`EL%N3ll=l4KX!v@FC*H=t?=r0$j(tx2Ka8!Y`DA~%ok!}4*LC*0_Z(q>k%`ntLMVdF*E6NtttYA$ z*}#j*{iS?}njzDbn&E1ZbY7|La9BOBDR-layvsZQq($6fdDHNz^stftc>=mf{-WD| zam9Dw;D5;gbg7}yWBT{so}aU01_8iXoL0?riYL5-oh+p48e<&@gSwl<`gVIBKmc%X zu_dNQbkuytNSF~;@iPV_iHSmUOknZ)7$M~uLP0@sQ+!r*lgG?GT20>4V_UsXu^DbN zfNuUJ-^et$nj$0=H!;0oOskaVSFe0uhKeke1x^=Y&yJmk@}oe;)l> zHFS?e@(spVMq94nEiQYvx^g)ZG#M;H`^6Bw7$uk@@ts{YRO5}$i_S*OlBJvpfq=&e&8rOt;7a>F` zjQWE>rE}+O(dYr2fiAAVCO!B*s|0Ri4FpNZ?oiC#9M~Hdo(8b1&qnC4VlY{_G5)YU z_BAJ=`b1J3K!94?sgW3CP7KE4z>m6wursSl9e(ypc`xgeWa4T|?J!O&I9ih)7RwTj z*g%RcIB{3s8oT9<({8}yzA1M8=9kED!pOuRWXkCkP6mGlo?fjmssSQ848`>F6cmcN z!_SbiybCx$CXVf({^Q_33B01b`zy0yrxy)9sa^+%-D6v1wH>zAs99m-knctd^We=3 zBb>~WG!~Zc+%fdr5`$)~?}$Lw#>PP>tJIc=4`Ad04=JcaI_R&!P*L`@8T}4Vt}}Fx zbcp;I{Eu6qt8=gV6&_ttPp4Z(uUzHUinG~}kD4^3%$FA`@f0#d(tDO)Tl~SPj6kHO zb-@ji8p@16e@loYw6wIW{+{DR4Zm?Ydh|TQ^mHcq9?h%i>idk{TK}7}E%*Gd9hdsO z<3`~Z3oz!ye>NPi5AKB1RZ>k$!r@hwxXt#E=E*V8wh&G%WIkGa;wJ5)enSm?1m|be z$wcC%9A=m3pmHXum^kY%FW$**t&-4c8aTTlpB~ zvi~E{5FYl%`*%nfNq%@sq%syrZ;{ARSn)heFMZhdA~w=>rp@^5f3*VL73&o@n^-TmO>VC7Hj!f2C$em=NMCbgzK7H$WNW+#{n?swSucYS!Q5 zpU4&od7_E-&tG0IT@H@!e!^7j7)R+6PE#q(3>h#L$#PD#=zL@sP z+sv3ayHdj4h7(kn%cH|OZ>pQT`l#miFGH<1@pvN_n3pG?_!vl=3`ckEH;K<#ey+FT zJ&BR_L=M&|eBa>qzwR4E&Im7;lHwCn`cL(yO6rn5XG!cLw;kuEv9tOV3Ur^9gehmt zZD)ju`mcqb-o#&A_|4XfIKM^|40e*)UtA9!!riDES!+M30S&oS%VpLnfrH+)DIY~= zxbPtTok>!1Q?gv~hEnFjcv+&Yp7e7I0AmdFY{1)cmdfx+)7_mE_-~q>(ia;6ydX`B ze1(bmxndL-*ET6nhPpk)^7M=9vn&t|vtW7%6Gdn783sVUA*zkdTHO(VKBIKMSP=MU zG&=yq%J%&>0jlT+6}e=vxiNyvFhNp&6+Z8KU~%JWgX)2bDjm^qyV+L;%V)xoSOQKS zh0MAeRcAabLFk{4!%=fikU>A-Neo z$PB=x5MJttoltGbJMI>p*7!?E=9QrL$8;gaHXXJjU@RQNK6E?dRTP%4j#-RfTY|L0 zsx%@XFoq}FmK*?SVBJ2Yb7KxHzRHi8!?fD%?{j*7?=}ypZE;R1hzKgXq>}mBhG|Sl zNd%J#G^UK40Q`}Vp~Ajox+)_`7&Mi(YFO3^8PnoQl;HX%2-_{S3|*xb;zdR7g8{2q zIXd^1#X-Yq;%NFY});x4|DWk-Nm;#2Xe>^xhTct z?5C5z?mb62JP+5jDoF@0GFv=icn#{Ja3*?r`VmEuvkQeG$dh|T_UNlLWB&D}Q+9S* z`Bu&FqAg*nZia|2sJ=x6;2jZ`yLmEa{-yzO&ZcUNm$8{lvhmXH8{T56(0f?`4?oCj z#kVm91R)iN-b=J{%k%mXk70*RswG8elo022Ea`P*R9^!U@@|3iF-up(BaY zpi~Niz&zPpGD1L@68tH-4&8h1`y<(Px z)|(2E*5}Cc@OpJ9(8P_Pc1@u~Qb+fAl=+uK)Z*QA7&ClbtSO?=Wagzdk6Ob6`Y(Lo zP=a0=Y_jv%p19$$PNMv^fnm=ngu#n(}p0>is^t6LrLl ztx`^YD_e*%mgJgi^;QzoFX+dFTP7Hc($<~+#~?b9>A$83hYfo0l|=4{XiKQ7T}U~A z{ETnU3NEz=>^~FupV=Ua?gMY(qrp)bI2aw>=Z5oAfGQGn5?ArLS*otK#;Fc;5wb=0 zEtlS3dK|7^vh!Qz5XD-2$>*(h2&=g;a z52o-Hvn*5C=ab7_e#978dD_LVS9;iW93=F}6Vep9V!us$N(!zdnN66{uSt7L=9G75=3Rx3JT(Mu89k-E^(kxupou5 zQ%2ocWs}%bIs?H9NKV%(fKA;9MyJiyVoQl0pyDD1*>405l=#(RHrqg_OR_PQTb17Z z;=Hkw{&Bb((E>kI35Go<^6TnGC0eTw6sph|h9#HflbVl_miTRYZJh;pFg>>|)d=~r z;ekEC6E=-%w^QzBPwJDi>3Q^41jIAw51EQ`SY-p?yFAiDQGzY1e3ZjraF4!!|6a)B z6UqSvXm?xCAr*)!O}m~2C8_CTj>lj#ynM8+Z@@uA%jz@0E zu+r_#Q`L^^y8ppZo+IakV};bbyYVd9~gOCgh|A{ zsoc|&M%j~x|Mq|c>V5_yO<4x))@vTtc~yqta{4?94JuUgPN-8=$=MC`w)?<^mDSaL zQk-Aq2NtUVSj@_U1+YdZ=jWs~DmHdn&`MnLp^6e@T!UD}!TP#m+i`S`%|~RP)t*!M z7zpFi+ft|%ZtO8(>C@a=G|w@fl9WncBrbJeFYFahF7)4XO59C*-e4J>UeK+JnM$ev z0Ij;@6DjWJR>+|riDU{@fZW0K+=9fq^t`dm;>NQ)^UWR5+V3=n6|SKO2fs@`u*W^# zP$i1|ka+%U{J>P4s1Eo+Un~w0T*jYy$W7L`hZw4aJdE`e$C~qv>ANYP#5l3;t*2kU zKIir{1oZtY7T?7S51<`LT2;!z;*jXO(81h1piWK*B@~rG^R4r=pL_BIIK?qrfqfZ4 zW1DJNnLgguZYIPC{y)30uixp)+OP4{=}U}>cyLsM)e%Zb5IOG^5nDL9ydFk!eSXS8 zN(a0?Wl9_XXuDpUnWszjEIN`Rj}Rt^Py=kdR3>FSySFopV8esHampF|m|rSdg~kw2 z7%tR6bFhdfojw!1jFeapR|pUYo2pdl?HOabH5jRJU;lVASp306_zS`X5xcO0jA!2` z)97dwZ`{F!$}3PH?EC5xKPH)nF9+o0>zRO0C=)q^+>(v$RR&OAMWG7`aO)y2Gewo` zrq4`-r4fG$PWXc(tC?fk;fuwd4w7&TkJZl4D2%lvLT_aJd=BBDbB5Z@$e_3Q7m39# zfmp`mF?ei-S?pCU|B{ruX0Yv0HQdO3GMR*WFJRRC=cwxZnQ?RSCM@wZ{hi>L$FofV z`2|A~n9C}mL>TzW*P~F2Z@xxGMg?vpvWr|3{ZxZ^SqCs6V?D_>{2r~&u~12dHv%?g zEIc4rqW8`I9;8<4H2uKYLHcsqzrQVb{d`qU=h-W_ zrF#am$5D7uApU)cAPIh;|Ivk7lzLF>d1z%w(F-leR8Gu*JC{9s7Me;>Y{3II0Sw9F*HHmVq@QwH&u;>dk)QUQE9x?AkZMU9e zbm_=;vB4|Zu#2DcizrWC=Mgv6S6c4f(x`I@$}P<)%+Mcir~|8>_OKN*@?G`>_mv!%PolN1U3+)nu;Y0O|V;NJ@2;c7{7)hE{Z2IvVqO8rZYdzVVLN^#In8Yegevo2|+SC2PvcG(rfjk|flXZm$KEL1gRe>pLl`CwLfl?7?PK!R$bO5y$Mj;J?&Ony!4% zGx1PM7D-1MBvE|7tIoIpIGcUY8!8MW-^twgTM8KHpz!z4m3mutR8NAF_BQ=)6p=T? zC{IsMZ~X}(zMDp^3cJGm%Sn^+rMZrUmRl*Q{sJxeHiy}C)iP@RhciG|BU8{HjC-{n zj-8Jg8q5uG^`!dh<1K&J7Bq&P;05?f(;g5Da)b+|jlUs~vQ8EMRyd55@U!rNP+C`z zwIzl#lBSxK!N^z6F0s=8rfLli(y5a1V9T^QW-Tl#Q*;Fj}sG9uL| zXVy7st~?h@BmGMPc6w;V+*x0=z$9T~;&3+)(!gvNzIbQ4rQ2rr1PsmA`sU&BRNQJ95|5ILnqVLS zQ0}x}{VMwntvJ=VtZ!t*2|_tR#98KZ*LuH_OV)P*?Ljavd>$O8HW&VH6P*R@Di=IP zupB8+AZnwMr}MR@hb9Q_l!EIcX-@5NK}qaq=6vmI3lyFa~cybc9+c z*=2kBs0AqvQ>#^X48@O{nBkrN1rf+O>x)~eL19K?YuZ_O<=lbPj8eL^w(FgJ2Ok=)@D2s--JE==k8!!$usWSkuzykuQ4htHK$Hm zB~Kr|pl*vMsGx%`nT!YKz(te0xm3Wb?4K7D)p_~s6HX|k&-mtL47e~-7+S9j!ctT@wGdevG3ywEQ;w@&&=F8YTA!N?hOrpv&0ttI0Mc_AL|%-$~qX-XIt`giOQWlNy|!euPpJ z9J~zbtmZRy20qlhEMId*@&oIUm`gWR2)21NUB*Bu#X;yFxW~g{ebM2eh-gLrp7RAJ+jZb? zzX~GOS~>2u29e)c7b81?AJb<|^NuD%1-|lqTvKS5t^qtLZr{qJ5W5Kf zi;u%iO>fm|$)rx&fFdne0$X$PWD0jp3C;9+ltrqjXWSkbDaHp_LLdMF$w^nuLcL=& z?LpgM!#byEUcV*1tEF2ga%r>vA@8{adRgYm$RQ=@luzKN~S2FB-12D?x;hD z@xHLIJeD9hPD?y43en8v|003c$VDx%!{R~m)ts_|d-JbovAl}F23Ac;M z^@YWoy%Nf>kum?HPV0WR;!Em;rIF(5eU|qzeRMrTR}e3x1>;aKV8@L)%Ve+OkHsby z*#SiNp|M_-Wh{v@runSmoFZ>E4c)a`x(gfM7*kU-fD(TeM{d1ben!K5El3-J0_c|S zSy#F2QnW4?Yql3Ssc%?V@kwRap2-H!R~jG?07 z#B>T6*eviY8luXcxc+6a`Kxu7T3G=;u*5&$e+kc~0Y2&X^WpVerB#=b9MsJ~H_tS? zFtyU{@HLfSfkA;8iORh%H0n>ny&^n$g5}$uGxjn8V>KOOf|9-AfFEW4be}W6*(+bb zvJqy$fBE4UQQ40_f^0K<&jEl?12E7&hIDhKR=2lHDnq}rpAkXid3rgLbM|C$ZI*>l zYnTL!F784C(hS4iJT^o77`M?!^y1(H%qU`P&Cs7o5 zieJSD%4hGhax1IaiX%Jo8*o#dEg_%@1Me`l#5hr)^0c1ryVT25^IJVm?X5$vTOHHQwX&VYpoG6FYBZjtA~-3 zKjXDJ0q9;@WL_NW)*G_?_oG?A6?9rfo2V7sro85!tr(!x@bluZuYJQ5kJhjcKR74{ zXEzljP!dfj=|6Ht_ZW}8;HFhzRC{t&;AE8x_qSKY@{p{pngQGwjn=i>t3}l5xNw zF&>ifdRpALzV@naw?QlnUijQV4JoryT6Z?CtGqk|fRSi|#gYExjRixhikeuHQVm#& zb!M?g1g@1G0MIYn0cfB&;3Of)Jm%UtPw{9ut)QP0W41B)1qcFyjeO62)qfv0)O&NJ zGxb< zvP3W23-0?Uh!VZ@#SPsd0JPZ0am%VimnzsC(K~!VAIXX0N(gu_9TE!z0RFL0Z+61? z&lXpKiFiy)a-}%smH?ae4+JK*cIFxMh7-v^VhgGogU_#6S!QhE1Jz;M$It=XBr}PD z%<;Cc)Ez-ImKf+2-%fJD872Z1(cPU(ZxWm0bJEujd!85DA(!6(XJsf{*hYc$&(8uG z2=?B*5q%Xw;vs0>O(ttbM{byyVtqxv=T4qC-8JPQG}*45%35!X`l4P_6mS7!RDi!< z^^0((w-Ee~MxZ2>=p13=irto( zLY~D7j%W9LAc=zPGDaK*F!Wdhr%)PLt#wiWZ z0^fL@MIr0P`1Th@cl@Al_e)TIP$JHzxj2ND^=BAvBX?LO!#IA3*@^%_U)TYIv3p`t zjSphYE^@!+t|F8sqbz;ZNKDVqW2%C={#;*>R?#~2Uy;NbDw6Amd;`Cy0E%Y3_X z5veFQr6QLwk&a1)z$NxKxLLeThQg#x0eY@A_Yz=4$JJw}!r;npD=wt*(i6n5-yC7- zAgbOC7Dc+t09H=8hMF~l72?YD(b;*yiMCM@@qrFtN;my(M-Iw>-UpT$?yppVA_)4L zC)#Co9K;;5rHF+r@$U)v^xCICiRgQ2(RwbncsVYs{{3n(rf`oQ=s#-$RCV#;{#kn9 zuOfvXF{Z_n#l>KJj~QP=00dZvZ4wMD18cp+l$5BkMC2iua=5<|hsjX2xC`cKSewt& z^-h8LvdY0H=qbpVrs8z=B)`w5oVg%yi3V-AFMj)NrA~bGezC9b_wPZ(+2aVU%m&+a zpxW9(snZ%7n0MMyBesr>-UC-G)GlVrGtRZs-ZnAXVYLQ0cGDdPSr7Wd=w4y2;5%bP z{v5*o+y#j~fz!0h6cXDbz2>CUf%jJ|%BEAN9ne2mWs(Z+FlY7RxgAN-D;2tfCqeO- zA8<3T^wr4#Eq1|jwe*!4%}o&)#{jZ9XFN=bN)PcX)o)yV=F@~J3g5qYQ2GT}ty97r z9UmV{e4bmxbC8iF>j<8{CkaJ1?O?Hw4rk|D2SK<;SXh(b4*|)BAEedvi19pBBHXus z}NZ3?Z;o-c;|*Kj|Y-6*rcISCCRuWt61 zWUge^q)MCEz_T~!$P%wNV7OXzC5g&!@1*>8+0L_|in*u-r=~Ig ztnu{|WVA|iV5D)~LZy;Svoq1tUy^pC3gGEeTw0x$jxRITOh$=ssb$hBs`;7>%O^7M zHr-og;(-5^Ad+&dSq6bZ#qD<6dM8ZVpN}cpbX4}_6{Hu~u${DY|KbaD#YlK8Fb{RcAjcFOK%FTjvtP3&k)iF#O4O@B$TRjmG|7h!>Lx#W*MUEW$ky}N(bLPhM`!YPs z_9?zW(WUDEb{juE>CCpv%plXpAzvb9E)Uqx1(Q;>8fVByY862y*lY4C6gTz+!GTu9 z!?SgDhPo_wk&O-?ZHLm>G7+uMEmR_ZzD#lhLatjp|I)*LUrJXU`*YloRWJoPT||>Y zCkE?(xg?HZ=1B56i8?to>HRB&L|0W&V2xgH7S+0Ca{3)2AR^25%4co- z=@!-h7x+_x{P@{+5w+PtfckZYhIlK(+>N<*ey%)4j-kA(Ot8uZLzeR!F*thqhqxEr zcDsem{uj!m{7}Sj%385D?@fuyIAaYISO7H^KY}FU3_0zQ%)f=C4qflV3vz91pXWyz zU+b`2(Z;?o*#A)+5R4Q3tDaLOy~GM@aDr03%B0;wBlQM}vMsxcNy>nyw9-{FghVI* zjaxzz^g1AK)Rq*R9aN-Nz8H#iJ>H`PfstMZ|4zBKt>q+QAP4j!j#{5`&fiWnp9K^T zvPJFliJh|{86>b^S)O*lzQUFnDLkxjk8eGGwp;kc6LokZ4vZGbIr9h~v{T@msG<*g zI$2y}a~P6rx~u;pH30&Ur;WcOO3+WqLn$jsne{_EM0em}wSE%+N5;r6_IzKJ**e2H zhucF7ex)+e`Q2w#1({>Ng>t|!0wC>*@*+NkNetx}vsz-ehOGeZ2h zOHaHKE9$R8ldx&YUI7mcm?7oo9;n6!fcrKf01tQDp^O?+E(-afigSY+VOs_J^_dZh z3d<3!ixwrJK*dTsks=4-i(sf|%&LeL@jxQSSV!RjC-1*<+hX96 z?-hr5mAsP{!ni-hxbj9Ua|k4}PardNA_`Of6%*WxzL=}D+`f7o(!Egz2ILv?40)jF zY11j(5JB_PD+o}w)?zZ0SDMVB!qT@FVhCat!j{ue=o$%d6}t~Lvq52q@#Wyr{G6_; zJko6PwqO5e;;9q%lma-iSqKxqVqx&p#i-UdtkRntOG2@+f zknS3l_IHT=?s>axr^AddHL!$an618%Ar=t^3JlRHQH@)>yiL1XZP4@@XH|v)Kti8k z8`Z^xHB4m6oC#LgJ31)XHcorAk=#~`^{>xYIenVyrAm-aF=1eyjU2QX-GfwIyJ^g` zC8e&5M@p!z;_TYa+cmVz1)0P#vYSNw84ujT(Q>wK;5dI))k12PQkOfr_rxMY)*=;A zSiWxy`B2K2Hi$$y^i&Tag z8Ht&YjSh3UeoT9ri+jq!*TuBw9*8Z>Ay37~$N9aXpPz*%=(80BA87pbT~;u*wyl9- zxD--AB78uc1tLtr({A|1CGMiKHFnF1?D_lsnZ-axV7wbpR0K{004TJlFBskKH~aAz zUL~B8zE$11AbsG<&o(^XE-O(rPQmxNU}@Dk?hK)O=RZ*TIxIrGk{`>{(&zgW_v|8L z?S?`lLAFvqiE8mlvM_9`>DoW<22I1QDa+MnEzmph@j?WP8o3own3(_5DPm=he7|&b$0}3;@vu!GARaV@C~kP zSrS(plS#52iKmzF#PAV-q$1YD5Pyn8RNo(6j8NJ|KHE2;*#-NBLrOYP6cXkR7@oru zJ4h-S_-G+WGql|T@`qRtZV_Y-!L4m-p+O!CBH&}hIU#yc+A4q5XMq9K6r1Sp7Kd)g zK$OM}%4bqoCI3wWJlw@p7*9&$Dvr?MVwUR5QYBOD5D3I=49x=m^k*3m;$=>#cH+@v?qsgZIv6x7Dw ztq=@v0Nfpjiep<-oRV;z^v5~e788ZUh!cm>Jrl@9eodv5Dl~hP99{9ysOjRSrnCOX z#yd}P(-0(RAXPEgL;(fMlCzUa>7ng zEyYJ80q6{DIyqllT;yFy#;7uY#Bka174c7=5rXtE;E%s5`H(T3u0j4rU*E*VGLYlR zQo+sT)6D^|g6mxUuc$jx?B?tlKY@VkQ$u*axcbSYW$m2FW$qW?qX@`bLh!);-03e;q z{Y${v2%jf?3du(jX6&4FF891!On)4d&;64fM&yB_bj`X&(loz9rEi1(6o~-ONZaxb=1mQH^mxCGMU_r`NB;AW{1Cvk7}ik>=+nWo{zNM zh2ZVS{{cKG?KpL5NUaT1EX%US85+NZ;EMr8R}1B+bgz9&!Zg25;>QTR-oOATr=)Y) z08N3h!CEY})S_DYIu=YEH%hFN z1~SOZ&1Y_~dcuk`K%7!V+(M&yd)&$iU15TRM8q&nb2Eedpor`YU>6cQqO~#c50dKK zOfK_i3)>tu)@cJ7WZNlICamb_JeI=K!sMoC5~~5c4qz#Or6AscNCe=f5KIO!8Nfu; zqH20}w~KXwRfJp}p?h&F1*69j>kY(% zL^Qe^l=?h04uGJ0wENRS2*IO5-lXy!H!WPeaOr4wXf#=GAOVPoBu#TiO&<9F?cKpj zTR|Ab@&B1dEu;&P?j(>vLAtF<_k9EP4SWFKqiZ)Ve1T@wx6mwX>8@g1Q}F7>LKg+$ z)|t=61rf1L(q@ty`F{HgvpI0@%$@Urw#dI_Iu!=JAl`-R>+U2bH_ZwU$cU=D_St(geQdCkjr6?&WDJG>DER;sPh#?fsX7hZUEiA6$0m-B)j%)v7 z=nk)2#h3o+kfR@5Zjb81RNWZ-OW9j3I%!?S1CoiEB~{axMxsBrFS;r4fMk^pCi9HT z#RHPjliv$(88jXD4#8*U=Jqo#$&JVZlF@N-d@0kgv)L2awx3PZiw7jLlkeZUV4M8C z5BRIZo0ERuU$1J$w|OU|)oLw0Z8Ubwcn!P)E0I1J96YUGPRo_qPU*`(NZdcWJ98M$9!`1Il)i+~gwFL;;R6`d~>lZcL9}0v-V#%Je%_H8BDGf%(9D zfM!S=fYE@Y;U>sB9$1rt{R(huLfa`B`xlqSc{nF~_17fG8iT#8t;+q4F<9H3tVe5r zbuTc#!nXHRF@Ehb;1_@qz;fVV2F!iHQlNh-Zi28z;Fk%&dx8G||4LEnCxL!t3|?p8 zgF@N>*|1?Y&`t4D&a!^}^BRlv2?fT`+! z%yk+}SVKf)RPZIhp9rVs5w%!y9PZJWtrD0IJ!5z}U>kv8_jzIs<>zfSTnhZeD{lrm zmC?V7%?3Aa@3{86fOgo-w9nN&PlkO#EzJh(McP4VduJYt4A{fHzH9=dAR=8cyAy09 zbbmQ-MjEL(`4_li1NH_*d3FM~x?&q(k%+X4^3^fT0DkZCJ%Rh0sQ=Tj@dB8ms&A{A zd3U?I9>k1y&NLc0#^vu))z@nUtg6d_XI$}9z`z190S>v$=BZQj8q)1veq;jA4}q;N z-yc{jBE1rL>x$fXO~hP40E2+L-DzPiBqFUb#b2u+3;auTy0`^^Ad3WOI?URB%KXke_%Ga4~jr1TYL(CnBHDsed&iRowubhn+43KHyW*TV*46gnFeb z9>DC|Bx>r}*FOSo3SDYhz?|Dr;kBmjUOv+fR8?=qu15yf5|0P|Dk2}Rao=iAs=5sL zjw?1&J0I{E?5ZfhB30d-#Hgw(f%UFlRnl6}aEoS9MLQIv?|*fIZ9yM5JStuvdHe(?#Ujw1m0tz*c}6Rmv_!{&Ve` z$W;Z2NIT4*4e(k4c-j>jfYWji*aqnBid)>qCNrt(^S~DgH$tDqPI2m?A8K`7_{oBGRK0*;&Z>^aERWa8ADNL0U+S=PMeP+w9~345t)iD z^I&mFk5viz7cbu@k*m%~Ro})g)4%MhrisXeiTo&zJ4EE9Y5_&$ax4HC zY_*yV?nF)=dE zu{JN}F$h9wo*`p6Rsz;Xu)_nzX0MXZmC7S2#69<*?Yop2ZGxFNzmAO4lp>y(Mi)~Y z$+;DnR6?;@Ii6^g=-^@#SUE4cA z&BHcPyCS>?%22TG*gfK)?H=GR4}Vhx`w_ASgx0O{MwIg~<;CK+f{W!_sPbaD!#oC? z1=Wpt>Nr-TydK7t6bFbZc51p93#$FDdyyAnW@I!3ekX8dEOv^}_P~$G{)Zz$x(Dc8 z<`3+Mg}SHV9t7?zXAnOG%G-eXV&jx|wkKywHF6@jw|Kat^HyGm(~Dv=B1_tXc}Wh7 zCJ&N0@I-R|%P<1F?l;6Knt#FhUF?)@8E~(v{xcOYSxy1F2YU%Hfbd}BMTdWjsy #include +extern const char* version; +extern const char* revision; + PortGroupList *pgl; MainWindow::MainWindow(QWidget *parent) @@ -58,6 +61,8 @@ void MainWindow::on_actionHelpAbout_triggered() Ui::About about; about.setupUi(aboutDialog); + about.versionLabel->setText( + QString("Version: %1 Revision: %2").arg(version).arg(revision)); aboutDialog->exec(); diff --git a/client/ostinato.pro b/client/ostinato.pro index c24cec0..2738df9 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -1,5 +1,6 @@ TEMPLATE = app CONFIG += qt +RC_FILE = ostinato.rc QT += network script INCLUDEPATH += "../rpc/" "../common/" LIBS += -lprotobuf @@ -67,5 +68,10 @@ SOURCES += \ streamlistdelegate.cpp \ streammodel.cpp + +QMAKE_DISTCLEAN += object_script.* + +include(../version.pri) + # TODO(LOW): Test only include(modeltest.pri) diff --git a/client/ostinato.qrc b/client/ostinato.qrc index 5f4df48..cb71e4c 100644 --- a/client/ostinato.qrc +++ b/client/ostinato.qrc @@ -14,7 +14,9 @@ icons/control_stop.png icons/deco_exclusive.png icons/delete.png + icons/logo.png icons/magnifier.png + icons/name.png icons/portgroup_add.png icons/portgroup_connect.png icons/portgroup_delete.png diff --git a/client/ostinato.rc b/client/ostinato.rc new file mode 100644 index 0000000..41983b2 --- /dev/null +++ b/client/ostinato.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "icons/logo.ico" diff --git a/common/ostproto.pro b/common/ostproto.pro index e2b9cb3..2c8aaf3 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -99,3 +99,5 @@ protobuf_impl.depends = ${QMAKE_FILE_BASE}.pb.h protobuf_impl.commands = $$escape_expand(\n) protobuf_impl.variable_out = GENERATED_SOURCES QMAKE_EXTRA_COMPILERS += protobuf_impl + +QMAKE_DISTCLEAN += object_script.* diff --git a/server/drone.cpp b/server/drone.cpp index 0e03b29..7f84033 100644 --- a/server/drone.cpp +++ b/server/drone.cpp @@ -7,11 +7,15 @@ #include extern int myport; +extern const char* version; +extern const char* revision; Drone::Drone(QWidget *parent) : QWidget(parent) { setupUi(this); + versionLabel->setText( + QString("Version: %1 Revision: %2").arg(version).arg(revision)); rpcServer = new RpcServer(); service = new MyService(); diff --git a/server/drone.pro b/server/drone.pro index b0ae7d2..34ea026 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -38,3 +38,6 @@ SOURCES += \ SOURCES += myservice.cpp SOURCES += pcapextra.cpp +QMAKE_DISTCLEAN += object_script.* + +include (../version.pri) diff --git a/server/drone.ui b/server/drone.ui index 73fde04..e2e0613 100644 --- a/server/drone.ui +++ b/server/drone.ui @@ -42,6 +42,16 @@ p, li { white-space: pre-wrap; }
+ + + + Version/Revision Placeholder + + + Qt::AlignCenter + + + diff --git a/version.pri b/version.pri new file mode 100644 index 0000000..df1335c --- /dev/null +++ b/version.pri @@ -0,0 +1,16 @@ +APP_VERSION = 0.1 +APP_VERSION_FILE = version.cpp +revtarget.target = $$APP_VERSION_FILE +win32:revtarget.commands = echo "const char *version = \"$$APP_VERSION\";" \ + "const char *revision = \"$(shell svnversion .)\";" \ + > $$APP_VERSION_FILE +unix:revtarget.commands = echo \ + "\"const char *version = \\\"$$APP_VERSION\\\";" \ + "const char *revision = \\\"$(shell svnversion .)\\\";\"" \ + > $$APP_VERSION_FILE +revtarget.depends = $$SOURCES $$HEADERS $$FORMS $$POST_TARGETDEPS + +SOURCES += $$APP_VERSION_FILE +QMAKE_EXTRA_TARGETS += revtarget +POST_TARGETDEPS += $$APP_VERSION_FILE +QMAKE_DISTCLEAN += $$APP_VERSION_FILE From 602be86a42bc19767d2ec75404a7d24725554b9c Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 27 Mar 2010 14:27:55 +0000 Subject: [PATCH 52/98] Fixes - Win32: If bindconfig.exe is not present, WinPcapPort::hasExclusiveControl() returns false instead of true (we assume we don't have exclusive control) - Win32: WinPcapPort now looks for bindconfig.exe in the app's dirPath() instead of the current directory --- server/winpcapport.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp index b9ddfdf..2e23aac 100644 --- a/server/winpcapport.cpp +++ b/server/winpcapport.cpp @@ -1,5 +1,6 @@ #include "winpcapport.h" +#include #include #ifdef Q_OS_WIN32 @@ -58,11 +59,16 @@ OstProto::LinkState WinPcapPort::linkState() bool WinPcapPort::hasExclusiveControl() { QString portName(adapter_->Name + strlen("\\Device\\NPF_")); + QString bindConfigFilePath(QCoreApplication::applicationDirPath() + + "/bindconfig.exe"); int exitCode; qDebug("%s: %s", __FUNCTION__, portName.toAscii().constData()); - exitCode = QProcess::execute("bindconfig.exe", + if (!QFile::exists(bindConfigFilePath)) + return false; + + exitCode = QProcess::execute(bindConfigFilePath, QStringList() << "comp" << portName); qDebug("%s: exit code %d", __FUNCTION__, exitCode); @@ -76,13 +82,18 @@ bool WinPcapPort::hasExclusiveControl() bool WinPcapPort::setExclusiveControl(bool exclusive) { QString portName(adapter_->Name + strlen("\\Device\\NPF_")); + QString bindConfigFilePath(QCoreApplication::applicationDirPath() + + "/bindconfig.exe"); QString status; qDebug("%s: %s", __FUNCTION__, portName.toAscii().constData()); + if (!QFile::exists(bindConfigFilePath)) + return false; + status = exclusive ? "disable" : "enable"; - QProcess::execute("bindconfig.exe", + QProcess::execute(bindConfigFilePath, QStringList() << "comp" << portName << status); updateNotes(); From 59c9ae8baa3645bc2fee54abcbc433d64f6d64fa Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 27 Mar 2010 18:38:57 +0000 Subject: [PATCH 53/98] - Added Copyright and License (GPLv3) notifications to all source files viz. *.h, *.cpp, *.proto - Also added a "License" tab to the 'About Ostinato' dialog box. --- client/about.ui | 245 +++++++++++++++++-------------- client/dumpview.cpp | 19 +++ client/dumpview.h | 19 +++ client/hexlineedit.cpp | 19 +++ client/hexlineedit.h | 19 +++ client/main.cpp | 19 +++ client/mainwindow.cpp | 19 +++ client/mainwindow.h | 19 +++ client/modeltest.cpp | 19 +++ client/modeltest.h | 19 +++ client/packetmodel.cpp | 19 +++ client/packetmodel.h | 19 +++ client/port.cpp | 19 +++ client/port.h | 19 +++ client/portgroup.cpp | 19 +++ client/portgroup.h | 19 +++ client/portgrouplist.cpp | 19 +++ client/portgrouplist.h | 19 +++ client/portmodel.cpp | 19 +++ client/portmodel.h | 19 +++ client/portstatsfilterdialog.cpp | 19 +++ client/portstatsfilterdialog.h | 19 +++ client/portstatsmodel.cpp | 19 +++ client/portstatsmodel.h | 19 +++ client/portstatswindow.cpp | 19 +++ client/portstatswindow.h | 19 +++ client/portswindow.cpp | 19 +++ client/portswindow.h | 19 +++ client/stream.cpp | 19 +++ client/stream.h | 19 +++ client/streamconfigdialog.cpp | 19 +++ client/streamconfigdialog.h | 19 +++ client/streamlistdelegate.cpp | 19 +++ client/streamlistdelegate.h | 19 +++ client/streammodel.cpp | 19 +++ client/streammodel.h | 19 +++ common/abstractprotocol.cpp | 19 +++ common/abstractprotocol.h | 19 +++ common/arp.cpp | 19 +++ common/arp.h | 19 +++ common/arp.proto | 19 +++ common/comboprotocol.h | 19 +++ common/dot2llc.h | 19 +++ common/dot2llc.proto | 19 +++ common/dot2snap.h | 19 +++ common/dot2snap.proto | 19 +++ common/dot3.cpp | 19 +++ common/dot3.h | 19 +++ common/dot3.proto | 19 +++ common/eth2.cpp | 19 +++ common/eth2.h | 19 +++ common/eth2.proto | 19 +++ common/icmp.cpp | 19 +++ common/icmp.h | 19 +++ common/icmp.proto | 19 +++ common/intcombobox.h | 19 +++ common/ip4.cpp | 19 +++ common/ip4.h | 19 +++ common/ip4.proto | 19 +++ common/llc.cpp | 19 +++ common/llc.h | 19 +++ common/llc.proto | 19 +++ common/mac.cpp | 19 +++ common/mac.h | 19 +++ common/mac.proto | 19 +++ common/payload.cpp | 19 +++ common/payload.h | 19 +++ common/payload.proto | 19 +++ common/protocol.proto | 19 +++ common/protocollist.cpp | 19 +++ common/protocollist.h | 19 +++ common/protocollistiterator.cpp | 19 +++ common/protocollistiterator.h | 19 +++ common/protocolmanager.cpp | 19 +++ common/protocolmanager.h | 19 +++ common/sample.cpp | 19 +++ common/sample.h | 19 +++ common/sample.proto | 19 +++ common/snap.cpp | 19 +++ common/snap.h | 19 +++ common/snap.proto | 19 +++ common/streambase.cpp | 19 +++ common/streambase.h | 19 +++ common/svlan.cpp | 19 +++ common/svlan.h | 19 +++ common/svlan.proto | 19 +++ common/tcp.cpp | 19 +++ common/tcp.h | 19 +++ common/tcp.proto | 19 +++ common/udp.cpp | 19 +++ common/udp.h | 19 +++ common/udp.proto | 19 +++ common/userscript.cpp | 19 +++ common/userscript.h | 19 +++ common/userscript.proto | 19 +++ common/vlan.cpp | 19 +++ common/vlan.h | 19 +++ common/vlan.proto | 19 +++ common/vlanstack.h | 19 +++ common/vlanstack.proto | 19 +++ rpc/pbhelper.h | 19 +++ rpc/pbrpcchannel.cpp | 19 +++ rpc/pbrpcchannel.h | 19 +++ rpc/pbrpccommon.h | 19 +++ rpc/pbrpccontroller.h | 19 +++ rpc/rpcserver.cpp | 19 +++ rpc/rpcserver.h | 19 +++ server/abstractport.cpp | 19 +++ server/abstractport.h | 19 +++ server/drone.cpp | 19 +++ server/drone.h | 19 +++ server/drone_main.cpp | 19 +++ server/myservice.cpp | 19 +++ server/myservice.h | 19 +++ server/pcapextra.cpp | 19 +++ server/pcapextra.h | 19 +++ server/pcapport.cpp | 19 +++ server/pcapport.h | 19 +++ server/portmanager.cpp | 19 +++ server/portmanager.h | 19 +++ server/winpcapport.cpp | 19 +++ server/winpcapport.h | 19 +++ 122 files changed, 2434 insertions(+), 110 deletions(-) diff --git a/client/about.ui b/client/about.ui index 5dab03e..34cd66c 100644 --- a/client/about.ui +++ b/client/about.ui @@ -5,8 +5,8 @@ 0 0 - 456 - 303 + 500 + 327 @@ -16,119 +16,144 @@ - About + About Ostinato - - - QFrame::Box + + + 0 - - QFrame::Sunken - - - - - - - - - 0 - 0 - - - - - - - :/icons/logo.png - - - false - - - Qt::AlignCenter - - - - - - - - - Qt::Vertical - - - - 20 - 21 - - - - - - - - - - - :/icons/name.png - - - Qt::AlignCenter - - - - - - - Version/Revision Placeholder - - - Qt::AlignCenter - - - - - - - Copyright (c) 2007-2010 Srivats P. - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 21 - - - - - - - - - - - - Logo (c): Dhiman Sengupta + + + Ostinato + + + + + + + + + 0 + 0 + + + + + + + :/icons/logo.png + + + false + + + Qt::AlignCenter + + + + + + + + + Qt::Vertical + + + + 20 + 21 + + + + + + + + + + + :/icons/name.png + + + Qt::AlignCenter + + + + + + + Version/Revision Placeholder + + + Qt::AlignCenter + + + + + + + Copyright (c) 2007-2010 Srivats P. + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 21 + + + + + + + + + + + + Logo (c): Dhiman Sengupta Icons (c): Mark James (http://www.famfamfam.com/lab/icons/silk/) - - - Qt::AlignCenter - - - - + + + Qt::AlignCenter + + + + + + + + License + + + + + + <p>This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</p><p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</p><p>You should have received a copy of the GNU General Public License along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a></p> + + + Qt::RichText + + + Qt::AlignCenter + + + true + + + + + diff --git a/client/dumpview.cpp b/client/dumpview.cpp index 65584ee..fe99e01 100644 --- a/client/dumpview.cpp +++ b/client/dumpview.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "dumpview.h" //! \todo Enable Scrollbars diff --git a/client/dumpview.h b/client/dumpview.h index 6f7db2e..b170cd0 100644 --- a/client/dumpview.h +++ b/client/dumpview.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include // FIXME: High diff --git a/client/hexlineedit.cpp b/client/hexlineedit.cpp index 68d7dab..6150084 100644 --- a/client/hexlineedit.cpp +++ b/client/hexlineedit.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "hexlineedit.h" #include "qdebug.h" diff --git a/client/hexlineedit.h b/client/hexlineedit.h index 09f638a..20ad460 100644 --- a/client/hexlineedit.h +++ b/client/hexlineedit.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _HEXLINEEDIT #define _HEXLINEEDIT diff --git a/client/main.cpp b/client/main.cpp index 53b43a6..e927b60 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "mainwindow.h" #include diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 2cb07ae..2bd7655 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "mainwindow.h" #if 0 diff --git a/client/mainwindow.h b/client/mainwindow.h index 9ddd926..0d8f02f 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _MAIN_WINDOW_H #define _MAIN_WINDOW_H diff --git a/client/modeltest.cpp b/client/modeltest.cpp index 2598c58..4b3de1f 100644 --- a/client/modeltest.cpp +++ b/client/modeltest.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + /**************************************************************************** ** ** Copyright (C) 2007 Trolltech ASA. All rights reserved. diff --git a/client/modeltest.h b/client/modeltest.h index 38b6b2b..9b2d39f 100644 --- a/client/modeltest.h +++ b/client/modeltest.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + /**************************************************************************** ** ** Copyright (C) 2007 Trolltech ASA. All rights reserved. diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 11ed59d..b095c45 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include "packetmodel.h" diff --git a/client/packetmodel.h b/client/packetmodel.h index 4f3b542..08dcea9 100644 --- a/client/packetmodel.h +++ b/client/packetmodel.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PACKET_MODEL_H #define _PACKET_MODEL_H diff --git a/client/port.cpp b/client/port.cpp index 565af93..eda09f6 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/client/port.h b/client/port.h index 6e2e9d3..91f6d8a 100644 --- a/client/port.h +++ b/client/port.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PORT_H #define _PORT_H diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 7531ef6..c5a8a2b 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "portgroup.h" #include diff --git a/client/portgroup.h b/client/portgroup.h index 88e96f7..dbf831c 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PORT_GROUP_H #define _PORT_GROUP_H diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index 6d8a079..3d6a8be 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "portgrouplist.h" // TODO(LOW): Remove diff --git a/client/portgrouplist.h b/client/portgrouplist.h index e8d2433..3083c26 100644 --- a/client/portgrouplist.h +++ b/client/portgrouplist.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PORT_GROUP_LIST_H #define _PORT_GROUP_LIST_H diff --git a/client/portmodel.cpp b/client/portmodel.cpp index cb62664..1d13eda 100644 --- a/client/portmodel.cpp +++ b/client/portmodel.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "portmodel.h" #include "portgrouplist.h" diff --git a/client/portmodel.h b/client/portmodel.h index 566785c..2027f0b 100644 --- a/client/portmodel.h +++ b/client/portmodel.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PORT_MODEL_H #define _PORT_MODEL_H diff --git a/client/portstatsfilterdialog.cpp b/client/portstatsfilterdialog.cpp index 724ee40..457a7c8 100644 --- a/client/portstatsfilterdialog.cpp +++ b/client/portstatsfilterdialog.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "portstatsfilterdialog.h" PortStatsFilterDialog::PortStatsFilterDialog(QWidget *parent) diff --git a/client/portstatsfilterdialog.h b/client/portstatsfilterdialog.h index 28d94ed..7eea255 100644 --- a/client/portstatsfilterdialog.h +++ b/client/portstatsfilterdialog.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PORT_STATS_FILTER_DIALOG_H #define _PORT_STATS_FILTER_DIALOG_H diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 80241cf..5bfd33e 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "portstatsmodel.h" #include "portgrouplist.h" diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h index 0a2e3aa..d50508b 100644 --- a/client/portstatsmodel.h +++ b/client/portstatsmodel.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PORT_STATS_MODEL_H #define _PORT_STATS_MODEL_H diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index 9b8b224..035a23c 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "portstatswindow.h" #include "portstatsmodel.h" diff --git a/client/portstatswindow.h b/client/portstatswindow.h index b2ad6f2..39f9108 100644 --- a/client/portstatswindow.h +++ b/client/portstatswindow.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PORT_STATS_WINDOW_H #define _PORT_STATS_WINDOW_H diff --git a/client/portswindow.cpp b/client/portswindow.cpp index f3b4760..0ef8a15 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "portswindow.h" #include diff --git a/client/portswindow.h b/client/portswindow.h index 6389887..607c40a 100644 --- a/client/portswindow.h +++ b/client/portswindow.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PORTS_WINDOW_H #define _PORTS_WINDOW_H diff --git a/client/stream.cpp b/client/stream.cpp index 7d21b14..a24c971 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/client/stream.h b/client/stream.h index de7508d..213af70 100644 --- a/client/stream.h +++ b/client/stream.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _STREAM_H #define _STREAM_H diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 41c9732..dd02697 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include "streamconfigdialog.h" diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 0961767..637bc9c 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _STREAM_CONFIG_DIALOG_H #define _STREAM_CONFIG_DIALOG_H diff --git a/client/streamlistdelegate.cpp b/client/streamlistdelegate.cpp index f701c13..f15bc18 100644 --- a/client/streamlistdelegate.cpp +++ b/client/streamlistdelegate.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include #include diff --git a/client/streamlistdelegate.h b/client/streamlistdelegate.h index 6a52aaa..a98a34e 100644 --- a/client/streamlistdelegate.h +++ b/client/streamlistdelegate.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef STREAM_LIST_DELEGATE_H #define STREAM_LIST_DELEGATE_H diff --git a/client/streammodel.cpp b/client/streammodel.cpp index 76735d0..5c57cdb 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "stream.h" #include "streammodel.h" #include "portgrouplist.h" diff --git a/client/streammodel.h b/client/streammodel.h index e73bb18..b0b41d2 100644 --- a/client/streammodel.h +++ b/client/streammodel.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _STREAM_MODEL_H #define _STREAM_MODEL_H diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index f66dfdd..750a26b 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include "abstractprotocol.h" diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index fb6a703..9d12dd2 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _ABSTRACT_PROTOCOL_H #define _ABSTRACT_PROTOCOL_H diff --git a/common/arp.cpp b/common/arp.cpp index 5fb146b..7548c62 100644 --- a/common/arp.cpp +++ b/common/arp.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/arp.h b/common/arp.h index 6f6c256..677b73a 100644 --- a/common/arp.h +++ b/common/arp.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _ARP_H #define _ARP_H diff --git a/common/arp.proto b/common/arp.proto index 9491a6c..9a4bd52 100644 --- a/common/arp.proto +++ b/common/arp.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/comboprotocol.h b/common/comboprotocol.h index 9d10348..c6efa0a 100644 --- a/common/comboprotocol.h +++ b/common/comboprotocol.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _COMBO_PROTOCOL_H #define _COMBO_PROTOCOL_H diff --git a/common/dot2llc.h b/common/dot2llc.h index 44f6a3b..b858914 100644 --- a/common/dot2llc.h +++ b/common/dot2llc.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _DOT2_LLC_H #define _DOT2_LLC_H diff --git a/common/dot2llc.proto b/common/dot2llc.proto index 51eb756..08e857c 100644 --- a/common/dot2llc.proto +++ b/common/dot2llc.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; import "dot3.proto"; import "llc.proto"; diff --git a/common/dot2snap.h b/common/dot2snap.h index 2ad3ead..0da586a 100644 --- a/common/dot2snap.h +++ b/common/dot2snap.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _DOT2_SNAP_H #define _DOT2_SNAP_H diff --git a/common/dot2snap.proto b/common/dot2snap.proto index ce41b8f..3af4261 100644 --- a/common/dot2snap.proto +++ b/common/dot2snap.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/dot3.cpp b/common/dot3.cpp index 1c16f40..adbe5d5 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/dot3.h b/common/dot3.h index 925374a..8a0d5c2 100644 --- a/common/dot3.h +++ b/common/dot3.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _DOT3_H #define _DOT3_H diff --git a/common/dot3.proto b/common/dot3.proto index 154f554..e3f4344 100644 --- a/common/dot3.proto +++ b/common/dot3.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/eth2.cpp b/common/eth2.cpp index 2939fed..dd85063 100644 --- a/common/eth2.cpp +++ b/common/eth2.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/eth2.h b/common/eth2.h index cae1bb3..dcb8a7a 100644 --- a/common/eth2.h +++ b/common/eth2.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _ETH2_H #define _ETH2_H diff --git a/common/eth2.proto b/common/eth2.proto index c5339a9..e0c52a2 100644 --- a/common/eth2.proto +++ b/common/eth2.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/icmp.cpp b/common/icmp.cpp index 32d0fb5..0c03700 100644 --- a/common/icmp.cpp +++ b/common/icmp.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include "icmp.h" diff --git a/common/icmp.h b/common/icmp.h index 3a9fba6..0d6f218 100644 --- a/common/icmp.h +++ b/common/icmp.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _ICMP_H #define _ICMP_H diff --git a/common/icmp.proto b/common/icmp.proto index 72dcd38..f48e9a7 100644 --- a/common/icmp.proto +++ b/common/icmp.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/intcombobox.h b/common/intcombobox.h index ca62511..7da3351 100644 --- a/common/intcombobox.h +++ b/common/intcombobox.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef __INT_COMBO_BOX #define __INT_COMBO_BOX diff --git a/common/ip4.cpp b/common/ip4.cpp index c2594f3..f3bb887 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/ip4.h b/common/ip4.h index a9a40b9..ab7b3de 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _IPV4_H #define _IPV4_H diff --git a/common/ip4.proto b/common/ip4.proto index ffdfcae..9914977 100644 --- a/common/ip4.proto +++ b/common/ip4.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/llc.cpp b/common/llc.cpp index 5a5f1d2..76e8e46 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/llc.h b/common/llc.h index 5de0b72..2cc9fe8 100644 --- a/common/llc.h +++ b/common/llc.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _LLC_H #define _LLC_H diff --git a/common/llc.proto b/common/llc.proto index c1966ab..1bb6324 100644 --- a/common/llc.proto +++ b/common/llc.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/mac.cpp b/common/mac.cpp index 30f0ec2..706931a 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/mac.h b/common/mac.h index 242ce2a..48d0e35 100644 --- a/common/mac.h +++ b/common/mac.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _MAC_H #define _MAC_H diff --git a/common/mac.proto b/common/mac.proto index 642f725..475590d 100644 --- a/common/mac.proto +++ b/common/mac.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/payload.cpp b/common/payload.cpp index 292c0c5..2c6c267 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/payload.h b/common/payload.h index d468a16..2fd32d2 100644 --- a/common/payload.h +++ b/common/payload.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PAYLOAD_H #define _PAYLOAD_H diff --git a/common/payload.proto b/common/payload.proto index 0cbc878..02cfc04 100644 --- a/common/payload.proto +++ b/common/payload.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/protocol.proto b/common/protocol.proto index d1205f7..4bd5899 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + package OstProto; message StreamId { diff --git a/common/protocollist.cpp b/common/protocollist.cpp index 08ff40a..1b3397c 100644 --- a/common/protocollist.cpp +++ b/common/protocollist.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "protocollist.h" #include "abstractprotocol.h" diff --git a/common/protocollist.h b/common/protocollist.h index d760f14..62df3c9 100644 --- a/common/protocollist.h +++ b/common/protocollist.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include class AbstractProtocol; diff --git a/common/protocollistiterator.cpp b/common/protocollistiterator.cpp index 242d8d9..a081365 100644 --- a/common/protocollistiterator.cpp +++ b/common/protocollistiterator.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "protocollistiterator.h" #include "protocollist.h" #include "abstractprotocol.h" diff --git a/common/protocollistiterator.h b/common/protocollistiterator.h index 463dae9..6baa39f 100644 --- a/common/protocollistiterator.h +++ b/common/protocollistiterator.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include class AbstractProtocol; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index f65c9b2..130e5ce 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "protocolmanager.h" #include "abstractprotocol.h" diff --git a/common/protocolmanager.h b/common/protocolmanager.h index c80315e..ac64919 100644 --- a/common/protocolmanager.h +++ b/common/protocolmanager.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PROTOCOL_MANAGER_H #define _PROTOCOL_MANAGER_H diff --git a/common/sample.cpp b/common/sample.cpp index a37ba49..4d601bf 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include "sample.h" diff --git a/common/sample.h b/common/sample.h index 443d8c3..b92152b 100644 --- a/common/sample.h +++ b/common/sample.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _SAMPLE_H #define _SAMPLE_H diff --git a/common/sample.proto b/common/sample.proto index 16d4daf..6d74304 100644 --- a/common/sample.proto +++ b/common/sample.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/snap.cpp b/common/snap.cpp index cfabc1b..6803253 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/snap.h b/common/snap.h index 42eae0c..2e60b84 100644 --- a/common/snap.h +++ b/common/snap.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _SNAP_H #define _SNAP_H diff --git a/common/snap.proto b/common/snap.proto index 7ac3254..bf54803 100644 --- a/common/snap.proto +++ b/common/snap.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/streambase.cpp b/common/streambase.cpp index a09093b..109252c 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "streambase.h" #include "abstractprotocol.h" #include "protocollist.h" diff --git a/common/streambase.h b/common/streambase.h index 5b40b1d..61964c6 100644 --- a/common/streambase.h +++ b/common/streambase.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _STREAM_BASE_H #define _STREAM_BASE_H diff --git a/common/svlan.cpp b/common/svlan.cpp index 6d30cfc..893671d 100644 --- a/common/svlan.cpp +++ b/common/svlan.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include "svlan.h" diff --git a/common/svlan.h b/common/svlan.h index 3c7d673..7ba051b 100644 --- a/common/svlan.h +++ b/common/svlan.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _SVLAN_H #define _SVLAN_H diff --git a/common/svlan.proto b/common/svlan.proto index 42f45bc..aa02f70 100644 --- a/common/svlan.proto +++ b/common/svlan.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; import "vlan.proto"; diff --git a/common/tcp.cpp b/common/tcp.cpp index 7a66347..9c44ec0 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/tcp.h b/common/tcp.h index 8ef7ebf..3b32b35 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _TCP_H #define _TCP_H diff --git a/common/tcp.proto b/common/tcp.proto index 05dd181..39d96be 100644 --- a/common/tcp.proto +++ b/common/tcp.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/udp.cpp b/common/udp.cpp index b755310..7bb74e3 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include diff --git a/common/udp.h b/common/udp.h index 652c03a..86c2ca8 100644 --- a/common/udp.h +++ b/common/udp.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _UDP_H #define _UDP_H diff --git a/common/udp.proto b/common/udp.proto index 23ed43e..5c30eac 100644 --- a/common/udp.proto +++ b/common/udp.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/userscript.cpp b/common/userscript.cpp index ba26c72..fa084f1 100644 --- a/common/userscript.cpp +++ b/common/userscript.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "userscript.h" #include diff --git a/common/userscript.h b/common/userscript.h index 3f51142..4ef0d91 100644 --- a/common/userscript.h +++ b/common/userscript.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _USER_SCRIPT_H #define _USER_SCRIPT_H diff --git a/common/userscript.proto b/common/userscript.proto index aaf2621..484223f 100644 --- a/common/userscript.proto +++ b/common/userscript.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/vlan.cpp b/common/vlan.cpp index 5abee7d..2946068 100644 --- a/common/vlan.cpp +++ b/common/vlan.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include #include "vlan.h" diff --git a/common/vlan.h b/common/vlan.h index f276ce5..728572b 100644 --- a/common/vlan.h +++ b/common/vlan.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _Vlan_H #define _Vlan_H diff --git a/common/vlan.proto b/common/vlan.proto index a963444..802627c 100644 --- a/common/vlan.proto +++ b/common/vlan.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/common/vlanstack.h b/common/vlanstack.h index 4b24464..847ac3d 100644 --- a/common/vlanstack.h +++ b/common/vlanstack.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _VLAN_STACK_H #define _VLAN_STACK_H diff --git a/common/vlanstack.proto b/common/vlanstack.proto index 4e6e9a0..203f3ef 100644 --- a/common/vlanstack.proto +++ b/common/vlanstack.proto @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + import "protocol.proto"; package OstProto; diff --git a/rpc/pbhelper.h b/rpc/pbhelper.h index e87d4ca..7ab80b3 100644 --- a/rpc/pbhelper.h +++ b/rpc/pbhelper.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PB_HELPER_H #define _PB_HELPER_H diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index 9b5997f..521aca5 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "pbrpcchannel.h" PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) diff --git a/rpc/pbrpcchannel.h b/rpc/pbrpcchannel.h index 8c2efbc..682c553 100644 --- a/rpc/pbrpcchannel.h +++ b/rpc/pbrpcchannel.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PB_RPC_CHANNEL_H #define _PB_RPC_CHANNEL_H diff --git a/rpc/pbrpccommon.h b/rpc/pbrpccommon.h index 12040ee..5cbbb57 100644 --- a/rpc/pbrpccommon.h +++ b/rpc/pbrpccommon.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PB_RPC_COMMON_H #define _PB_RPC_COMMON_H diff --git a/rpc/pbrpccontroller.h b/rpc/pbrpccontroller.h index 50260d7..fa11cdd 100644 --- a/rpc/pbrpccontroller.h +++ b/rpc/pbrpccontroller.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PB_RPC_CONTROLLER_H #define _PB_RPC_CONTROLLER_H diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index 36d96e9..5d67833 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + //#include "pbhelper.h" #include "rpcserver.h" diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h index 0872373..1e9c93e 100644 --- a/rpc/rpcserver.h +++ b/rpc/rpcserver.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _RPC_SERVER_H #define _RPC_SERVER_H diff --git a/server/abstractport.cpp b/server/abstractport.cpp index 7d2c0cf..70d833f 100644 --- a/server/abstractport.cpp +++ b/server/abstractport.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "abstractport.h" #include diff --git a/server/abstractport.h b/server/abstractport.h index ba13d25..4b036fa 100644 --- a/server/abstractport.h +++ b/server/abstractport.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _SERVER_ABSTRACT_PORT_H #define _SERVER_ABSTRACT_PORT_H diff --git a/server/drone.cpp b/server/drone.cpp index 7f84033..8206ac2 100644 --- a/server/drone.cpp +++ b/server/drone.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "drone.h" #include "rpcserver.h" diff --git a/server/drone.h b/server/drone.h index c8d9ff2..7466a76 100644 --- a/server/drone.h +++ b/server/drone.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _DRONE_H #define _DRONE_H diff --git a/server/drone_main.cpp b/server/drone_main.cpp index 0bac7c1..722f5c0 100644 --- a/server/drone_main.cpp +++ b/server/drone_main.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "drone.h" int myport; diff --git a/server/myservice.cpp b/server/myservice.cpp index 3699cfd..424a95a 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "myservice.h" diff --git a/server/myservice.h b/server/myservice.h index b292151..09cb479 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _MY_SERVICE_H #define _MY_SERVICE_H diff --git a/server/pcapextra.cpp b/server/pcapextra.cpp index b4fdba7..4acbda9 100644 --- a/server/pcapextra.cpp +++ b/server/pcapextra.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "pcapextra.h" #include // memcpy() diff --git a/server/pcapextra.h b/server/pcapextra.h index de4cec1..415fe3e 100644 --- a/server/pcapextra.h +++ b/server/pcapextra.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _PCAP_EXTRA_H #define _PCAP_EXTRA_H diff --git a/server/pcapport.cpp b/server/pcapport.cpp index 96a33b6..f9412cf 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "pcapport.h" #include diff --git a/server/pcapport.h b/server/pcapport.h index 5a1ef3f..0001b0a 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _SERVER_PCAP_PORT_H #define _SERVER_PCAP_PORT_H diff --git a/server/portmanager.cpp b/server/portmanager.cpp index bec541f..b4f7572 100644 --- a/server/portmanager.cpp +++ b/server/portmanager.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "portmanager.h" #include diff --git a/server/portmanager.h b/server/portmanager.h index 1d4bd73..2407bf2 100644 --- a/server/portmanager.h +++ b/server/portmanager.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _SERVER_PORT_MANAGER_H #define _SERVER_PORT_MANAGER_H diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp index 2e23aac..3f38a15 100644 --- a/server/winpcapport.cpp +++ b/server/winpcapport.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #include "winpcapport.h" #include diff --git a/server/winpcapport.h b/server/winpcapport.h index dc0c84d..5ab2f9b 100644 --- a/server/winpcapport.h +++ b/server/winpcapport.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + #ifndef _SERVER_WIN_PCAP_PORT_H #define _SERVER_WIN_PCAP_PORT_H From 6d4be4272b2507379ae7447950a81a8f8f1e0da1 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 27 Mar 2010 18:44:18 +0000 Subject: [PATCH 54/98] - Removed Copyright notice from client/modeltest.* files which are Trolltech provided and carry a Trolltech copyright notice - Added the GPLv3 license text - COPYING --- COPYING | 674 +++++++++++++++++++++++++++++++++++++++++++ client/modeltest.cpp | 19 -- client/modeltest.h | 19 -- 3 files changed, 674 insertions(+), 38 deletions(-) create mode 100644 COPYING diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/client/modeltest.cpp b/client/modeltest.cpp index 4b3de1f..2598c58 100644 --- a/client/modeltest.cpp +++ b/client/modeltest.cpp @@ -1,22 +1,3 @@ -/* -Copyright (C) 2010 Srivats P. - -This file is part of "Ostinato" - -This is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see -*/ - /**************************************************************************** ** ** Copyright (C) 2007 Trolltech ASA. All rights reserved. diff --git a/client/modeltest.h b/client/modeltest.h index 9b2d39f..38b6b2b 100644 --- a/client/modeltest.h +++ b/client/modeltest.h @@ -1,22 +1,3 @@ -/* -Copyright (C) 2010 Srivats P. - -This file is part of "Ostinato" - -This is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see -*/ - /**************************************************************************** ** ** Copyright (C) 2007 Trolltech ASA. All rights reserved. From 1cfc771daa5968769c48298b81b244c4e0fa8213 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 3 Apr 2010 08:18:29 +0000 Subject: [PATCH 55/98] - Added Preferences Dialog - Wireshark path can be configured by user in the preferences - Support for portable mode for preferences (.ini in same location as the executable) --- client/icons/preferences.png | Bin 0 -> 584 bytes client/main.cpp | 16 +++++ client/mainwindow.cpp | 10 +++ client/mainwindow.h | 1 + client/mainwindow.ui | 13 +++- client/ostinato.pro | 4 ++ client/ostinato.qrc | 1 + client/portgroup.cpp | 19 ++++-- client/preferences.cpp | 56 +++++++++++++++++ client/preferences.h | 41 +++++++++++++ client/preferences.ui | 114 +++++++++++++++++++++++++++++++++++ client/settings.h | 38 ++++++++++++ 12 files changed, 307 insertions(+), 6 deletions(-) create mode 100644 client/icons/preferences.png create mode 100644 client/preferences.cpp create mode 100644 client/preferences.h create mode 100644 client/preferences.ui create mode 100644 client/settings.h diff --git a/client/icons/preferences.png b/client/icons/preferences.png new file mode 100644 index 0000000000000000000000000000000000000000..565a9330e0a156dff5bed2c9fad8c95a44344ba4 GIT binary patch literal 584 zcmV-O0=NB%P)g}f4o)2%U3C;eEDoiEh?94d(rV57VIF#8VqzW$HrDC|#U`x@QDbgi zVl)t9GGz&YY#D?gc%>hISA+_EBpnXt#pnC`p6@xw0$8TCbULjhlgVx(kuc)%xbgqq zR5+DNDFRN0!y)7Gm}oT0i39}h4h928qY?Rho^UvPGJ#kuW|-Amtrn`Pmd&+bFo@sp z$LI4IQw7BG?|#2ewOS<<3VjL$0=lMY^m;wqZujv5kx1l%Sl;V&Iy4#$ip3&@LV2!7vhhN=PCz%^9v24`qb(+m4W?!q-&~=?ssf5GfnAmJKV;3bvpDm0(NhahZ=&^sqo6Odj6>)Dq_3p~4~ zvb`d3Mydwjt&Df^hVmLtI2x=U&h9(JVYX-!y~z3zi;1>=LY;o(bL$(Yf$lf)dMf0-u^0HrpTG Wk@)HE*94aU0000 #include "mainwindow.h" #include +#include +#include + +QSettings *appSettings; QMainWindow *mainWindow; @@ -28,9 +32,21 @@ int main(int argc, char* argv[]) QApplication app(argc, argv); int exitCode; + /* (Portable Mode) If we have a .ini file in the same directory as the + executable, we use that instead of the platform specific location + and format for the settings */ + QString portableIni = QCoreApplication::applicationDirPath() + + "/ostinato.ini"; + if (QFile::exists(portableIni)) + appSettings = new QSettings(portableIni, QSettings::IniFormat); + else + appSettings = new QSettings("Ostinato", "Ostinato"); + mainWindow = new MainWindow; mainWindow->show(); exitCode = app.exec(); delete mainWindow; + delete appSettings; + return exitCode; } diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 2bd7655..b7d4145 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -26,6 +26,7 @@ along with this program. If not, see #include "portgrouplist.h" #include "portstatswindow.h" #include "portswindow.h" +#include "preferences.h" #include "ui_about.h" #include @@ -74,6 +75,15 @@ MainWindow::~MainWindow() delete localServer_; } +void MainWindow::on_actionPreferences_triggered() +{ + Preferences *preferences = new Preferences(); + + preferences->exec(); + + delete preferences; +} + void MainWindow::on_actionHelpAbout_triggered() { QDialog *aboutDialog = new QDialog; diff --git a/client/mainwindow.h b/client/mainwindow.h index 0d8f02f..2f2602d 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -45,6 +45,7 @@ public: ~MainWindow(); public slots: + void on_actionPreferences_triggered(); void on_actionHelpAbout_triggered(); }; diff --git a/client/mainwindow.ui b/client/mainwindow.ui index 1f93f5e..93b57e4 100644 --- a/client/mainwindow.ui +++ b/client/mainwindow.ui @@ -26,6 +26,7 @@ File + @@ -48,7 +49,17 @@ &About + + + :/icons/preferences.png + + + Preferences + + - + + + diff --git a/client/ostinato.pro b/client/ostinato.pro index 2738df9..853ca5c 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -37,6 +37,8 @@ HEADERS += \ portstatsfilterdialog.h \ portstatswindow.h \ portswindow.h \ + preferences.h \ + settings.h \ streamconfigdialog.h \ streamlistdelegate.h \ streammodel.h @@ -47,6 +49,7 @@ FORMS += \ portstatsfilter.ui \ portstatswindow.ui \ portswindow.ui \ + preferences.ui \ streamconfigdialog.ui SOURCES += \ @@ -64,6 +67,7 @@ SOURCES += \ portstatsfilterdialog.cpp \ portstatswindow.cpp \ portswindow.cpp \ + preferences.cpp \ streamconfigdialog.cpp \ streamlistdelegate.cpp \ streammodel.cpp diff --git a/client/ostinato.qrc b/client/ostinato.qrc index cb71e4c..5008ee9 100644 --- a/client/ostinato.qrc +++ b/client/ostinato.qrc @@ -24,6 +24,7 @@ icons/portstats_clear.png icons/portstats_clear_all.png icons/portstats_filter.png + icons/preferences.png icons/sound_mute.png icons/sound_none.png icons/stream_add.png diff --git a/client/portgroup.cpp b/client/portgroup.cpp index c5a8a2b..8e2597f 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -19,9 +19,12 @@ along with this program. If not, see #include "portgroup.h" +#include "settings.h" + #include #include #include +#include #include #include #include @@ -661,20 +664,26 @@ void PortGroup::processViewCaptureAck(PbRpcController *controller) { QFile *capFile = static_cast(controller->binaryBlob()); -#ifdef Q_OS_WIN32 - QString viewer("C:/Program Files/Wireshark/wireshark.exe"); -#else - QString viewer("/usr/bin/wireshark"); -#endif + QString viewer = appSettings->value(kWiresharkPathKey, + kWiresharkPathDefaultValue).toString(); qDebug("In %s", __FUNCTION__); capFile->flush(); capFile->close(); + if (!QFile::exists(viewer)) + { + QMessageBox::warning(NULL, "Can't find Wireshark", + viewer + QString(" does not exist!\n\nPlease correct the path" + " to Wireshark in the Preferences.")); + goto _exit; + } + if (!QProcess::startDetached(viewer, QStringList() << capFile->fileName())) qDebug("Failed starting Wireshark"); +_exit: delete controller; } diff --git a/client/preferences.cpp b/client/preferences.cpp new file mode 100644 index 0000000..4f372ee --- /dev/null +++ b/client/preferences.cpp @@ -0,0 +1,56 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#include "preferences.h" + +#include "settings.h" + +#include + +Preferences::Preferences() +{ + Q_ASSERT(appSettings); + + setupUi(this); + + wiresharkPathEdit->setText(appSettings->value(kWiresharkPathKey, + kWiresharkPathDefaultValue).toString()); +} + +Preferences::~Preferences() +{ +} + +void Preferences::accept() +{ + appSettings->setValue(kWiresharkPathKey, wiresharkPathEdit->text()); + + QDialog::accept(); +} + +void Preferences::on_wiresharkPathButton_clicked() +{ + QString path; + + path = QFileDialog::getOpenFileName(0, "Locate Wireshark", + wiresharkPathEdit->text()); + + if (!path.isEmpty()) + wiresharkPathEdit->setText(path); +} diff --git a/client/preferences.h b/client/preferences.h new file mode 100644 index 0000000..0bb2af4 --- /dev/null +++ b/client/preferences.h @@ -0,0 +1,41 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _PREFERENCES_H +#define _PREFERENCES_H + +#include "ui_preferences.h" + +#include + +class Preferences : public QDialog, public Ui::Preferences +{ + Q_OBJECT +public: + Preferences(); + ~Preferences(); + +public slots: + void accept(); + +private slots: + void on_wiresharkPathButton_clicked(); +}; + +#endif diff --git a/client/preferences.ui b/client/preferences.ui new file mode 100644 index 0000000..514ed42 --- /dev/null +++ b/client/preferences.ui @@ -0,0 +1,114 @@ + + Preferences + + + + 0 + 0 + 400 + 164 + + + + Preferences + + + :/icons/preferences.png + + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + + + Wireshark Path + + + + + + + + + + ... + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + Preferences + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Preferences + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/client/settings.h b/client/settings.h new file mode 100644 index 0000000..fa22e54 --- /dev/null +++ b/client/settings.h @@ -0,0 +1,38 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _SETTINGS_H +#define _SETTINGS_H + +#include +#include + +extern QSettings *appSettings; + +const QString kWiresharkPathKey("WiresharkPath"); +#ifdef Q_OS_WIN32 +const QString kWiresharkPathDefaultValue( + "C:/Program Files/Wireshark/wireshark.exe"); +#else +const QString kWiresharkPathDefaultValue("/usr/bin/wireshark"); +#endif + +#endif + + From c630d4c29161ecb3be56bf570e675c34099d227b Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 4 Apr 2010 08:15:39 +0000 Subject: [PATCH 56/98] - Added icons to some menu items - Fix: Changed Preferences to inherit privately from Ui::Preferences - Added "About Qt" to Help Menu - Added the PortList/StreamList actions to File Menu - Fix: "New Stream" action is enabled only when a port is selected in the port list - Fix: Ostinato now looks for Drone in the correct path --- client/icons/about.png | Bin 0 -> 1036 bytes client/icons/exit.png | Bin 0 -> 688 bytes client/icons/qt.png | Bin 0 -> 2037 bytes client/mainwindow.cpp | 17 ++++++++++++++--- client/mainwindow.ui | 16 ++++++++++++++++ client/ostinato.qrc | 3 +++ client/portswindow.cpp | 11 ++++++++++- client/portswindow.ui | 2 +- client/preferences.h | 2 +- 9 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 client/icons/about.png create mode 100644 client/icons/exit.png create mode 100644 client/icons/qt.png diff --git a/client/icons/about.png b/client/icons/about.png new file mode 100644 index 0000000000000000000000000000000000000000..95fb35e1202dcf7f5c61ede0162a23f03f1eee66 GIT binary patch literal 1036 zcmV+n1oQieP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igP# z2LJ>Iv3BAB00WFkL_t(o!@XD0apO7+gx=i0*nyY|%nn3%pi~fc5TygA1EmAGf>0HN zsUUU-EJ1ESdp`#bMN_hG=H_8W9~5P92`m;cbzKJ{f>H|C>lOEGo@XefAcQ~&0RV8h zT%ff^RaNlbgNQ&xnCBVJIS>(~ltq680EfdNf_TJ22&n5CUDp8sgb*Mi2qECThf)ee z1n1mp|9n1|0nGCZDJ6&qFE1|-fw0y_r+j0+#Ov!ThzQnN0Dv(DM1)}&$^Zc1d_G5{ zec#^&aJ^npRTYL|h+qzf1Dta)>{@F8z&MVpbrC=gVjM>Rz_KixAe2(jT4Pz3cw^?& z)-%uZHh>&NDQBr^t)aEX=jUfUKx-W%LPYT1$B6KL3W7?GIb=eJ8^k$)^mZII0P$VE zZkh(hn0){MFbu&<{Fe4Y%UQe-#tA& z-K0$j0p}c~ln_Dyz)BsRb7-0-iWu|z6etv#9 zHILOShm;jFWpatYRaF&zYOPo0T?CM_G_Q(#hXaUWWUXEGhSKlI7!yk-1;A`&#-{tu zxlM%(A;j-O2$3(ju<`F>Gb$aF67qC9#oTj~*=thVSvhiCb~$h=sT-5Wd%r@>WGn$# zmIceQ#7l75=Ih*kQNe@|)V3{c*&pt#tg0$HolX=&ARz>GT}SWl@2hpm{+p(W9yRA2 z5fL4a$Kt-VmWYV@z9%B0VHo1NuIsW>DdkPMwQXCJULnNhXvNCdG|j3K?oC<5AMt$0 zQk>>Cgm5!v<>2bNj^dTK<6QvGxmYH~7)U9hl*0G-H@?2UqKdJ^?zLrWZH&a$2(~#B z=5m=n#u!{Km)(wOj9DFiPppb%$Rjrk(Z|Qf%|OEC1^{nwZy+LcUAI!oM+aK~pb)}J z9C8k9&4nDX=jZ3uWb{bbR{-j|#xza40P>lU33)soBY$`@$^oYl+pGe1FbqSSbV~>4 zGa!@GT3ehQ?;Q>R)gMPUN~n~I>ktBk5N`Int|Md2w#YnU0N|WM-}jr%h;OR3#yF0< zlk(phrQu5dRP6EKU)rh+r)i2&*b<$;$?qdpq14*`NBa#<`c}ZkF07dV0000GS2eE@_I zS~TaE^z1tT1me$mOd>fuB1*9ukjYHe@2!~sjG5tP)N7xSr3G9P+3oKa++V)SLaGru zn`QvjgqvWRa7{oUyOUDA37GDE%9f3r>9Muk`Z$59p<W>iYj7vxikNWw_8sK+%_fnobvCa5%KNOO6e%CReDLPLmVwdHp%H5J z8cVW-n2=oPDz8D+5J{LSmLlCXMPg`l3MX6KVJNMw&n~!g&9zA<=CHFVyLz1l^k+DTiboyDIuKD~MJE&R)Oo;bO6gPHCylVLL*a<{&sTsdkI7k&ZU WO{4dBd(FK700004HU6=o70{GE1?O|XyFbE6*6TqM+SpA<0`0%^BR|UWRofmqx&W?zi zrw2u5_Pi(#9R{2 z(GaRElJdruSs2^MyJlwMeY-ecki)*r-#wXGf6QILHXsR{1_nG)6<|?dzu7X6-K%)8UStstZSg@8U|izTH`%Pl`y0S^iqG){d1s2hX` zP|iC{PgkkbY|s@gVU51NR(g^h*wRGd0Fu7Wc1l%+pSyZvYc|HB$xVCKK1pBV3ewdz z9id>G?g<1hBcS)9=-o92XdYFq$3)t+5wOj|n=vB-h^%YK@STQiuAN17zkgzy63vcir!BccYXSc93Od&Evr98 zxE1^vqq8VNI$lYXROsjop0Fs-#%VPYh?+)c+~n5JhuHJwD0}usxO%;gQww6)NzNPv zR|T0EuJWg+Q*2yuQ)e=^w)5WGAK{IW{Tw^@2NK;80&OTE>k4q11Z-*JNP%)CN+?G9 zTWD|VMwrl3gj-#%+b(g;0JU^4xs=Phhf}o9-#{X=I&#~NyGiuM zIezA4l8NO+Vg`w2vGDSqwXML4W&y`UNDJ2$j1Sf^R41AWQnxZ}zFAVNm#En_G#pO7 zE;;(Q5JK9-`wB!t38sb&(y0ogqmvAc^s{_JoEVTeDlG_(ZVJ-Y}uN8c<&P% zfZa_3rc=R|b);)j$~ia!a+v}hS7s=iB`l|gp$pzRP$M(iOHhw+^34)mtMcTtB?>8n zHP=RHiPtb?-Kxq|AzvG-6bjRrZjQEC081;>hG*W*0q2_p>Y|J-D>$mk2Peu@=Bs4V zIof+GSaKd+H#zz0JTo7}LFp7L<81#zmDrV4#>b`@8!EG5dzhUM*_6d__PbBr`^GcR z{%B5~I*Wo=<8KsNss0}2sW0ER-kNB;bEZA*5vEju0>J%cIwHOtX~(&lPy&X9*4;%Cml_!IoPhC@0T{$2)0{ z#wnM}+`bE6fd7!dztFHKI?X}3ZbQH^B-`(7bOC^4ufXqqn&!q`?SzZ~($Yxu(fGVn zDtQ7Wa&tCIWN879kE0YdVRP&KZ6w!K8W68#oI2w2{kv0q>y}Br;nj;jFJqb}*=)v> zC^IrpUwq$K`c8QHE+{O=p;WK)z>i}b{8fn~FO@M2V?o3#P)d4mi#3}=eDw!C?0BZ~nbN1*rR@SX$sx7bG;Q1CG9Dm2)$q z2#oolVc;ZC@`0ugls<6D1U$2nH`Cu{XXJ8V>+G<|deHjt2}_setProcessChannelMode(QProcess::ForwardedChannels); - localServer_->start("./drone.exe"); + localServer_->start(serverApp); pgl = new PortGroupList; portsWindow = new PortsWindow(pgl, this); statsWindow = new PortStatsWindow(pgl, this); - portsDock = new QDockWidget(tr("Ports"), this); - statsDock = new QDockWidget(tr("Stats"), this); + portsDock = new QDockWidget(tr("Ports and Streams"), this); + statsDock = new QDockWidget(tr("Statistics"), this); setupUi(this); + menuFile->insertActions(menuFile->actions().at(0), portsWindow->actions()); + statsDock->setWidget(statsWindow); addDockWidget(Qt::BottomDockWidgetArea, statsDock); portsDock->setWidget(portsWindow); addDockWidget(Qt::TopDockWidgetArea, portsDock); connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close())); + connect(actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt())); #if 0 { DbgThread *dbg = new DbgThread(pgl); diff --git a/client/mainwindow.ui b/client/mainwindow.ui index 93b57e4..28861d4 100644 --- a/client/mainwindow.ui +++ b/client/mainwindow.ui @@ -26,6 +26,7 @@ File + @@ -34,17 +35,24 @@ Help + + + :/icons/exit.png + E&xit + + :/icons/about.png + &About @@ -57,6 +65,14 @@ Preferences + + + :/icons/qt.png + + + About Qt + + diff --git a/client/ostinato.qrc b/client/ostinato.qrc index 5008ee9..bd88fd1 100644 --- a/client/ostinato.qrc +++ b/client/ostinato.qrc @@ -1,5 +1,6 @@ + icons/about.png icons/arrow_down.png icons/arrow_left.png icons/arrow_right.png @@ -14,6 +15,7 @@ icons/control_stop.png icons/deco_exclusive.png icons/delete.png + icons/exit.png icons/logo.png icons/magnifier.png icons/name.png @@ -25,6 +27,7 @@ icons/portstats_clear_all.png icons/portstats_filter.png icons/preferences.png + icons/qt.png icons/sound_mute.png icons/sound_none.png icons/stream_add.png diff --git a/client/portswindow.cpp b/client/portswindow.cpp index 0ef8a15..e0ad61e 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -55,6 +55,12 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) tvStreamList->addAction(actionEdit_Stream); tvStreamList->addAction(actionDelete_Stream); + addActions(tvPortList->actions()); + QAction *sep = new QAction(this); + sep->setSeparator(true); + addAction(sep); + addActions(tvStreamList->actions()); + tvStreamList->setModel(plm->getStreamModel()); tvPortList->setModel(plm->getPortModel()); @@ -220,7 +226,10 @@ void PortsWindow::updateStreamViewActions() else { qDebug("No selection"); - actionNew_Stream->setEnabled(true); + if (plm->isPort(tvPortList->currentIndex())) + actionNew_Stream->setEnabled(true); + else + actionNew_Stream->setDisabled(true); actionEdit_Stream->setDisabled(true); actionDelete_Stream->setDisabled(true); } diff --git a/client/portswindow.ui b/client/portswindow.ui index 17361d4..3032b79 100644 --- a/client/portswindow.ui +++ b/client/portswindow.ui @@ -227,7 +227,7 @@ true - Exclusive Control (EXPERIMENTAL) + Exclusive Port Control (EXPERIMENTAL) diff --git a/client/preferences.h b/client/preferences.h index 0bb2af4..1821346 100644 --- a/client/preferences.h +++ b/client/preferences.h @@ -24,7 +24,7 @@ along with this program. If not, see #include -class Preferences : public QDialog, public Ui::Preferences +class Preferences : public QDialog, private Ui::Preferences { Q_OBJECT public: From 2af83212a6784c67a34f50c0e5345dec49aa0318 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 7 Apr 2010 21:13:54 +0530 Subject: [PATCH 57/98] Due to the switch to mercurial from svn, changed 'svnversion' to 'hg identify -i' --- version.pri | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.pri b/version.pri index df1335c..f19cb31 100644 --- a/version.pri +++ b/version.pri @@ -2,11 +2,11 @@ APP_VERSION = 0.1 APP_VERSION_FILE = version.cpp revtarget.target = $$APP_VERSION_FILE win32:revtarget.commands = echo "const char *version = \"$$APP_VERSION\";" \ - "const char *revision = \"$(shell svnversion .)\";" \ + "const char *revision = \"$(shell hg identify -i)\";" \ > $$APP_VERSION_FILE unix:revtarget.commands = echo \ "\"const char *version = \\\"$$APP_VERSION\\\";" \ - "const char *revision = \\\"$(shell svnversion .)\\\";\"" \ + "const char *revision = \\\"$(shell hg identify -i)\\\";\"" \ > $$APP_VERSION_FILE revtarget.depends = $$SOURCES $$HEADERS $$FORMS $$POST_TARGETDEPS From 836ed6e16de0869a6c88d88c54042b513d56c452 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 10 Apr 2010 17:04:54 +0530 Subject: [PATCH 58/98] Provided option to manually specify revision hash for source packages and tarballs --- version.pri | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/version.pri b/version.pri index f19cb31..d1f53fc 100644 --- a/version.pri +++ b/version.pri @@ -1,12 +1,15 @@ APP_VERSION = 0.1 +APP_REVISION = $(shell hg identify -i) +#uncomment the below line in a source package and fill-in the correct revision +#APP_REVISION = APP_VERSION_FILE = version.cpp revtarget.target = $$APP_VERSION_FILE win32:revtarget.commands = echo "const char *version = \"$$APP_VERSION\";" \ - "const char *revision = \"$(shell hg identify -i)\";" \ + "const char *revision = \"$$APP_REVISION\";" \ > $$APP_VERSION_FILE unix:revtarget.commands = echo \ "\"const char *version = \\\"$$APP_VERSION\\\";" \ - "const char *revision = \\\"$(shell hg identify -i)\\\";\"" \ + "const char *revision = \\\"$APP_REVISION\\\";\"" \ > $$APP_VERSION_FILE revtarget.depends = $$SOURCES $$HEADERS $$FORMS $$POST_TARGETDEPS From 2e77fd8b947d3bcf5043a280c0d42f01628943b9 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 10 Apr 2010 21:15:31 +0530 Subject: [PATCH 59/98] Adding a missing $ in version.pri for unix compilation --- version.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.pri b/version.pri index d1f53fc..103b6e9 100644 --- a/version.pri +++ b/version.pri @@ -9,7 +9,7 @@ win32:revtarget.commands = echo "const char *version = \"$$APP_VERSION\";" \ > $$APP_VERSION_FILE unix:revtarget.commands = echo \ "\"const char *version = \\\"$$APP_VERSION\\\";" \ - "const char *revision = \\\"$APP_REVISION\\\";\"" \ + "const char *revision = \\\"$$APP_REVISION\\\";\"" \ > $$APP_VERSION_FILE revtarget.depends = $$SOURCES $$HEADERS $$FORMS $$POST_TARGETDEPS From 35f4a8bafb8fdc57b5cb3266f1d04a5768cc1c0a Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Fri, 16 Apr 2010 16:45:35 +0530 Subject: [PATCH 60/98] Fixes for 64bit compilation and Qt4.6 --- Makefile | 3 ++- client/main.cpp | 6 +++++- client/portstatsmodel.cpp | 16 ++++++++-------- client/streamconfigdialog.cpp | 12 ++++++------ common/icmp.cpp | 1 - common/protocollistiterator.cpp | 8 ++++---- common/protocolmanager.cpp | 2 +- common/streambase.cpp | 10 +++++----- server/drone_main.cpp | 5 +++++ 9 files changed, 36 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 557a682..0b49aa8 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +debug: QMAKE_CONFIG=-config debug release: QMAKE_CONFIG=-config release all: @@ -7,7 +8,7 @@ all: $(MAKE) -C client release: qmake all - +debug: qmake all clean: -$(MAKE) -C client $@ diff --git a/client/main.cpp b/client/main.cpp index fd5daf8..91f61d8 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -18,13 +18,15 @@ along with this program. If not, see */ #include "mainwindow.h" +#include "../common/protocolmanager.h" #include #include #include -QSettings *appSettings; +extern ProtocolManager *OstProtocolManager; +QSettings *appSettings; QMainWindow *mainWindow; int main(int argc, char* argv[]) @@ -32,6 +34,8 @@ int main(int argc, char* argv[]) QApplication app(argc, argv); int exitCode; + OstProtocolManager = new ProtocolManager(); + /* (Portable Mode) If we have a .ini file in the same directory as the executable, we use that instead of the platform specific location and format for the settings */ diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index 5bfd33e..92e6a24 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -130,28 +130,28 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const // Statistics case e_STAT_FRAMES_RCVD: - return stats.rx_pkts(); + return quint64(stats.rx_pkts()); case e_STAT_FRAMES_SENT: - return stats.tx_pkts(); + return quint64(stats.tx_pkts()); case e_STAT_FRAME_SEND_RATE: - return stats.tx_pps(); + return quint64(stats.tx_pps()); case e_STAT_FRAME_RECV_RATE: - return stats.rx_pps(); + return quint64(stats.rx_pps()); case e_STAT_BYTES_RCVD: - return stats.rx_bytes(); + return quint64(stats.rx_bytes()); case e_STAT_BYTES_SENT: - return stats.tx_bytes(); + return quint64(stats.tx_bytes()); case e_STAT_BYTE_SEND_RATE: - return stats.tx_bps(); + return quint64(stats.tx_bps()); case e_STAT_BYTE_RECV_RATE: - return stats.rx_bps(); + return quint64(stats.rx_bps()); #if 0 case e_STAT_FRAMES_RCVD_NIC: diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index dd02697..9609be3 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -28,7 +28,7 @@ along with this program. If not, see // FIXME(HI) - remove #include "../common/protocolmanager.h" -extern ProtocolManager OstProtocolManager; +extern ProtocolManager *OstProtocolManager; int StreamConfigDialog::lastTopLevelTabIndex = 0; @@ -95,7 +95,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, if (id2 != ButtonIdNone && id2 != ButtonIdOther) { - if (OstProtocolManager.isValidNeighbour(id1, id2)) + if (OstProtocolManager->isValidNeighbour(id1, id2)) { connect(btn1, SIGNAL(toggled(bool)), btn2, SLOT(setEnabled(bool))); @@ -117,7 +117,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, } mpAvailableProtocolsModel = new QStringListModel( - OstProtocolManager.protocolDatabase(), this); + OstProtocolManager->protocolDatabase(), this); lvAllProtocols->setModel(mpAvailableProtocolsModel); mpSelectedProtocolsModel = new QStringListModel(this); lvSelectedProtocols->setModel(mpSelectedProtocolsModel); @@ -375,7 +375,7 @@ void StreamConfigDialog::on_tbAdd_clicked() } foreach(QModelIndex idx, selection) - _iter->insert(OstProtocolManager.createProtocol( + _iter->insert(OstProtocolManager->createProtocol( mpAvailableProtocolsModel->stringList().at(idx.row()), mpStream)); updateSelectProtocolsAdvancedWidget(); @@ -689,7 +689,7 @@ void StreamConfigDialog::__updateProtocol(int level, int newId) switch (oldId) { case ButtonIdNone: - _iter->insert(OstProtocolManager.createProtocol( + _iter->insert(OstProtocolManager->createProtocol( newId, mpStream)); break; @@ -699,7 +699,7 @@ void StreamConfigDialog::__updateProtocol(int level, int newId) p =_iter->next(); if (newId) - _iter->setValue(OstProtocolManager.createProtocol( + _iter->setValue(OstProtocolManager->createProtocol( newId, mpStream)); else _iter->remove(); diff --git a/common/icmp.cpp b/common/icmp.cpp index 0c03700..67290c4 100644 --- a/common/icmp.cpp +++ b/common/icmp.cpp @@ -215,7 +215,6 @@ QVariant IcmpProtocol::fieldData(int index, FieldAttrib attrib, cksum = 0; // avoid the 'maybe used unitialized' warning break; } - printf("%s: attrib = %d, cksum = %d\n", __FUNCTION__, attrib, cksum); switch(attrib) { diff --git a/common/protocollistiterator.cpp b/common/protocollistiterator.cpp index a081365..9f82c3d 100644 --- a/common/protocollistiterator.cpp +++ b/common/protocollistiterator.cpp @@ -33,12 +33,12 @@ ProtocolListIterator::~ProtocolListIterator() bool ProtocolListIterator::findNext(const AbstractProtocol* value) const { - return _iter->findNext((AbstractProtocol*)((uint)value)); + return _iter->findNext(const_cast(value)); } bool ProtocolListIterator::findPrevious(const AbstractProtocol* value) { - return _iter->findPrevious((AbstractProtocol*)((uint)value)); + return _iter->findPrevious(const_cast(value)); } bool ProtocolListIterator::hasNext() const @@ -69,7 +69,7 @@ void ProtocolListIterator::insert(AbstractProtocol* value) else value->next = NULL; - _iter->insert((AbstractProtocol*)((uint)value)); + _iter->insert(const_cast(value)); } AbstractProtocol* ProtocolListIterator::next() @@ -109,7 +109,7 @@ void ProtocolListIterator::setValue(AbstractProtocol* value) const _iter->value()->next->prev = value; value->prev = _iter->value()->prev; value->next = _iter->value()->next; - _iter->setValue((AbstractProtocol*)((uint)value)); + _iter->setValue(const_cast(value)); } void ProtocolListIterator::toBack() diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 130e5ce..9e06468 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -39,7 +39,7 @@ along with this program. If not, see #include "userscript.h" #include "sample.h" -ProtocolManager OstProtocolManager; +ProtocolManager *OstProtocolManager; ProtocolManager::ProtocolManager() { diff --git a/common/streambase.cpp b/common/streambase.cpp index 109252c..44be9f1 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -23,7 +23,7 @@ along with this program. If not, see #include "protocollistiterator.h" #include "protocolmanager.h" -extern ProtocolManager OstProtocolManager; +extern ProtocolManager *OstProtocolManager; StreamBase::StreamBase() : mStreamId(new OstProto::StreamId), @@ -39,12 +39,12 @@ StreamBase::StreamBase() : iter = createProtocolListIterator(); // By default newly created streams have the mac and payload protocols - proto = OstProtocolManager.createProtocol( + proto = OstProtocolManager->createProtocol( OstProto::Protocol::kMacFieldNumber, this); iter->insert(proto); qDebug("stream: mac = %p", proto); - proto = OstProtocolManager.createProtocol( + proto = OstProtocolManager->createProtocol( OstProto::Protocol::kPayloadFieldNumber, this); iter->insert(proto); qDebug("stream: payload = %p", proto); @@ -89,7 +89,7 @@ void StreamBase::protoDataCopyFrom(const OstProto::Stream &stream) iter = createProtocolListIterator(); for (int i=0; i < stream.protocol_size(); i++) { - proto = OstProtocolManager.createProtocol( + proto = OstProtocolManager->createProtocol( stream.protocol(i).protocol_id().id(), this); proto->protoDataCopyFrom(stream.protocol(i)); iter->insert(proto); @@ -208,7 +208,7 @@ quint16 StreamBase::frameLen(int streamIndex) const case OstProto::StreamCore::e_fl_random: //! \todo (MED) This 'random' sequence is same across iterations pktLen = 64; // to avoid the 'maybe used uninitialized' warning - qsrand(((uint) this)); + qsrand(reinterpret_cast(this)); for (int i = 0; i <= streamIndex; i++) pktLen = qrand(); pktLen = frameLenMin() + (pktLen % diff --git a/server/drone_main.cpp b/server/drone_main.cpp index 722f5c0..3f16bcc 100644 --- a/server/drone_main.cpp +++ b/server/drone_main.cpp @@ -19,12 +19,17 @@ along with this program. If not, see #include "drone.h" +#include "../common/protocolmanager.h" + +extern ProtocolManager *OstProtocolManager; + int myport; int main(int argc, char *argv[]) { QApplication app(argc, argv); Drone drone; + OstProtocolManager = new ProtocolManager(); app.setApplicationName(drone.objectName()); From 7b9c1f92a09112189cd9a32f82d76e70fc12102f Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Fri, 16 Apr 2010 20:11:08 +0530 Subject: [PATCH 61/98] Fixed crash in PortStatsFilterDialog while removing selected rows --- client/portstatsfilterdialog.cpp | 56 +++++++++++++++----------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/client/portstatsfilterdialog.cpp b/client/portstatsfilterdialog.cpp index 457a7c8..baf9192 100644 --- a/client/portstatsfilterdialog.cpp +++ b/client/portstatsfilterdialog.cpp @@ -80,52 +80,48 @@ QList PortStatsFilterDialog::getItemList(bool* ok, void PortStatsFilterDialog::on_tbSelectIn_clicked() { - QStandardItem *item; - while (lvUnselected->selectionModel()->selectedIndexes().size()) + QList rows; + + foreach(QModelIndex idx, lvUnselected->selectionModel()->selectedIndexes()) + rows.append(idx.row()); + qSort(rows.begin(), rows.end(), qGreater()); + + int count = mSelected.rowCount(); + + foreach(int row, rows) { - item = mUnselected.takeItem(lvUnselected->selectionModel()-> - selectedIndexes().at(0).row()); - if (mUnselected.removeRow(lvUnselected->selectionModel()-> - selectedIndexes().at(0).row())) - mSelected.appendRow(item); + QList items = mUnselected.takeRow(row); + mSelected.insertRow(count, items); } } void PortStatsFilterDialog::on_tbSelectOut_clicked() { - QStandardItem *item; + QList rows; - while (lvSelected->selectionModel()->selectedIndexes().size()) + foreach(QModelIndex idx, lvSelected->selectionModel()->selectedIndexes()) + rows.append(idx.row()); + qSort(rows.begin(), rows.end(), qGreater()); + + foreach(int row, rows) { - item = mSelected.takeItem(lvSelected->selectionModel()-> - selectedIndexes().at(0).row()); - if (mSelected.removeRow(lvSelected->selectionModel()-> - selectedIndexes().at(0).row())) - { - mUnselected.appendRow(item); - mUnselected.sort(0); - } + QList items = mSelected.takeRow(row); + mUnselected.appendRow(items); } + + mUnselected.sort(0); } void PortStatsFilterDialog::on_lvUnselected_doubleClicked(const QModelIndex &index) { - QStandardItem *item; - - item = mUnselected.takeItem(index.row()); - if (mUnselected.removeRow(index.row())) - mSelected.appendRow(item); + QList items = mUnselected.takeRow(index.row()); + mSelected.appendRow(items); } void PortStatsFilterDialog::on_lvSelected_doubleClicked(const QModelIndex &index) { - QStandardItem *item; - - item = mSelected.takeItem(index.row()); - if (mSelected.removeRow(index.row())) - { - mUnselected.appendRow(item); - mUnselected.sort(0); - } + QList items = mSelected.takeRow(index.row()); + mUnselected.appendRow(items); + mUnselected.sort(0); } From 254e7141b04c1ab58360afb54f1f54baf0495db4 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 17 Apr 2010 17:32:46 +0530 Subject: [PATCH 62/98] PortStatsFilterDialog - ports can now be inserted at a specific row instead of just being added to the end --- client/portstatsfilterdialog.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/portstatsfilterdialog.cpp b/client/portstatsfilterdialog.cpp index baf9192..55882f1 100644 --- a/client/portstatsfilterdialog.cpp +++ b/client/portstatsfilterdialog.cpp @@ -86,12 +86,13 @@ void PortStatsFilterDialog::on_tbSelectIn_clicked() rows.append(idx.row()); qSort(rows.begin(), rows.end(), qGreater()); - int count = mSelected.rowCount(); + QModelIndex idx = lvSelected->selectionModel()->currentIndex(); + int insertAt = idx.isValid() ? idx.row() : mSelected.rowCount(); foreach(int row, rows) { QList items = mUnselected.takeRow(row); - mSelected.insertRow(count, items); + mSelected.insertRow(insertAt, items); } } @@ -115,7 +116,10 @@ void PortStatsFilterDialog::on_tbSelectOut_clicked() void PortStatsFilterDialog::on_lvUnselected_doubleClicked(const QModelIndex &index) { QList items = mUnselected.takeRow(index.row()); - mSelected.appendRow(items); + QModelIndex idx = lvSelected->selectionModel()->currentIndex(); + int insertAt = idx.isValid() ? idx.row() : mSelected.rowCount(); + + mSelected.insertRow(insertAt, items); } void PortStatsFilterDialog::on_lvSelected_doubleClicked(const QModelIndex &index) From 3591227c0b0d53e6d060795b7e7a27ca20d6352b Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 17 Apr 2010 18:44:20 +0530 Subject: [PATCH 63/98] Fixed a assert failure when closing the client with the port list expanded --- client/portgroup.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/client/portgroup.cpp b/client/portgroup.cpp index 8e2597f..faa1f0a 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -78,7 +78,16 @@ PortGroup::~PortGroup() void PortGroup::on_rpcChannel_stateChanged(QAbstractSocket::SocketState state) { qDebug("state changed %d", state); - emit portGroupDataChanged(mPortGroupId); + + switch (state) + { + case QAbstractSocket::UnconnectedState: + case QAbstractSocket::ClosingState: + break; + + default: + emit portGroupDataChanged(mPortGroupId); + } } void PortGroup::on_rpcChannel_connected() From 0075a3712b7b879ccaa51739328a08954de8f045 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 17 Apr 2010 19:57:28 +0530 Subject: [PATCH 64/98] Added .hgignore --- .hgignore | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .hgignore diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..b0a474f --- /dev/null +++ b/.hgignore @@ -0,0 +1,29 @@ +syntax: glob + +# generated object files +*.o +*.a +*.exe + +# Qt generated files +ui_*.h +moc_*.cpp +qrc_*.cpp + +# QMake generated files +*\Makefile* +*\object_script.* + +# protobuf generated files +*.pb.h +*.pb.cc + +# ostinato generated files +version.cpp + +# vim swap files +*.swp + +# ctags +tags + From ae050372654a419fa7f0fd2ba9d10aa84b6881f1 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 18 Apr 2010 21:50:35 +0530 Subject: [PATCH 65/98] Added, edited, corrected and completed the AbstractProtocol doxygen documentation --- common/abstractprotocol.cpp | 304 ++++++++++++++++++++++++++++++------ common/abstractprotocol.h | 50 +++--- common/sample.cpp | 2 + 3 files changed, 289 insertions(+), 67 deletions(-) diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 750a26b..fdca539 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -26,20 +26,49 @@ along with this program. If not, see /*! \class AbstractProtocol - \todo (MED) update AbstractProtocol documentation - Bare Minimum set of methods that a subclass needs to reimplement + AbstractProtocol is the base abstract class which provides the interface + for all protocols. + + All protocols supported by Ostinato are derived from AbstractProtocol. Apart + from defining the interface for a protocol, it also provides sensible default + implementations for methods so that the subclasses need not re-implement. It + also provides convenience functions for subclasses to use such as methods to + retrieve payload size, checksum etc. + + A subclass typically needs to reimplement the following methods - + - name() + - shortName() + - createInstance() + - protocolNumber() - protoDataCopyInto() [pure virtual] - protoDataCopyFrom() [pure virtual] - fieldCount() + - fieldFlags() + - fieldData() + - setFieldData() + - configWidget() [pure virtual] + - loadConfigWidget() [pure virtual] + - storeConfigWidget() [pure virtual] - Any useful protocol should also provide implementations for - - name() - - shortName() - - fieldName() + Depending on certain conditions, subclasses may need to reimplement the + following additional methods - + - protocolIdType() + - protocolId() + - protocolFrameSize() + - isProtocolFrameValueVariable() + - isProtocolFrameSizeVariable() - Protocols with meta fields should additionally implement - - metaFieldCount() - - isMetaField() + See the description of the methods for more information. + + Most of the above methods just need some standard boilerplate code - + the SampleProtocol implementation includes the boilerplate +*/ + +/*! + Constructs an abstract protocol for the given stream and parent + + parent is typically NULL except for protocols which are part of a + ComboProtocol */ AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent) { @@ -51,16 +80,31 @@ AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent) protoSize = -1; } +/*! + Destroys the abstract protocol +*/ AbstractProtocol::~AbstractProtocol() { } +/*! + Allocates and returns a new instance of the class. + + Caller is responsible for freeing up after use. Subclasses MUST implement + this function +*/ AbstractProtocol* AbstractProtocol::createInstance(StreamBase* /* stream */, AbstractProtocol* /* parent */) { return NULL; } +/*! + Returns the protocol's field number as defined in message 'Protocol', enum 'k' + (file: protocol.proto) + + Subclasses MUST implement this function +*/ quint32 AbstractProtocol::protocolNumber() const { qFatal("Something wrong!!!"); @@ -68,29 +112,44 @@ quint32 AbstractProtocol::protocolNumber() const } /*! - \fn virtual void protoDataCopyInto(OstProto::OstProto::StreamCore &stream) = 0; + \fn virtual void AbstractProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const = 0 - Copy the protocol's protobuf into the passed in stream \n - In the base class this is a pure virtual function. Subclasses should - implement this function by using - \n - stream.AddExtension()->CopyFrom() */ + Copy the protocol's protobuf as an extension into the passed in protocol -/* - \fn virtual void protoDataCopyFrom(const OstProto::OstProto::StreamCore &stream) = 0; - */ + In the base class this is a pure virtual function. Subclasses MUST implement + this function. See the SampleProtocol for an example +*/ -/*! Returns the full name of the protocol \n - The default implementation returns a null string */ + +/*! + \fn virtual void AbstractProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) = 0 + + Copy and update the protocol's protobuf member data variable from the + passed in protocol + + In the base class this is a pure virtual function. Subclasses MUST implement + this function. See the SampleProtocol for an example +*/ + + +/*! + Returns the full name of the protocol + + The default implementation returns a null string +*/ QString AbstractProtocol::name() const { return QString(); } -/*! Returns the short name or abbreviation of the protocol \n - The default implementation forms and returns a abbreviation composed +/*! + Returns the short name or abbreviation of the protocol + + The default implementation forms and returns an abbreviation composed of all the upper case chars in name() \n The default implementation caches the abbreviation on its first invocation - and subsequently returns the cached abbreviation */ + and subsequently returns the cached abbreviation +*/ QString AbstractProtocol::shortName() const { if (protoAbbr.isNull()) @@ -109,19 +168,27 @@ QString AbstractProtocol::shortName() const return protoAbbr; } -/*! Returns the number of fields (both Frame and Meta fields) \n - The default implementation returns zero */ -int AbstractProtocol::fieldCount() const +/*! + Returns the number of fields in the protocol (both Frame fields and + Meta fields) + + The default implementation returns zero. Subclasses MUST implement this + function. +*/ +int AbstractProtocol::fieldCount() const { return 0; } -/*! Returns the number of meta fields \n +/*! + Returns the number of meta fields + The default implementation counts and returns the number of fields for which the FieldIsMeta flag is set\n The default implementation caches the count on its first invocation - and subsequently returns the cached count */ -int AbstractProtocol::metaFieldCount() const + and subsequently returns the cached count +*/ +int AbstractProtocol::metaFieldCount() const { if (metaCount < 0) { @@ -135,24 +202,35 @@ int AbstractProtocol::metaFieldCount() const return metaCount; } -/*! Returns the number of frame fields \n - Convenience method - same as fieldCount() minus metaFieldCount() */ -int AbstractProtocol::frameFieldCount() const +/*! + Returns the number of frame fields + + Convenience method - same as fieldCount() minus metaFieldCount() +*/ +int AbstractProtocol::frameFieldCount() const { //qDebug("%s:%d, %d", __FUNCTION__, fieldCount(), metaFieldCount()); return (fieldCount() - metaFieldCount()); } +/*! + Returns the field flags for the passed in field index + + The default implementation assumes all fields to be frame fields and returns + 'FieldIsNormal'. Subclasses must reimplement this method if they have any + meta fields or checksum fields. See the SampleProtocol for an example. +*/ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const { return FieldIsNormal; } -/*! Returns the requested field attribute data \n +/*! + Returns the requested field attribute data + Protocols which have meta fields that vary a frame field across streams may use the streamIndex to return the appropriate field value \n - Some field attriubutes e.g. FieldName may be invariant across streams\n - The default implementation returns the fieldValue() converted to string + Some field attributes e.g. FieldName may be invariant across streams\n The FieldTextValue attribute may include additional information about the field's value e.g. a checksum field may include "(correct)" or "(incorrect)" alongwith the actual checksum value. \n @@ -167,14 +245,14 @@ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const fields whose size are a non-integral multiple of bytes or smaller than a byte, subclasses should return the correct value. Also for fields which represent checksums, subclasses should return a value for - FieldBitSize - even if it is an integral multiple of bytes + FieldBitSize - even if it is an integral multiple of bytes. \note If a subclass uses any of the below functions to derive FieldFrameValue, the subclass should handle and return a value for FieldBitSize to prevent endless recrusion - - protocolFrameCksum() - protocolFramePayloadSize() - */ +*/ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { @@ -203,25 +281,58 @@ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, return QVariant(); } -/*! Sets the value of a field corresponding to index \n - Returns true if field is successfully set, false otherwise \n - The default implementation always returns false */ +/*! + Sets the value of a field corresponding to index + + This method is called by the GUI code to store a user specified value into + the protocol's protoBuf. Currently this method is called with + FieldAttrib = FieldValue only. + + Returns true if field is successfully set, false otherwise. + The default implementation always returns false. Subclasses should + reimplement this method. See SampleProtocol for an example. + +*/ bool AbstractProtocol::setFieldData(int /*index*/, const QVariant& /*value*/, FieldAttrib /*attrib*/) { return false; } +/*! + Returns the protocolIdType for the protocol + + The default implementation returns ProtocolIdNone. If a subclass has a + protocolId field it should return the appropriate value e.g. IP protocol + will return ProtocolIdIp, Ethernet will return ProtocolIdEth etc. +*/ AbstractProtocol::ProtocolIdType AbstractProtocol::protocolIdType() const { return ProtocolIdNone; } +/*! + Returns the protocol id of the protocol for the given type + + The default implementation returns 0. If a subclass represents a protocol + which has a particular protocol id, it should return the appropriate value. + If a protocol does not have an id for the given type, it should defer to + the base class. e.g. IGMP will return 2 for ProtocolIdIp, and defer to the + base class for the remaining ProtocolIdTypes; IP will return 0x800 for + ProtocolIdEth type, 0x060603 for ProtocolIdLlc and 0x04 for ProtocolIdIp etc. +*/ quint32 AbstractProtocol::protocolId(ProtocolIdType /*type*/) const { return 0; } +/*! + Returns the protocol id of the payload protocol (the protocol that + immediately follows the current one) + + A subclass which has a protocol id field, can use this to retrieve the + appropriate value +*/ quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const { quint32 id; @@ -237,6 +348,16 @@ quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const return id; } +/*! + Returns the protocol's size in bytes + + The default implementation sums up the individual field bit sizes and + returns it. The default implementation calculates the caches the size on + the first invocation and subsequently returns the cached size. + + If the subclass protocol has a varying protocol size, it MUST reimplement + this method, otherwise the default implementation is sufficient. +*/ int AbstractProtocol::protocolFrameSize(int streamIndex) const { if (protoSize < 0) @@ -255,6 +376,13 @@ int AbstractProtocol::protocolFrameSize(int streamIndex) const return protoSize; } +/*! + Returns the byte offset in the packet where the protocol starts + + This method is useful only for "padding" protocols i.e. protocols which + fill up the remaining space for the user defined packet size e.g. the + PatternPayload protocol +*/ int AbstractProtocol::protocolFrameOffset(int streamIndex) const { int size = 0; @@ -272,6 +400,12 @@ int AbstractProtocol::protocolFrameOffset(int streamIndex) const return size; } +/*! + Returns the size of the payload in bytes. The payload includes all protocols + subsequent to the current + + This method is useful for protocols which need to fill in a payload size field +*/ int AbstractProtocol::protocolFramePayloadSize(int streamIndex) const { int size = 0; @@ -289,11 +423,14 @@ int AbstractProtocol::protocolFramePayloadSize(int streamIndex) const } -/*! Returns a byte array encoding the protocol (and its fields) which can be +/*! + Returns a byte array encoding the protocol (and its fields) which can be inserted into the stream's frame + The default implementation forms and returns an ordered concatenation of - the FrameValue of all the 'frame' fields of the protocol taking care of fields - which are not an integral number of bytes\n */ + the FrameValue of all the 'frame' fields of the protocol also taking care of + fields which are not an integral number of bytes\n +*/ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) const { QByteArray proto, field; @@ -386,16 +523,38 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) return proto; } +/*! + Returns true if the protocol varies one or more of its fields at run-time, + false otherwise + + The default implementation returns false. A subclass should reimplement + if it has varying fields e.g. an IP protocol that increments/decrements + the IP address with every packet +*/ bool AbstractProtocol::isProtocolFrameValueVariable() const { return false; } +/*! + Returns true if the protocol varies its size at run-time, false otherwise + + The default implmentation returns false. A subclass should reimplement + if it varies its size at run-time e.g. a Payload protocol for a stream with + incrementing/decrementing frame lengths +*/ bool AbstractProtocol::isProtocolFrameSizeVariable() const { return false; } +/*! + Returns true if the payload content for a protocol varies at run-time, + false otherwise + + This is useful for subclasses which have fields dependent on payload content + (e.g. UDP has a checksum field that varies if the payload varies) +*/ bool AbstractProtocol::isProtocolFramePayloadValueVariable() const { AbstractProtocol *p = next; @@ -412,6 +571,13 @@ bool AbstractProtocol::isProtocolFramePayloadValueVariable() const return false; } +/*! + Returns true if the payload size for a protocol varies at run-time, + false otherwise + + This is useful for subclasses which have fields dependent on payload size + (e.g. UDP has a checksum field that varies if the payload varies) +*/ bool AbstractProtocol::isProtocolFramePayloadSizeVariable() const { AbstractProtocol *p = next; @@ -428,14 +594,17 @@ bool AbstractProtocol::isProtocolFramePayloadSizeVariable() const return false; } - /*! + Returns the checksum (of the requested type) of the protocol's contents + + Useful for protocols which have a checksum field + \note If a subclass uses protocolFrameCksum() from within fieldData() to derive a cksum field, it MUST handle and return the 'FieldBitSize' attribute also for that particular field instead of using the default AbstractProtocol implementation for 'FieldBitSize' - this is required to prevent infinite recursion - */ +*/ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex, CksumType cksumType) const { @@ -502,6 +671,14 @@ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex, return cksum; } +/*! + Returns the checksum of the requested type for the protocol's header + + This is useful for subclasses which needs the header's checksum e.g. TCP/UDP + require a "Pseudo-IP" checksum + + Currently the default implementation supports only type CksumIpPseudo +*/ quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, CksumType cksumType) const { @@ -530,6 +707,15 @@ quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, return (quint16) ~sum; } +/*! + Returns the checksum of the requested type for the protocol's payload + + This is useful for subclasses which needs the payload's checksum e.g. TCP/UDP + require a IP checksum of the payload (to be combined with other checksums to + derive the final checksum) + + Currently the default implementation supports only type CksumIp +*/ quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, CksumType cksumType) const { @@ -558,3 +744,33 @@ quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, return (quint16) ~sum; } +/*! + \fn virtual QWidget* AbstractProtocol::configWidget() = 0; + + Returns the configuration widget for the protocol. The protocol retains + ownership of the configuration widget - the caller should not free it. + + In the base class this is a pure virtual function. Subclasses MUST implement + this function. See the SampleProtocol for an example +*/ + +/*! + \fn virtual void AbstractProtocol::loadConfigWidget() = 0; + + Loads data from the protocol's protobuf into the configuration widget of + the protocol + + In the base class this is a pure virtual function. Subclasses MUST implement + this function. See the SampleProtocol for an example +*/ + +/*! + \fn virtual void AbstractProtocol::storeConfigWidget() = 0; + + Stores data from the configuration widget of the protocol into the protocol's + protobuf + + In the base class this is a pure virtual function. Subclasses MUST implement + this function. See the SampleProtocol for an example +*/ + diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index 9d12dd2..61ee58a 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -48,45 +48,49 @@ class AbstractProtocol friend class ProtocolListIterator; private: - mutable int metaCount; - mutable int protoSize; + mutable int metaCount; + mutable int protoSize; mutable QString protoAbbr; protected: - StreamBase *mpStream; - AbstractProtocol *parent; - AbstractProtocol *prev; - AbstractProtocol *next; + StreamBase *mpStream; //!< Stream that this protocol belongs to + AbstractProtocol *parent; //!< Parent protocol, if any + AbstractProtocol *prev; //!< Protocol preceding this protocol + AbstractProtocol *next; //!< Protocol succeeding this protocol public: + //! Properties of a field, can be OR'd enum FieldFlag { - FieldIsNormal = 0x0, - FieldIsMeta = 0x1, - FieldIsCksum = 0x2 + FieldIsNormal = 0x0, //!< field appears in frame content + FieldIsMeta = 0x1, //!< field does not appear in frame, is meta data + FieldIsCksum = 0x2 //!< field is a checksum, appears in frame content }; - Q_DECLARE_FLAGS(FieldFlags, FieldFlag); + Q_DECLARE_FLAGS(FieldFlags, FieldFlag); //!< \private abcd + //! Various attributes of a field enum FieldAttrib { - FieldName, //! name - FieldValue, //! value in host byte order (user editable) - FieldTextValue, //! value as text - FieldFrameValue, //! frame encoded value in network byte order - FieldBitSize, //! size in bits + FieldName, //!< name + FieldValue, //!< value in host byte order (user editable) + FieldTextValue, //!< value as text + FieldFrameValue, //!< frame encoded value in network byte order + FieldBitSize, //!< size in bits }; + //! Supported Protocol Id types enum ProtocolIdType { - ProtocolIdNone, - ProtocolIdLlc, - ProtocolIdEth, - ProtocolIdIp, + ProtocolIdNone, //!< Marker representing non-existent protocol id + ProtocolIdLlc, //!< LLC (802.2) + ProtocolIdEth, //!< Ethernet II + ProtocolIdIp, //!< IP }; + //! Supported checksum types enum CksumType { - CksumIp, - CksumIpPseudo, - CksumTcpUdp, + CksumIp, //!< Standard IP Checksum + CksumIpPseudo, //!< Standard checksum for Pseudo-IP header + CksumTcpUdp, //!< Standard TCP/UDP checksum including pseudo-IP - CksumMax + CksumMax //!< Marker for number of cksum types }; AbstractProtocol(StreamBase *stream, AbstractProtocol *parent = 0); diff --git a/common/sample.cpp b/common/sample.cpp index 4d601bf..d83ab54 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -30,6 +30,7 @@ SampleConfigForm::SampleConfigForm(QWidget *parent) SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent) : AbstractProtocol(stream, parent) { + /* The configWidget is created lazily */ configForm = NULL; } @@ -459,6 +460,7 @@ bool SampleProtocol::isProtocolFrameSizeVariable() const QWidget* SampleProtocol::configWidget() { + /* Lazy creation of the configWidget */ if (configForm == NULL) { configForm = new SampleConfigForm; From e681e1e22689acdb7e4054f961f658b1b74f008c Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 24 Apr 2010 19:16:39 +0530 Subject: [PATCH 66/98] Added new param 'cksumScope' in AbstractProtocol's header and payload cksum methods; this ensures that TCP/UDP checksum is now correct if preceded by a IP 4over4. --- common/abstractprotocol.cpp | 32 ++++++++++++++++++++++++-------- common/abstractprotocol.h | 12 ++++++++++-- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index fdca539..8ed7513 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -672,15 +672,19 @@ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex, } /*! - Returns the checksum of the requested type for the protocol's header + Returns the checksum of the requested type for the protocol's header This is useful for subclasses which needs the header's checksum e.g. TCP/UDP - require a "Pseudo-IP" checksum + require a "Pseudo-IP" checksum. The checksum is limited to the specified + scope. Currently the default implementation supports only type CksumIpPseudo + + \note The default value for cksumScope is different for + protocolFrameHeaderCksum() and protocolFramePayloadCksum() */ quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, - CksumType cksumType) const + CksumType cksumType, CksumScope cksumScope) const { quint32 sum = 0; quint16 cksum; @@ -692,15 +696,19 @@ quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, { cksum = p->protocolFrameCksum(streamIndex, cksumType); sum += (quint16) ~cksum; - p = p->prev; qDebug("%s: sum = %u, cksum = %u", __FUNCTION__, sum, cksum); + if (cksumScope == CksumScopeAdjacentProtocol) + goto out; + p = p->prev; } if (parent) { - cksum = parent->protocolFrameHeaderCksum(streamIndex, cksumType); + cksum = parent->protocolFrameHeaderCksum(streamIndex, cksumType, + cksumScope); sum += (quint16) ~cksum; } +out: while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); @@ -712,12 +720,16 @@ quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, This is useful for subclasses which needs the payload's checksum e.g. TCP/UDP require a IP checksum of the payload (to be combined with other checksums to - derive the final checksum) + derive the final checksum). The checksum is limited to the specified + scope. Currently the default implementation supports only type CksumIp + + \note The default value for cksumScope is different for + protocolFrameHeaderCksum() and protocolFramePayloadCksum() */ quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, - CksumType cksumType) const + CksumType cksumType, CksumScope cksumScope) const { quint32 sum = 0; quint16 cksum; @@ -729,15 +741,19 @@ quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, { cksum = p->protocolFrameCksum(streamIndex, cksumType); sum += (quint16) ~cksum; + if (cksumScope == CksumScopeAdjacentProtocol) + goto out; p = p->next; } if (parent) { - cksum = parent->protocolFramePayloadCksum(streamIndex, cksumType); + cksum = parent->protocolFramePayloadCksum(streamIndex, cksumType, + cksumScope); sum += (quint16) ~cksum; } +out: while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index 61ee58a..f34beb9 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -93,6 +93,12 @@ public: CksumMax //!< Marker for number of cksum types }; + //! Supported checksum scopes + enum CksumScope { + CksumScopeAdjacentProtocol, //!< Cksum only the adjacent protocol + CksumScopeAllProtocols, //!< Cksum over all the protocols + }; + AbstractProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~AbstractProtocol(); @@ -134,9 +140,11 @@ public: virtual quint32 protocolFrameCksum(int streamIndex = 0, CksumType cksumType = CksumIp) const; quint32 protocolFrameHeaderCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; + CksumType cksumType = CksumIp, + CksumScope cksumScope = CksumScopeAdjacentProtocol) const; quint32 protocolFramePayloadCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; + CksumType cksumType = CksumIp, + CksumScope cksumScope = CksumScopeAllProtocols) const; virtual QWidget* configWidget() = 0; virtual void loadConfigWidget() = 0; From d0cddbafb8611befefcc2aa30a73b470a8dc0295 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 2 May 2010 15:37:46 +0530 Subject: [PATCH 67/98] Added a preflight check method to class StreamBase - this is used by StreamConfigDialog to notify the user of potential problems such as truncated frames --- client/streamconfigdialog.cpp | 13 +++++- client/streamconfigdialog.ui | 52 ++++++++-------------- common/dot3.cpp | 4 -- common/payload.cpp | 10 +++-- common/streambase.cpp | 81 +++++++++++++++++++++++++++++++++-- common/streambase.h | 8 +++- 6 files changed, 120 insertions(+), 48 deletions(-) diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 9609be3..b58e2b3 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -926,11 +926,20 @@ void StreamConfigDialog::StoreCurrentStream() void StreamConfigDialog::on_pbOk_clicked() { - OstProto::Stream s; + QString log; + OstProto::Stream s; // Store dialog contents into stream StoreCurrentStream(); + if (!mpStream->preflightCheck(log)) + { + if (QMessageBox::warning(this, "Preflight Check", log + "\nContinue?", + QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + == QMessageBox::No) + return; + } + // Copy the data from the "local working copy of stream" to "actual stream" mpStream->protoDataCopyInto(s); mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyFrom(s); @@ -938,5 +947,7 @@ void StreamConfigDialog::on_pbOk_clicked() qDebug("stream stored"); lastTopLevelTabIndex = twTopLevel->currentIndex(); + + accept(); } diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 07457e6..f4417f7 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -1198,22 +1198,6 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - pbOk - clicked() - StreamConfigDialog - accept() - - - 496 - 552 - - - 533 - 433 - - - pbCancel clicked() @@ -1221,8 +1205,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff reject() - 579 - 552 + 558 + 453 533 @@ -1237,12 +1221,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 158 - 149 + 169 + 207 - 158 - 149 + 169 + 207 @@ -1253,12 +1237,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 59 - 120 + 125 + 207 - 59 - 149 + 125 + 207 @@ -1269,12 +1253,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 59 - 123 + 125 + 207 - 59 - 149 + 125 + 207 @@ -1285,12 +1269,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 59 - 123 + 125 + 207 - 145 - 149 + 156 + 207 diff --git a/common/dot3.cpp b/common/dot3.cpp index adbe5d5..e97bdc0 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -23,7 +23,6 @@ along with this program. If not, see #include "dot3.h" #include "streambase.h" -#define SZ_FCS 4 Dot3ConfigForm::Dot3ConfigForm(QWidget *parent) : QWidget(parent) @@ -95,7 +94,6 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, { quint16 len; - //len = mpStream->frameLen() - SZ_FCS; len = protocolFramePayloadSize(streamIndex); return len; } @@ -103,7 +101,6 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, { quint16 len; - //len = mpStream->frameLen() - SZ_FCS; len = protocolFramePayloadSize(streamIndex); return QString("%1").arg(len); } @@ -112,7 +109,6 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, quint16 len; QByteArray fv; - //len = mpStream->frameLen() - SZ_FCS; len = protocolFramePayloadSize(streamIndex); fv.resize(2); qToBigEndian(len, (uchar*) fv.data()); diff --git a/common/payload.cpp b/common/payload.cpp index 2c6c267..4536a82 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -24,7 +24,6 @@ along with this program. If not, see #include "payload.h" #include "streambase.h" -#define SZ_FCS 4 PayloadConfigForm::PayloadConfigForm(QWidget *parent) : QWidget(parent) @@ -94,19 +93,22 @@ QString PayloadProtocol::shortName() const return QString("DATA"); } -int PayloadProtocol::protocolFrameSize(int streamIndex) const +int PayloadProtocol::protocolFrameSize(int streamIndex) const { int len; len = mpStream->frameLen(streamIndex) - protocolFrameOffset(streamIndex) - - SZ_FCS; + - kFcsSize; + + if (len < 0) + len = 0; qDebug("%s: this = %p, streamIndex = %d, len = %d", __FUNCTION__, this, streamIndex, len); return len; } -int PayloadProtocol::fieldCount() const +int PayloadProtocol::fieldCount() const { return payload_fieldCount; } diff --git a/common/streambase.cpp b/common/streambase.cpp index 44be9f1..85909ba 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -362,14 +362,67 @@ _exit: return true; } -int StreamBase::frameValue(uchar *buf, int bufMaxSize, int n) const +bool StreamBase::isFrameSizeVariable() const +{ + ProtocolListIterator *iter; + + iter = createProtocolListIterator(); + while (iter->hasNext()) + { + AbstractProtocol *proto; + + proto = iter->next(); + if (proto->isProtocolFrameSizeVariable()) + goto _exit; + } + delete iter; + return false; + +_exit: + delete iter; + return true; +} + +// frameProtocolLength() returns the sum of all the individual protocol sizes +// which may be different from frameLen() +int StreamBase::frameProtocolLength(int frameIndex) const +{ + int len = 0; + ProtocolListIterator *iter = createProtocolListIterator(); + + while (iter->hasNext()) + { + AbstractProtocol *proto = iter->next(); + + len += proto->protocolFrameSize(frameIndex); + } + delete iter; + + return len; +} + +int StreamBase::frameCount() const +{ + int count; + + switch (sendUnit()) + { + case e_su_packets: count = numPackets(); break; + case e_su_bursts: count = numBursts() * burstSize(); break; + default: Q_ASSERT(false); // unreachable + } + + return count; +} + +int StreamBase::frameValue(uchar *buf, int bufMaxSize, int frameIndex) const { int pktLen, len = 0; - pktLen = frameLen(n); + pktLen = frameLen(frameIndex); // pktLen is adjusted for CRC/FCS which will be added by the NIC - pktLen -= 4; + pktLen -= kFcsSize; if ((pktLen < 0) || (pktLen > bufMaxSize)) return 0; @@ -383,7 +436,7 @@ int StreamBase::frameValue(uchar *buf, int bufMaxSize, int n) const QByteArray ba; proto = iter->next(); - ba = proto->protocolFrameValue(n); + ba = proto->protocolFrameValue(frameIndex); if (len + ba.size() < bufMaxSize) memcpy(buf+len, ba.constData(), ba.size()); @@ -394,6 +447,26 @@ int StreamBase::frameValue(uchar *buf, int bufMaxSize, int n) const return pktLen; } +bool StreamBase::preflightCheck(QString &result) const +{ + int count = isFrameSizeVariable() ? frameCount() : 1; + + for (int i = 0; i < count; i++) + { + if (frameLen(i) < (frameProtocolLength(i) + kFcsSize)) + { + result += QString("One or more frames may be truncated - " + "frame length should be at least %1.\n") + .arg(frameProtocolLength(i) + kFcsSize); + goto _fail; + } + } + return true; + +_fail: + return false; +} + bool StreamBase::StreamLessThan(StreamBase* stream1, StreamBase* stream2) { return stream1->ordinal() < stream2->ordinal() ? true : false; diff --git a/common/streambase.h b/common/streambase.h index 61964c6..7afbbd9 100644 --- a/common/streambase.h +++ b/common/streambase.h @@ -25,6 +25,8 @@ along with this program. If not, see #include "protocol.pb.h" +const int kFcsSize = 4; + class AbstractProtocol; class ProtocolList; class ProtocolListIterator; @@ -130,7 +132,11 @@ public: bool setBurstRate(quint32 burstsPerSec); bool isFrameVariable() const; - int frameValue(uchar *buf, int bufMaxSize, int n) const; + bool isFrameSizeVariable() const; + int frameProtocolLength(int frameIndex) const; + int frameCount() const; + int frameValue(uchar *buf, int bufMaxSize, int frameIndex) const; + bool preflightCheck(QString &result) const; static bool StreamLessThan(StreamBase* stream1, StreamBase* stream2); }; From d9f788e93d3a1c3b103ac6ff55f2669fe6ca3cd8 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Tue, 4 May 2010 21:42:29 +0530 Subject: [PATCH 68/98] Fixed compiler warnings --- client/ostinato.pro | 2 +- client/portgrouplist.cpp | 4 +++- client/portswindow.cpp | 8 ++++---- client/streamconfigdialog.cpp | 11 ++++++++--- common/streambase.cpp | 2 +- rpc/pbrpcchannel.cpp | 15 ++++++++------- rpc/rpcserver.cpp | 23 ++++++++++++----------- server/abstractport.cpp | 7 ++++--- server/pcapport.cpp | 4 ++-- server/pcapport.h | 2 +- 10 files changed, 44 insertions(+), 34 deletions(-) diff --git a/client/ostinato.pro b/client/ostinato.pro index 853ca5c..3655802 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -78,4 +78,4 @@ QMAKE_DISTCLEAN += object_script.* include(../version.pri) # TODO(LOW): Test only -include(modeltest.pri) +CONFIG(debug, debug|release):include(modeltest.pri) diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index 3d6a8be..a8e688c 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -29,11 +29,13 @@ PortGroupList::PortGroupList() { PortGroup *pg; +#ifndef QT_NO_DEBUG // TODO(LOW): Remove streamModelTester_ = new ModelTest(getStreamModel()); portModelTester_ = new ModelTest(getPortModel()); portStatsModelTester_ = new ModelTest(getPortStatsModel()); - +#endif + // Add the "Local" Port Group pg = new PortGroup; addPortGroup(*pg); diff --git a/client/portswindow.cpp b/client/portswindow.cpp index e0ad61e..ccaed5a 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -168,10 +168,10 @@ void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft, if ((tvPortList->currentIndex() >= topLeft) && (tvPortList->currentIndex() <= bottomRight)) #endif - if ((topLeft < tvPortList->currentIndex()) || - (topLeft == tvPortList->currentIndex()) && - ((tvPortList->currentIndex() < bottomRight)) || - (tvPortList->currentIndex() == bottomRight)) + if (((topLeft < tvPortList->currentIndex()) || + (topLeft == tvPortList->currentIndex())) && + (((tvPortList->currentIndex() < bottomRight)) || + (tvPortList->currentIndex() == bottomRight))) { updatePortViewActions(tvPortList->currentIndex()); } diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index b58e2b3..32ebe01 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -135,7 +135,9 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, LoadCurrentStream(); mpPacketModel = new PacketModel(this); tvPacketTree->setModel(mpPacketModel); +#ifndef QT_NO_DEBUG mpPacketModelTester = new ModelTest(mpPacketModel); +#endif tvPacketTree->header()->hide(); vwPacketDump->setModel(mpPacketModel); vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); @@ -386,7 +388,7 @@ void StreamConfigDialog::on_tbDelete_clicked() { int n; QModelIndex idx; - AbstractProtocol *p; + AbstractProtocol *p = NULL; idx = lvSelectedProtocols->currentIndex(); @@ -405,6 +407,7 @@ void StreamConfigDialog::on_tbDelete_clicked() p = _iter->next(); } + Q_CHECK_PTR(p); _iter->remove(); delete p; @@ -416,7 +419,7 @@ void StreamConfigDialog::on_tbUp_clicked() { int m, n; QModelIndex idx; - AbstractProtocol *p; + AbstractProtocol *p = NULL; idx = lvSelectedProtocols->currentIndex(); @@ -435,6 +438,7 @@ void StreamConfigDialog::on_tbUp_clicked() p = _iter->next(); } + Q_CHECK_PTR(p); _iter->remove(); _iter->previous(); _iter->insert(p); @@ -447,7 +451,7 @@ void StreamConfigDialog::on_tbDown_clicked() { int m, n; QModelIndex idx; - AbstractProtocol *p; + AbstractProtocol *p = NULL; idx = lvSelectedProtocols->currentIndex(); @@ -466,6 +470,7 @@ void StreamConfigDialog::on_tbDown_clicked() p = _iter->next(); } + Q_CHECK_PTR(p); _iter->remove(); _iter->next(); _iter->insert(p); diff --git a/common/streambase.cpp b/common/streambase.cpp index 85909ba..6ba1909 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -403,7 +403,7 @@ int StreamBase::frameProtocolLength(int frameIndex) const int StreamBase::frameCount() const { - int count; + int count = 0; switch (sendUnit()) { diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index 521aca5..c89a2d6 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -82,7 +82,8 @@ void PbRpcChannel::CallMethod( ::google::protobuf::Message *response, ::google::protobuf::Closure* done) { - char msg[MSGBUF_SIZE]; + char msgBuf[MSGBUF_SIZE]; + char* const msg = &msgBuf[0]; int len; bool ret; @@ -110,7 +111,7 @@ void PbRpcChannel::CallMethod( if (!req->IsInitialized()) { qWarning("RpcChannel: missing required fields in request"); - qDebug(req->InitializationErrorString().c_str()); + qDebug("%s", req->InitializationErrorString().c_str()); qFatal("exiting"); @@ -125,13 +126,13 @@ void PbRpcChannel::CallMethod( this->response=response; isPending = true; - ret = req->SerializeToArray((void*) (&msg[PB_HDR_SIZE]), sizeof(msg)); + ret = req->SerializeToArray((void*)(msg+PB_HDR_SIZE), sizeof(msgBuf)-PB_HDR_SIZE); Q_ASSERT(ret == true); len = req->ByteSize(); - *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_REQUEST); // type - *((quint16*)(&msg[2])) = HTONS(method->index()); // method id - *((quint32*)(&msg[4])) = HTONL(len); // len + *((quint16*)(msg+0)) = HTONS(PB_MSG_TYPE_REQUEST); // type + *((quint16*)(msg+2)) = HTONS(method->index()); // method id + *((quint32*)(msg+4)) = HTONL(len); // len // Avoid printing stats since it happens every couple of seconds if (pendingMethodId != 13) @@ -260,7 +261,7 @@ void PbRpcChannel::on_mpSocket_readyRead() if (!response->IsInitialized()) { qWarning("RpcChannel: missing required fields in response"); - qDebug(response->InitializationErrorString().c_str()); + qDebug("%s", response->InitializationErrorString().c_str()); controller->SetFailed("Required fields missing"); } diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index 5d67833..4b86b25 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -69,7 +69,8 @@ void RpcServer::done(PbRpcController *controller) { google::protobuf::Message *response = controller->response(); QIODevice *blob; - char msg[MSGBUF_SIZE]; + char msgBuf[MSGBUF_SIZE]; + char* const msg = &msgBuf[0]; int len; //qDebug("In RpcServer::done"); @@ -86,9 +87,9 @@ void RpcServer::done(PbRpcController *controller) len = blob->size(); qDebug("is binary blob of len %d", len); - *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_BINBLOB); // type - *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method - (*(quint32*)(&msg[4])) = HTONL(len); // len + *((quint16*)(msg+0)) = HTONS(PB_MSG_TYPE_BINBLOB); // type + *((quint16*)(msg+2)) = HTONS(pendingMethodId); // method + (*(quint32*)(msg+4)) = HTONL(len); // len clientSock->write(msg, PB_HDR_SIZE); @@ -97,7 +98,7 @@ void RpcServer::done(PbRpcController *controller) { int l; - len = blob->read(msg, sizeof(msg)); + len = blob->read(msg, sizeof(msgBuf)); l = clientSock->write(msg, len); Q_ASSERT(l == len); } @@ -108,18 +109,18 @@ void RpcServer::done(PbRpcController *controller) if (!response->IsInitialized()) { qWarning("response missing required fields!!"); - qDebug(response->InitializationErrorString().c_str()); + qDebug("%s", response->InitializationErrorString().c_str()); qFatal("exiting"); goto _exit; } - response->SerializeToArray((void*) &msg[PB_HDR_SIZE], sizeof(msg)); + response->SerializeToArray((void*)(msg+PB_HDR_SIZE), sizeof(msgBuf)-PB_HDR_SIZE); len = response->ByteSize(); - *((quint16*)(&msg[0])) = HTONS(PB_MSG_TYPE_RESPONSE); // type - *((quint16*)(&msg[2])) = HTONS(pendingMethodId); // method - *((quint32*)(&msg[4])) = HTONL(len); // len + *((quint16*)(msg+0)) = HTONS(PB_MSG_TYPE_RESPONSE); // type + *((quint16*)(msg+2)) = HTONS(pendingMethodId); // method + *((quint32*)(msg+4)) = HTONL(len); // len // Avoid printing stats since it happens once every couple of seconds if (pendingMethodId != 13) @@ -248,7 +249,7 @@ void RpcServer::when_dataAvail() if (!req->IsInitialized()) { qWarning("Missing required fields in request"); - qDebug(req->InitializationErrorString().c_str()); + qDebug("%s", req->InitializationErrorString().c_str()); qFatal("exiting"); delete req; delete resp; diff --git a/server/abstractport.cpp b/server/abstractport.cpp index 70d833f..954278b 100644 --- a/server/abstractport.cpp +++ b/server/abstractport.cpp @@ -76,7 +76,7 @@ StreamBase* AbstractPort::stream(int streamId) { for (int i = 0; i < streamList_.size(); i++) { - if (streamId == streamList_.at(i)->id()) + if ((uint)streamId == streamList_.at(i)->id()) return streamList_.at(i); } @@ -96,7 +96,7 @@ bool AbstractPort::deleteStream(int streamId) { StreamBase *stream; - if (streamId == streamList_.at(i)->id()) + if ((uint)streamId == streamList_.at(i)->id()) { stream = streamList_.takeAt(i); delete stream; @@ -157,6 +157,7 @@ void AbstractPort::updatePacketList() if (streamList_[i]->isFrameVariable()) { isVariable = true; + len = 0; // avoid compiler warning; get len value for each pkt } else { @@ -216,7 +217,7 @@ void AbstractPort::updatePacketList() */ setPacketListLoopMode(true, streamList_[i]->sendUnit() == - OstProto::StreamControl::e_su_bursts ? ibg : ipg); + StreamBase::e_su_bursts ? ibg : ipg); goto _stop_no_more_pkts; case ::OstProto::StreamControl::e_nw_goto_next: diff --git a/server/pcapport.cpp b/server/pcapport.cpp index f9412cf..222dd42 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -132,6 +132,7 @@ PcapPort::PortMonitor::PortMonitor(const char *device, Direction direction, ret = pcap_setdirection(handle_, PCAP_D_OUT); break; default: + ret = -1; // avoid 'may be used uninitialized' warning Q_ASSERT(false); } #endif @@ -351,8 +352,7 @@ int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p, struct pcap_pkthdr *hdr = (struct pcap_pkthdr*) queue->buffer; char *end = queue->buffer + queue->len; - if (sync) - ts = hdr->ts; + ts = hdr->ts; while (1) { diff --git a/server/pcapport.h b/server/pcapport.h index 0001b0a..a6264c5 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -36,7 +36,7 @@ public: void init(); virtual bool hasExclusiveControl() { return false; } - virtual bool setExclusiveControl(bool exclusive) { return false; } + virtual bool setExclusiveControl(bool /*exclusive*/) { return false; } virtual void clearPacketList() { transmitter_->clearPacketList(); From 3defe905e5b227a7a181cc4833482ffce7cbdaaf Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Thu, 6 May 2010 20:39:29 +0530 Subject: [PATCH 69/98] Added a generic TextProtocol that can be used for any text based protocol such as HTTP, SIP, RTSP, NNTP etc. Also - fixed a bug in ARP; IntComboBox sets itself as 'editable' --- common/arp.cpp | 8 ++ common/intcombobox.h | 1 + common/ostproto.pro | 4 + common/protocol.proto | 2 + common/protocolmanager.cpp | 9 +- common/textproto.cpp | 259 +++++++++++++++++++++++++++++++++++++ common/textproto.h | 89 +++++++++++++ common/textproto.proto | 37 ++++++ common/textproto.ui | 79 +++++++++++ 9 files changed, 486 insertions(+), 2 deletions(-) create mode 100644 common/textproto.cpp create mode 100644 common/textproto.h create mode 100644 common/textproto.proto create mode 100644 common/textproto.ui diff --git a/common/arp.cpp b/common/arp.cpp index 7548c62..84a6094 100644 --- a/common/arp.cpp +++ b/common/arp.cpp @@ -722,6 +722,8 @@ bool ArpProtocol::setFieldData(int index, const QVariant &value, uint mode = value.toUInt(&isOk); if (isOk && data.HwAddrMode_IsValid(mode)) data.set_sender_hw_addr_mode((OstProto::Arp::HwAddrMode) mode); + else + isOk = false; break; } case arp_senderHwAddrCount: @@ -745,6 +747,8 @@ bool ArpProtocol::setFieldData(int index, const QVariant &value, if (isOk && data.ProtoAddrMode_IsValid(mode)) data.set_sender_proto_addr_mode( (OstProto::Arp::ProtoAddrMode)mode); + else + isOk = false; break; } case arp_senderProtoAddrCount: @@ -774,6 +778,8 @@ bool ArpProtocol::setFieldData(int index, const QVariant &value, uint mode = value.toUInt(&isOk); if (isOk && data.HwAddrMode_IsValid(mode)) data.set_target_hw_addr_mode((OstProto::Arp::HwAddrMode)mode); + else + isOk = false; break; } case arp_targetHwAddrCount: @@ -797,6 +803,8 @@ bool ArpProtocol::setFieldData(int index, const QVariant &value, if (isOk && data.ProtoAddrMode_IsValid(mode)) data.set_target_proto_addr_mode( (OstProto::Arp::ProtoAddrMode)mode); + else + isOk = false; break; } case arp_targetProtoAddrCount: diff --git a/common/intcombobox.h b/common/intcombobox.h index 7da3351..2884a3a 100644 --- a/common/intcombobox.h +++ b/common/intcombobox.h @@ -28,6 +28,7 @@ public: IntComboBox(QWidget *parent = 0) : QComboBox(parent) { + setEditable(true); } void addItem(int value, const QString &text) { diff --git a/common/ostproto.pro b/common/ostproto.pro index 2c8aaf3..33567f8 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -16,6 +16,7 @@ FORMS += \ icmp.ui \ tcp.ui \ udp.ui \ + textproto.ui \ userscript.ui \ sample.ui PROTOS += \ @@ -36,6 +37,7 @@ PROTOS += \ icmp.proto \ tcp.proto \ udp.proto \ + textproto.proto \ userscript.proto \ sample.proto HEADERS += \ @@ -61,6 +63,7 @@ HEADERS += \ icmp.h \ tcp.h \ udp.h \ + textproto.h \ userscript.h \ sample.h SOURCES += \ @@ -82,6 +85,7 @@ SOURCES += \ icmp.cpp \ tcp.cpp \ udp.cpp \ + textproto.cpp \ userscript.cpp \ sample.cpp diff --git a/common/protocol.proto b/common/protocol.proto index 4bd5899..bafbe8a 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -106,6 +106,8 @@ message Protocol { kUdpFieldNumber = 141; kIcmpFieldNumber = 142; kIgmpFieldNumber = 143; + + kTextProtocolFieldNumber = 150; } } diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 9e06468..b543ac0 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -36,6 +36,7 @@ along with this program. If not, see #include "icmp.h" #include "tcp.h" #include "udp.h" +#include "textproto.h" #include "userscript.h" #include "sample.h" @@ -48,8 +49,6 @@ ProtocolManager::ProtocolManager() */ registerProtocol(OstProto::Protocol::kMacFieldNumber, (void*) MacProtocol::createInstance); - registerProtocol(OstProto::Protocol::kPayloadFieldNumber, - (void*) PayloadProtocol::createInstance); registerProtocol(OstProto::Protocol::kEth2FieldNumber, (void*) Eth2Protocol::createInstance); registerProtocol(OstProto::Protocol::kDot3FieldNumber, @@ -79,6 +78,12 @@ ProtocolManager::ProtocolManager() registerProtocol(OstProto::Protocol::kUdpFieldNumber, (void*) UdpProtocol::createInstance); + registerProtocol(OstProto::Protocol::kTextProtocolFieldNumber, + (void*) TextProtocol::createInstance); + + registerProtocol(OstProto::Protocol::kPayloadFieldNumber, + (void*) PayloadProtocol::createInstance); + registerProtocol(OstProto::Protocol::kUserScriptFieldNumber, (void*) UserScriptProtocol::createInstance); registerProtocol(OstProto::Protocol::kSampleFieldNumber, diff --git a/common/textproto.cpp b/common/textproto.cpp new file mode 100644 index 0000000..2f69f82 --- /dev/null +++ b/common/textproto.cpp @@ -0,0 +1,259 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#include + +#include "textproto.h" + +TextProtocolConfigForm::TextProtocolConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + portNumCombo->setValidator(new QIntValidator(0, 0xFFFF, this)); + portNumCombo->addItem(0, "Reserved"); + portNumCombo->addItem(80, "HTTP"); + portNumCombo->addItem(554, "RTSP"); + portNumCombo->addItem(5060, "SIP"); +} + +TextProtocol::TextProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) +{ + /* The configWidget is created lazily */ + configForm = NULL; +} + +TextProtocol::~TextProtocol() +{ + delete configForm; +} + +AbstractProtocol* TextProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) +{ + return new TextProtocol(stream, parent); +} + +quint32 TextProtocol::protocolNumber() const +{ + return OstProto::Protocol::kTextProtocolFieldNumber; +} + +void TextProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const +{ + protocol.MutableExtension(OstProto::textProtocol)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void TextProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::textProtocol)) + data.MergeFrom(protocol.GetExtension(OstProto::textProtocol)); +} + +QString TextProtocol::name() const +{ + return QString("Text Protocol"); +} + +QString TextProtocol::shortName() const +{ + return QString("TEXT"); +} + +quint32 TextProtocol::protocolId(ProtocolIdType type) const +{ + switch(type) + { + //case ProtocolIdTcpUdp: return data.port_num(); + default:break; + } + + return AbstractProtocol::protocolId(type); +} + +int TextProtocol::fieldCount() const +{ + return textProto_fieldCount; +} + +AbstractProtocol::FieldFlags TextProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case textProto_text: + break; + + case textProto_portNum: + case textProto_encoding: + flags |= FieldIsMeta; + break; + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return flags; +} + +QVariant TextProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case textProto_text: + { + switch(attrib) + { + case FieldName: + return QString("Text"); + case FieldValue: + case FieldTextValue: + return QString().fromStdString(data.text()); + case FieldFrameValue: + Q_ASSERT(data.encoding() == OstProto::TextProtocol::kUtf8); + return QString().fromStdString(data.text()).toUtf8(); + default: + break; + } + break; + + } + + // Meta fields + case textProto_portNum: + { + switch(attrib) + { + case FieldValue: + return data.port_num(); + default: + break; + } + break; + } + case textProto_encoding: + { + switch(attrib) + { + case FieldValue: + return data.encoding(); + default: + break; + } + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool TextProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + bool isOk = false; + + if (attrib != FieldValue) + goto _exit; + + switch (index) + { + case textProto_text: + { + data.set_text(value.toString().toUtf8()); + isOk = true; + break; + } + case textProto_portNum: + { + uint portNum = value.toUInt(&isOk); + if (isOk) + data.set_port_num(portNum); + break; + } + case textProto_encoding: + { + uint enc = value.toUInt(&isOk); + if (isOk && data.TextEncoding_IsValid(enc)) + data.set_encoding((OstProto::TextProtocol::TextEncoding) enc); + else + isOk = false; + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + +_exit: + return isOk; +} + +int TextProtocol::protocolFrameSize(int streamIndex) const +{ + return fieldData(textProto_text, FieldFrameValue).toByteArray().size() ; +} + +QWidget* TextProtocol::configWidget() +{ + /* Lazy creation of the configWidget */ + if (configForm == NULL) + { + configForm = new TextProtocolConfigForm; + loadConfigWidget(); + } + + return configForm; +} + +void TextProtocol::loadConfigWidget() +{ + configWidget(); + + configForm->portNumCombo->setValue( + fieldData(textProto_portNum, FieldValue).toUInt()); + configForm->encodingCombo->setCurrentIndex( + fieldData(textProto_encoding, FieldValue).toUInt()); + configForm->protoText->setText( + fieldData(textProto_text, FieldValue).toString()); +} + +void TextProtocol::storeConfigWidget() +{ + configWidget(); + + setFieldData(textProto_portNum, configForm->portNumCombo->currentValue()); + setFieldData(textProto_encoding, configForm->encodingCombo->currentIndex()); + + setFieldData(textProto_text, configForm->protoText->toPlainText()); +} + diff --git a/common/textproto.h b/common/textproto.h new file mode 100644 index 0000000..57b71cc --- /dev/null +++ b/common/textproto.h @@ -0,0 +1,89 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _TEXT_PROTOCOL_H +#define _TEXT_PROTOCOL_H + +#include "textproto.pb.h" +#include "ui_textproto.h" + +#include "abstractprotocol.h" + +/* +TextProtocol Protocol Frame Format - + specified text encoded with the specified encoding +*/ + +class TextProtocolConfigForm : public QWidget, public Ui::TextProtocol +{ + Q_OBJECT +public: + TextProtocolConfigForm(QWidget *parent = 0); +private slots: +}; + +class TextProtocol : public AbstractProtocol +{ +private: + OstProto::TextProtocol data; + TextProtocolConfigForm *configForm; + enum textProtocolField + { + // Frame Fields + textProto_text = 0, + + // Meta Fields + textProto_portNum, + textProto_encoding, + + textProto_fieldCount + }; + +public: + TextProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~TextProtocol(); + + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + + virtual quint32 protocolId(ProtocolIdType type) const; + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual int protocolFrameSize(int streamIndex = 0) const; + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/textproto.proto b/common/textproto.proto new file mode 100644 index 0000000..be4f246 --- /dev/null +++ b/common/textproto.proto @@ -0,0 +1,37 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +import "protocol.proto"; + +package OstProto; + +// Any Text based protocol +message TextProtocol { + enum TextEncoding { + kUtf8 = 0; + } + + optional uint32 port_num = 1 [default = 0]; + optional TextEncoding encoding = 2 [default = kUtf8]; + optional string text = 3; +} + +extend Protocol { + optional TextProtocol textProtocol = 150; +} diff --git a/common/textproto.ui b/common/textproto.ui new file mode 100644 index 0000000..b3cf278 --- /dev/null +++ b/common/textproto.ui @@ -0,0 +1,79 @@ + + TextProtocol + + + + 0 + 0 + 493 + 300 + + + + Form + + + + + + TCP/UDP Port Number (Protocol) + + + portNumCombo + + + + + + + + 2 + 0 + + + + + + + + Encode as + + + encodingCombo + + + + + + + + 1 + 0 + + + + + UTF-8 + + + + + + + + false + + + + + + + + IntComboBox + QComboBox +
intcombobox.h
+
+
+ + +
From 6ca88eb661b5adbb72914016f86d4ba9a7baaf3d Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 8 May 2010 20:12:38 +0530 Subject: [PATCH 70/98] StreamConfigDialog "Protocol Selection" framework has been enhanced to include a L5 group. TextProtocol has been added to this L5 group. TCP/UDP protocols have been modified to get port numbers from a L5 protocol; TCP/UDP protocols have also been updated as per the "Sample" protocol recommendation --- client/streamconfigdialog.cpp | 37 ++++- client/streamconfigdialog.h | 7 +- client/streamconfigdialog.ui | 142 ++++++++++------ common/abstractprotocol.h | 1 + common/tcp.cpp | 298 +++++++++++++++++++++++++++++----- common/tcp.h | 6 +- common/tcp.proto | 25 +-- common/tcp.ui | 52 +++++- common/textproto.cpp | 5 +- common/textproto.proto | 2 +- common/udp.cpp | 217 +++++++++++++++++++++---- common/udp.h | 6 +- common/udp.proto | 14 +- common/udp.ui | 62 +++++-- 14 files changed, 709 insertions(+), 165 deletions(-) diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 32ebe01..7789f8d 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -66,6 +66,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbL1None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); connect(rbFtNone, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); connect(rbL3None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); + connect(rbL4None, SIGNAL(toggled(bool)), SLOT(forceProtocolNone(bool))); // If L1/L2(FT)/L3/L4 = Other, force subsequent protocol to Other and // disable the subsequent protocol group as well @@ -78,8 +79,8 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbL4Other, SIGNAL(toggled(bool)), rbPayloadOther, SLOT(setChecked(bool))); connect(rbL4Other, SIGNAL(toggled(bool)), gbPayloadProto, SLOT(setDisabled(bool))); - // Setup valid subsequent protocols for L2 and L3 protocols - for (int i = ProtoL2; i <= ProtoL3; i++) + // Setup valid subsequent protocols for L2 to L4 protocols + for (int i = ProtoL2; i <= ProtoL4; i++) { foreach(QAbstractButton *btn1, bgProto[i]->buttons()) { @@ -207,7 +208,7 @@ void StreamConfigDialog::setupUiExtra() foreach(QRadioButton *btn, gbL4Proto->findChildren()) bgProto[ProtoL4]->addButton(btn); #else - bgProto[ProtoL4]->addButton(rbL4None, 0); + bgProto[ProtoL4]->addButton(rbL4None, ButtonIdNone); bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); bgProto[ProtoL4]->addButton(rbL4Icmp, OstProto::Protocol::kIcmpFieldNumber); @@ -215,6 +216,17 @@ void StreamConfigDialog::setupUiExtra() bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther); #endif + bgProto[ProtoL5] = new QButtonGroup(); +#if 0 + foreach(QRadioButton *btn, gbL5Proto->findChildren()) + bgProto[ProtoL5]->addButton(btn); +#else + bgProto[ProtoL5]->addButton(rbL5None, ButtonIdNone); + bgProto[ProtoL5]->addButton(rbL5Text, + OstProto::Protocol::kTextProtocolFieldNumber); + bgProto[ProtoL5]->addButton(rbL5Other, ButtonIdOther); +#endif + bgProto[ProtoPayload] = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbPayloadProto->findChildren()) @@ -639,13 +651,19 @@ void StreamConfigDialog::forceProtocolNone(bool checked) bgProto[ProtoL3]->button(ButtonIdNone)->click(); disableProtocols(bgProto[ProtoL3], checked); } - else if (btn == rbL3None) + else if (btn == rbL3None) { if (checked) bgProto[ProtoL4]->button(ButtonIdNone)->click(); disableProtocols(bgProto[ProtoL4], checked); } - else + else if (btn == rbL4None) + { + if (checked) + bgProto[ProtoL5]->button(ButtonIdNone)->click(); + disableProtocols(bgProto[ProtoL5], checked); + } + else { Q_ASSERT(1 == 0); // Unreachable code! } @@ -929,6 +947,15 @@ void StreamConfigDialog::StoreCurrentStream() } } +void StreamConfigDialog::on_tbProtocolData_currentChanged(int /*index*/) +{ + // Refresh protocol widgets in case there is any dependent data between + // protocols e.g. TCP/UDP port numbers are dependent on Port/Protocol + // selection in TextProtocol + mpStream->storeProtocolWidgets(); + mpStream->loadProtocolWidgets(); +} + void StreamConfigDialog::on_pbOk_clicked() { QString log; diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 637bc9c..5709570 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -61,7 +61,8 @@ private: ProtoL2 = 2, ProtoL3 = 3, ProtoL4 = 4, - ProtoPayload = 5, + ProtoL5 = 5, + ProtoPayload = 6, ProtoMax }; @@ -87,7 +88,6 @@ private: static int lastTopLevelTabIndex; void setupUiExtra(); - void updateSelectedProtocols(); void LoadCurrentStream(); void StoreCurrentStream(); @@ -122,6 +122,9 @@ private slots: void updateSelectProtocolsAdvancedWidget(); + // "Protocol Data" related + void on_tbProtocolData_currentChanged(int index); + void on_pbPrev_clicked(); void on_pbNext_clicked(); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index f4417f7..f64c848 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -9,7 +9,7 @@ 0 0 569 - 464 + 481 @@ -174,14 +174,14 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff 0 0 527 - 226 + 243 Simple - + L1 @@ -220,7 +220,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
- + true @@ -351,7 +351,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + true @@ -393,49 +393,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - - - true - - - VLAN - - - false - - - false - - - - - - Untagged - - - true - - - - - - - Tagged - - - - - - - Stacked - - - - - - - + true @@ -507,7 +465,49 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + + + + true + + + VLAN + + + false + + + false + + + + + + Untagged + + + true + + + + + + + Tagged + + + + + + + Stacked + + + + + + + Qt::Vertical @@ -515,11 +515,53 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff 20 - 21 + 71 + + + + true + + + L5 + + + + + + None + + + true + + + + + + + false + + + Text + + + + + + + false + + + Other + + + + + + diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index f34beb9..a36bbef 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -82,6 +82,7 @@ public: ProtocolIdLlc, //!< LLC (802.2) ProtocolIdEth, //!< Ethernet II ProtocolIdIp, //!< IP + ProtocolIdTcpUdp, //!< TCP/UDP Port Number }; //! Supported checksum types diff --git a/common/tcp.cpp b/common/tcp.cpp index 9c44ec0..f29b1a1 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -73,6 +73,11 @@ QString TcpProtocol::shortName() const return QString("TCP"); } +AbstractProtocol::ProtocolIdType TcpProtocol::protocolIdType() const +{ + return ProtocolIdTcpUdp; +} + quint32 TcpProtocol::protocolId(ProtocolIdType type) const { switch(type) @@ -84,7 +89,7 @@ quint32 TcpProtocol::protocolId(ProtocolIdType type) const return AbstractProtocol::protocolId(type); } -int TcpProtocol::fieldCount() const +int TcpProtocol::fieldCount() const { return tcp_fieldCount; } @@ -114,12 +119,16 @@ AbstractProtocol::FieldFlags TcpProtocol::fieldFlags(int index) const case tcp_urg_ptr: break; + case tcp_is_override_src_port: + case tcp_is_override_dst_port: case tcp_is_override_hdrlen: case tcp_is_override_cksum: flags |= FieldIsMeta; break; default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); break; } @@ -132,47 +141,81 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, switch (index) { case tcp_src_port: + { + quint16 srcPort; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + if (data.is_override_src_port()) + srcPort = data.src_port(); + else + srcPort = payloadProtocolId(ProtocolIdTcpUdp); + break; + default: + srcPort = 0; // avoid the 'maybe used unitialized' warning + break; + } switch(attrib) { case FieldName: return QString("Source Port"); case FieldValue: - return data.src_port(); + return srcPort; case FieldTextValue: - return QString("%1").arg(data.src_port()); + return QString("%1").arg(srcPort); case FieldFrameValue: { QByteArray fv; fv.resize(2); - qToBigEndian((quint16) data.src_port(), (uchar*) fv.data()); + qToBigEndian(srcPort, (uchar*) fv.data()); return fv; } default: break; } break; - + } case tcp_dst_port: + { + quint16 dstPort; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + if (data.is_override_dst_port()) + dstPort = data.dst_port(); + else + dstPort = payloadProtocolId(ProtocolIdTcpUdp); + break; + default: + dstPort = 0; // avoid the 'maybe used unitialized' warning + break; + } switch(attrib) { case FieldName: return QString("Destination Port"); case FieldValue: - return data.dst_port(); + return dstPort; case FieldTextValue: - return QString("%1").arg(data.dst_port()); + return QString("%1").arg(dstPort); case FieldFrameValue: { QByteArray fv; fv.resize(2); - qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data()); + qToBigEndian(dstPort, (uchar*) fv.data()); return fv; } default: break; } break; - + } case tcp_seq_num: switch(attrib) { @@ -384,19 +427,174 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, break; // Meta fields + case tcp_is_override_src_port: + { + switch(attrib) + { + case FieldValue: + return data.is_override_src_port(); + default: + break; + } + break; + } + case tcp_is_override_dst_port: + { + switch(attrib) + { + case FieldValue: + return data.is_override_dst_port(); + default: + break; + } + break; + } case tcp_is_override_hdrlen: + { + switch(attrib) + { + case FieldValue: + return data.is_override_hdrlen(); + default: + break; + } + break; + } case tcp_is_override_cksum: + { + switch(attrib) + { + case FieldValue: + return data.is_override_cksum(); + default: + break; + } + break; + } default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); break; } return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool TcpProtocol::setFieldData(int /*index*/, const QVariant &/*value*/, - FieldAttrib /*attrib*/) +bool TcpProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) { - return false; + bool isOk = false; + + if (attrib != FieldValue) + goto _exit; + + switch (index) + { + case tcp_src_port: + { + uint srcPort = value.toUInt(&isOk); + if (isOk) + data.set_src_port(srcPort); + break; + } + case tcp_dst_port: + { + uint dstPort = value.toUInt(&isOk); + if (isOk) + data.set_dst_port(dstPort); + break; + } + case tcp_seq_num: + { + uint seqNum = value.toUInt(&isOk); + if (isOk) + data.set_seq_num(seqNum); + break; + } + case tcp_ack_num: + { + uint ackNum = value.toUInt(&isOk); + if (isOk) + data.set_ack_num(ackNum); + break; + } + case tcp_hdrlen: + { + uint hdrLen = value.toUInt(&isOk); + if (isOk) + data.set_hdrlen_rsvd( + (data.hdrlen_rsvd() & 0x0F) | (hdrLen << 4)); + break; + } + case tcp_rsvd: + { + uint rsvd = value.toUInt(&isOk); + if (isOk) + data.set_hdrlen_rsvd( + (data.hdrlen_rsvd() & 0xF0) | (rsvd & 0x0F)); + break; + } + case tcp_flags: + { + uint flags = value.toUInt(&isOk); + if (isOk) + data.set_flags(flags); + break; + } + case tcp_window: + { + uint window = value.toUInt(&isOk); + if (isOk) + data.set_window(window); + break; + } + case tcp_cksum: + { + uint cksum = value.toUInt(&isOk); + if (isOk) + data.set_cksum(cksum); + break; + } + case tcp_urg_ptr: + { + uint urgPtr = value.toUInt(&isOk); + if (isOk) + data.set_urg_ptr(urgPtr); + break; + } + case tcp_is_override_src_port: + { + data.set_is_override_src_port(value.toBool()); + isOk = true; + break; + } + case tcp_is_override_dst_port: + { + data.set_is_override_dst_port(value.toBool()); + isOk = true; + break; + } + case tcp_is_override_hdrlen: + { + data.set_is_override_hdrlen(value.toBool()); + isOk = true; + break; + } + case tcp_is_override_cksum: + { + data.set_is_override_cksum(value.toBool()); + isOk = true; + break; + } + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + +_exit: + return isOk; } bool TcpProtocol::isProtocolFrameValueVariable() const @@ -421,53 +619,73 @@ void TcpProtocol::loadConfigWidget() { configWidget(); - configForm->leTcpSrcPort->setText(QString().setNum(data.src_port())); - configForm->leTcpDstPort->setText(QString().setNum(data.dst_port())); + configForm->leTcpSrcPort->setText( + fieldData(tcp_src_port, FieldValue).toString()); + configForm->cbTcpSrcPortOverride->setChecked( + fieldData(tcp_is_override_src_port, FieldValue).toBool()); - configForm->leTcpSeqNum->setText(QString().setNum(data.seq_num())); - configForm->leTcpAckNum->setText(QString().setNum(data.ack_num())); + configForm->leTcpDstPort->setText( + fieldData(tcp_dst_port, FieldValue).toString()); + configForm->cbTcpDstPortOverride->setChecked( + fieldData(tcp_is_override_dst_port, FieldValue).toBool()); - configForm->leTcpHdrLen->setText(fieldData(tcp_hdrlen, FieldValue).toString()); - configForm->cbTcpHdrLenOverride->setChecked(data.is_override_hdrlen()); + configForm->leTcpSeqNum->setText( + fieldData(tcp_seq_num, FieldValue).toString()); + configForm->leTcpAckNum->setText( + fieldData(tcp_ack_num, FieldValue).toString()); - configForm->leTcpWindow->setText(QString().setNum(data.window())); + configForm->leTcpHdrLen->setText( + fieldData(tcp_hdrlen, FieldValue).toString()); + configForm->cbTcpHdrLenOverride->setChecked( + fieldData(tcp_is_override_hdrlen, FieldValue).toBool()); + + configForm->leTcpWindow->setText( + fieldData(tcp_window, FieldValue).toString()); configForm->leTcpCksum->setText(QString("%1").arg( fieldData(tcp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); - configForm->cbTcpCksumOverride->setChecked(data.is_override_cksum()); + configForm->cbTcpCksumOverride->setChecked( + fieldData(tcp_is_override_cksum, FieldValue).toBool()); - configForm->leTcpUrgentPointer->setText(QString().setNum(data.urg_ptr())); - - configForm->cbTcpFlagsUrg->setChecked((data.flags() & TCP_FLAG_URG) > 0); - configForm->cbTcpFlagsAck->setChecked((data.flags() & TCP_FLAG_ACK) > 0); - configForm->cbTcpFlagsPsh->setChecked((data.flags() & TCP_FLAG_PSH) > 0); - configForm->cbTcpFlagsRst->setChecked((data.flags() & TCP_FLAG_RST) > 0); - configForm->cbTcpFlagsSyn->setChecked((data.flags() & TCP_FLAG_SYN) > 0); - configForm->cbTcpFlagsFin->setChecked((data.flags() & TCP_FLAG_FIN) > 0); + configForm->leTcpUrgentPointer->setText( + fieldData(tcp_urg_ptr, FieldValue).toString()); + + uint flags = fieldData(tcp_flags, FieldValue).toUInt(); + configForm->cbTcpFlagsUrg->setChecked((flags & TCP_FLAG_URG) > 0); + configForm->cbTcpFlagsAck->setChecked((flags & TCP_FLAG_ACK) > 0); + configForm->cbTcpFlagsPsh->setChecked((flags & TCP_FLAG_PSH) > 0); + configForm->cbTcpFlagsRst->setChecked((flags & TCP_FLAG_RST) > 0); + configForm->cbTcpFlagsSyn->setChecked((flags & TCP_FLAG_SYN) > 0); + configForm->cbTcpFlagsFin->setChecked((flags & TCP_FLAG_FIN) > 0); } void TcpProtocol::storeConfigWidget() { - bool isOk; int ff = 0; configWidget(); - data.set_src_port(configForm->leTcpSrcPort->text().toULong(&isOk)); - data.set_dst_port(configForm->leTcpDstPort->text().toULong(&isOk)); + setFieldData(tcp_src_port, configForm->leTcpSrcPort->text()); + setFieldData(tcp_is_override_src_port, + configForm->cbTcpSrcPortOverride->isChecked()); + setFieldData(tcp_dst_port, configForm->leTcpDstPort->text()); + setFieldData(tcp_is_override_dst_port, + configForm->cbTcpDstPortOverride->isChecked()); - data.set_seq_num(configForm->leTcpSeqNum->text().toULong(&isOk)); - data.set_ack_num(configForm->leTcpAckNum->text().toULong(&isOk)); + setFieldData(tcp_seq_num, configForm->leTcpSeqNum->text()); + setFieldData(tcp_ack_num, configForm->leTcpAckNum->text()); - data.set_hdrlen_rsvd((configForm->leTcpHdrLen->text().toULong(&isOk) << 4) & 0xF0); - data.set_is_override_hdrlen(configForm->cbTcpHdrLenOverride->isChecked()); + setFieldData(tcp_hdrlen, configForm->leTcpHdrLen->text()); + setFieldData(tcp_is_override_hdrlen, + configForm->cbTcpHdrLenOverride->isChecked()); - data.set_window(configForm->leTcpWindow->text().toULong(&isOk)); + setFieldData(tcp_window, configForm->leTcpWindow->text()); - data.set_cksum(configForm->leTcpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); - data.set_is_override_cksum(configForm->cbTcpCksumOverride->isChecked()); + setFieldData(tcp_cksum, configForm->leTcpCksum->text()); + setFieldData(tcp_is_override_cksum, + configForm->cbTcpCksumOverride->isChecked()); - data.set_urg_ptr(configForm->leTcpUrgentPointer->text().toULong(&isOk)); + setFieldData(tcp_urg_ptr, configForm->leTcpUrgentPointer->text()); if (configForm->cbTcpFlagsUrg->isChecked()) ff |= TCP_FLAG_URG; if (configForm->cbTcpFlagsAck->isChecked()) ff |= TCP_FLAG_ACK; @@ -475,6 +693,6 @@ void TcpProtocol::storeConfigWidget() if (configForm->cbTcpFlagsRst->isChecked()) ff |= TCP_FLAG_RST; if (configForm->cbTcpFlagsSyn->isChecked()) ff |= TCP_FLAG_SYN; if (configForm->cbTcpFlagsFin->isChecked()) ff |= TCP_FLAG_FIN; - data.set_flags(ff); + setFieldData(tcp_flags, ff); } diff --git a/common/tcp.h b/common/tcp.h index 3b32b35..265937a 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -57,6 +57,8 @@ private: tcp_cksum, tcp_urg_ptr, + tcp_is_override_src_port, + tcp_is_override_dst_port, tcp_is_override_hdrlen, tcp_is_override_cksum, @@ -76,9 +78,11 @@ public: virtual QString name() const; virtual QString shortName() const; + + virtual ProtocolIdType protocolIdType() const; virtual quint32 protocolId(ProtocolIdType type) const; - virtual int fieldCount() const; + virtual int fieldCount() const; virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, diff --git a/common/tcp.proto b/common/tcp.proto index 39d96be..3aa4382 100644 --- a/common/tcp.proto +++ b/common/tcp.proto @@ -22,22 +22,23 @@ import "protocol.proto"; package OstProto; // Tcp message Tcp { + optional bool is_override_src_port = 1; + optional bool is_override_dst_port = 2; + optional bool is_override_hdrlen = 3; + optional bool is_override_cksum = 4; - optional bool is_override_hdrlen = 1; - optional bool is_override_cksum = 2; + optional uint32 src_port = 5 [default = 49152]; + optional uint32 dst_port = 6 [default = 49153]; - optional uint32 src_port = 3 [default = 8902]; - optional uint32 dst_port = 4 [default = 80]; + optional uint32 seq_num = 7 [default = 129018]; + optional uint32 ack_num = 8; - optional uint32 seq_num = 5 [default = 129018]; - optional uint32 ack_num = 6; + optional uint32 hdrlen_rsvd = 9 [default = 0x50]; + optional uint32 flags = 10; - optional uint32 hdrlen_rsvd = 7 [default = 0x50]; - optional uint32 flags = 8; - - optional uint32 window = 9 [default = 1024]; - optional uint32 cksum = 10; - optional uint32 urg_ptr = 11; + optional uint32 window = 11 [default = 1024]; + optional uint32 cksum = 12; + optional uint32 urg_ptr = 13; } extend Protocol { diff --git a/common/tcp.ui b/common/tcp.ui index e19e9fb..6f3eee8 100644 --- a/common/tcp.ui +++ b/common/tcp.ui @@ -14,14 +14,18 @@ - + - Source Port + Override Source Port - + + + false + + @@ -48,14 +52,18 @@ - + - Destination Port + Override Destination Port - + + + false + + @@ -224,5 +232,37 @@ + + cbTcpSrcPortOverride + toggled(bool) + leTcpSrcPort + setEnabled(bool) + + + 159 + 16 + + + 178 + 18 + + + + + cbTcpDstPortOverride + toggled(bool) + leTcpDstPort + setEnabled(bool) + + + 147 + 45 + + + 180 + 44 + + + diff --git a/common/textproto.cpp b/common/textproto.cpp index 2f69f82..90327ea 100644 --- a/common/textproto.cpp +++ b/common/textproto.cpp @@ -83,7 +83,7 @@ quint32 TextProtocol::protocolId(ProtocolIdType type) const { switch(type) { - //case ProtocolIdTcpUdp: return data.port_num(); + case ProtocolIdTcpUdp: return data.port_num(); default:break; } @@ -220,7 +220,8 @@ _exit: int TextProtocol::protocolFrameSize(int streamIndex) const { - return fieldData(textProto_text, FieldFrameValue).toByteArray().size() ; + return fieldData(textProto_text, FieldFrameValue, streamIndex) + .toByteArray().size() ; } QWidget* TextProtocol::configWidget() diff --git a/common/textproto.proto b/common/textproto.proto index be4f246..8bb290b 100644 --- a/common/textproto.proto +++ b/common/textproto.proto @@ -27,7 +27,7 @@ message TextProtocol { kUtf8 = 0; } - optional uint32 port_num = 1 [default = 0]; + optional uint32 port_num = 1 [default = 80]; optional TextEncoding encoding = 2 [default = kUtf8]; optional string text = 3; } diff --git a/common/udp.cpp b/common/udp.cpp index 7bb74e3..4097ff8 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -73,6 +73,11 @@ QString UdpProtocol::shortName() const return QString("UDP"); } +AbstractProtocol::ProtocolIdType UdpProtocol::protocolIdType() const +{ + return ProtocolIdTcpUdp; +} + quint32 UdpProtocol::protocolId(ProtocolIdType type) const { switch(type) @@ -84,7 +89,7 @@ quint32 UdpProtocol::protocolId(ProtocolIdType type) const return AbstractProtocol::protocolId(type); } -int UdpProtocol::fieldCount() const +int UdpProtocol::fieldCount() const { return udp_fieldCount; } @@ -106,12 +111,16 @@ AbstractProtocol::FieldFlags UdpProtocol::fieldFlags(int index) const flags |= FieldIsCksum; break; + case udp_isOverrideSrcPort: + case udp_isOverrideDstPort: case udp_isOverrideTotLen: case udp_isOverrideCksum: flags |= FieldIsMeta; break; default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); break; } @@ -124,47 +133,81 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, switch (index) { case udp_srcPort: + { + quint16 srcPort; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + if (data.is_override_src_port()) + srcPort = data.src_port(); + else + srcPort = payloadProtocolId(ProtocolIdTcpUdp); + break; + default: + srcPort = 0; // avoid the 'maybe used unitialized' warning + break; + } switch(attrib) { case FieldName: return QString("Source Port"); case FieldValue: - return data.src_port(); + return srcPort; case FieldTextValue: - return QString("%1").arg(data.src_port()); + return QString("%1").arg(srcPort); case FieldFrameValue: { QByteArray fv; fv.resize(2); - qToBigEndian((quint16) data.src_port(), (uchar*) fv.data()); + qToBigEndian(srcPort, (uchar*) fv.data()); return fv; } default: break; } break; - + } case udp_dstPort: + { + quint16 dstPort; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + if (data.is_override_dst_port()) + dstPort = data.dst_port(); + else + dstPort = payloadProtocolId(ProtocolIdTcpUdp); + break; + default: + dstPort = 0; // avoid the 'maybe used unitialized' warning + break; + } switch(attrib) { case FieldName: return QString("Destination Port"); case FieldValue: - return data.dst_port(); + return dstPort; case FieldTextValue: - return QString("%1").arg(data.dst_port()); + return QString("%1").arg(dstPort); case FieldFrameValue: { QByteArray fv; fv.resize(2); - qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data()); + qToBigEndian(dstPort, (uchar*) fv.data()); return fv; } default: break; } break; - + } case udp_totLen: { @@ -253,30 +296,132 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, } break; } + // Meta fields - case udp_isOverrideTotLen: - case udp_isOverrideCksum: + case udp_isOverrideSrcPort: + { switch(attrib) { - case FieldIsMeta: - return true; + case FieldValue: + return data.is_override_src_port(); default: break; } break; + } + case udp_isOverrideDstPort: + { + switch(attrib) + { + case FieldValue: + return data.is_override_dst_port(); + default: + break; + } + break; + } + case udp_isOverrideTotLen: + { + switch(attrib) + { + case FieldValue: + return data.is_override_totlen(); + default: + break; + } + break; + } + case udp_isOverrideCksum: + { + switch(attrib) + { + case FieldValue: + return data.is_override_cksum(); + default: + break; + } + break; + } default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); break; } return AbstractProtocol::fieldData(index, attrib, streamIndex); } -bool UdpProtocol::setFieldData(int /*index*/, const QVariant &/*value*/, - FieldAttrib /*attrib*/) +bool UdpProtocol::setFieldData(int index, const QVariant& value, + FieldAttrib attrib) { - //! implement UdpProtocol::setFieldData() - return false; + bool isOk = false; + + if (attrib != FieldValue) + goto _exit; + + switch (index) + { + case udp_isOverrideSrcPort: + { + data.set_is_override_src_port(value.toBool()); + isOk = true; + break; + } + case udp_isOverrideDstPort: + { + data.set_is_override_dst_port(value.toBool()); + isOk = true; + break; + } + case udp_isOverrideTotLen: + { + data.set_is_override_totlen(value.toBool()); + isOk = true; + break; + } + case udp_isOverrideCksum: + { + data.set_is_override_cksum(value.toBool()); + isOk = true; + break; + } + case udp_srcPort: + { + uint srcPort = value.toUInt(&isOk); + if (isOk) + data.set_src_port(srcPort); + break; + } + case udp_dstPort: + { + uint dstPort = value.toUInt(&isOk); + if (isOk) + data.set_dst_port(dstPort); + break; + } + case udp_totLen: + { + uint totLen = value.toUInt(&isOk); + if (isOk) + data.set_totlen(totLen); + break; + } + case udp_cksum: + { + uint cksum = value.toUInt(&isOk); + if (isOk) + data.set_cksum(cksum); + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + +_exit: + return isOk; } bool UdpProtocol::isProtocolFrameValueVariable() const @@ -301,15 +446,24 @@ void UdpProtocol::loadConfigWidget() { configWidget(); - configForm->leUdpSrcPort->setText(fieldData(udp_srcPort, FieldValue).toString()); - configForm->leUdpDstPort->setText(fieldData(udp_dstPort, FieldValue).toString()); + configForm->leUdpSrcPort->setText( + fieldData(udp_srcPort, FieldValue).toString()); + configForm->cbUdpSrcPortOverride->setChecked( + fieldData(udp_isOverrideSrcPort, FieldValue).toBool()); + configForm->leUdpDstPort->setText( + fieldData(udp_dstPort, FieldValue).toString()); + configForm->cbUdpDstPortOverride->setChecked( + fieldData(udp_isOverrideDstPort, FieldValue).toBool()); - configForm->leUdpLength->setText(fieldData(udp_totLen, FieldValue).toString()); - configForm->cbUdpLengthOverride->setChecked(data.is_override_totlen()); + configForm->leUdpLength->setText( + fieldData(udp_totLen, FieldValue).toString()); + configForm->cbUdpLengthOverride->setChecked( + fieldData(udp_isOverrideTotLen, FieldValue).toBool()); configForm->leUdpCksum->setText(QString("%1").arg( fieldData(udp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); - configForm->cbUdpCksumOverride->setChecked(data.is_override_cksum()); + configForm->cbUdpCksumOverride->setChecked( + fieldData(udp_isOverrideCksum, FieldValue).toBool()); } void UdpProtocol::storeConfigWidget() @@ -318,13 +472,20 @@ void UdpProtocol::storeConfigWidget() configWidget(); - data.set_src_port(configForm->leUdpSrcPort->text().toULong(&isOk)); - data.set_dst_port(configForm->leUdpDstPort->text().toULong(&isOk)); + setFieldData(udp_srcPort, configForm->leUdpSrcPort->text()); + setFieldData(udp_isOverrideSrcPort, + configForm->cbUdpSrcPortOverride->isChecked()); + setFieldData(udp_dstPort, configForm->leUdpDstPort->text()); + setFieldData(udp_isOverrideDstPort, + configForm->cbUdpDstPortOverride->isChecked()); - data.set_totlen(configForm->leUdpLength->text().toULong(&isOk)); - data.set_is_override_totlen(configForm->cbUdpLengthOverride->isChecked()); + setFieldData(udp_totLen, configForm->leUdpLength->text()); + setFieldData(udp_isOverrideTotLen, + configForm->cbUdpLengthOverride->isChecked()); - data.set_cksum(configForm->leUdpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); - data.set_is_override_cksum(configForm->cbUdpCksumOverride->isChecked()); + setFieldData(udp_cksum, configForm->leUdpCksum->text().toUInt( + &isOk, BASE_HEX)); + setFieldData(udp_isOverrideCksum, + configForm->cbUdpCksumOverride->isChecked()); } diff --git a/common/udp.h b/common/udp.h index 86c2ca8..623e999 100644 --- a/common/udp.h +++ b/common/udp.h @@ -44,6 +44,8 @@ private: udp_totLen, udp_cksum, + udp_isOverrideSrcPort, + udp_isOverrideDstPort, udp_isOverrideTotLen, udp_isOverrideCksum, @@ -63,9 +65,11 @@ public: virtual QString name() const; virtual QString shortName() const; + + virtual ProtocolIdType protocolIdType() const; virtual quint32 protocolId(ProtocolIdType type) const; - virtual int fieldCount() const; + virtual int fieldCount() const; virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, diff --git a/common/udp.proto b/common/udp.proto index 5c30eac..8852c11 100644 --- a/common/udp.proto +++ b/common/udp.proto @@ -23,13 +23,15 @@ package OstProto; // UDP message Udp { - optional bool is_override_totlen = 1; - optional bool is_override_cksum = 2; + optional bool is_override_src_port = 1; + optional bool is_override_dst_port = 2; + optional bool is_override_totlen = 3; + optional bool is_override_cksum = 4; - optional uint32 src_port = 3 [default = 8902]; - optional uint32 dst_port = 4 [default = 80]; - optional uint32 totlen = 5; - optional uint32 cksum = 6; + optional uint32 src_port = 5 [default = 49152]; + optional uint32 dst_port = 6 [default = 49153]; + optional uint32 totlen = 7; + optional uint32 cksum = 8; } extend Protocol { diff --git a/common/udp.ui b/common/udp.ui index c5c9862..ab979e9 100644 --- a/common/udp.ui +++ b/common/udp.ui @@ -5,7 +5,7 @@ 0 0 - 217 + 246 144 @@ -16,24 +16,32 @@ - + - Source Port + Override Source Port - + + + false + + - + - Destination Port + Override Destination Port - + + + false + + @@ -109,8 +117,8 @@ 63 - 149 - 63 + 209 + 81 @@ -125,8 +133,40 @@ 106 - 158 - 106 + 209 + 107 + + + + + cbUdpDstPortOverride + toggled(bool) + leUdpDstPort + setEnabled(bool) + + + 131 + 43 + + + 166 + 46 + + + + + cbUdpSrcPortOverride + toggled(bool) + leUdpSrcPort + setEnabled(bool) + + + 125 + 21 + + + 167 + 20 From 564b30955bd317aaa6ec633eab691d1fa363ce35 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 8 May 2010 20:44:33 +0530 Subject: [PATCH 71/98] Removed hardcoded paths from pbrpc.pro; made MainWindow default size smaller --- client/mainwindow.ui | 6 +++--- rpc/pbrpc.pro | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/client/mainwindow.ui b/client/mainwindow.ui index 28861d4..45db008 100644 --- a/client/mainwindow.ui +++ b/client/mainwindow.ui @@ -5,8 +5,8 @@ 0 0 - 800 - 650 + 700 + 550 @@ -18,7 +18,7 @@ 0 0 - 800 + 700 21 diff --git a/rpc/pbrpc.pro b/rpc/pbrpc.pro index bcd5b8d..27ec61b 100644 --- a/rpc/pbrpc.pro +++ b/rpc/pbrpc.pro @@ -2,7 +2,6 @@ TEMPLATE = lib CONFIG += qt staticlib QT += network DEFINES += HAVE_REMOTE -INCLUDEPATH += "c:\msys\1.0\local\include" -LIBS += -L"C:\msys\1.0\local\lib" -lprotobuf +LIBS += -lprotobuf HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h SOURCES += rpcserver.cpp pbrpcchannel.cpp From 46cebefb19fefdc4d45a4f3fd233c482b99dca3e Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 9 May 2010 10:28:58 +0530 Subject: [PATCH 72/98] IP4over4 implemented as a "combo" protocol; added IP 4over4 as a L3 protocol in StreamConfigDialog. Also temporarily masked a change introduced in r59ec which triggers a crash if you click "cancel" in StreamConfigDialog with the "Protocol Data" tab open --- client/streamconfigdialog.cpp | 4 ++ client/streamconfigdialog.ui | 17 +++++- common/comboprotocol.h | 5 +- common/ip4.ui | 24 ++------ common/ip4over4.h | 101 ++++++++++++++++++++++++++++++++++ common/ip4over4.proto | 37 +++++++++++++ common/ostproto.pro | 2 + common/protocol.proto | 1 + common/protocolmanager.cpp | 8 ++- 9 files changed, 173 insertions(+), 26 deletions(-) create mode 100644 common/ip4over4.h create mode 100644 common/ip4over4.proto diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 7789f8d..6d336e3 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -200,6 +200,8 @@ void StreamConfigDialog::setupUiExtra() bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF); bgProto[ProtoL3]->addButton(rbL3Arp, OstProto::Protocol::kArpFieldNumber); + bgProto[ProtoL3]->addButton(rbL3Ip4over4, + OstProto::Protocol::kIp4over4FieldNumber); bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther); #endif @@ -952,8 +954,10 @@ void StreamConfigDialog::on_tbProtocolData_currentChanged(int /*index*/) // Refresh protocol widgets in case there is any dependent data between // protocols e.g. TCP/UDP port numbers are dependent on Port/Protocol // selection in TextProtocol +#if 0 // FIXME: temp mask to avoid crash till we fix it mpStream->storeProtocolWidgets(); mpStream->loadProtocolWidgets(); +#endif } void StreamConfigDialog::on_pbOk_clicked() diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index f64c848..687b970 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,7 +8,7 @@ 0 0 - 569 + 579 481 @@ -173,7 +173,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff 0 0 - 527 + 537 243 @@ -339,6 +339,19 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + false + + + IP 4over4 + + + false + + + + false diff --git a/common/comboprotocol.h b/common/comboprotocol.h index c6efa0a..c7d4053 100644 --- a/common/comboprotocol.h +++ b/common/comboprotocol.h @@ -25,7 +25,7 @@ along with this program. If not, see template class ComboProtocol : public AbstractProtocol { -private: +protected: ProtoA *protoA; ProtoB *protoB; QWidget *configForm; @@ -82,8 +82,7 @@ public: // NOTE: To use protoX->protoDataCopyFrom() we need to arrange // so that it sees its own protocolNumber() - but since the - // input param 'protocol' is 'const', we make a copy first - + // input param 'protocol' is 'const', we work on a copy proto.CopyFrom(protocol); proto.mutable_protocol_id()->set_id(protoA->protocolNumber()); diff --git a/common/ip4.ui b/common/ip4.ui index a3135e7..c457a2d 100644 --- a/common/ip4.ui +++ b/common/ip4.ui @@ -5,8 +5,8 @@ 0 0 - 527 - 296 + 493 + 308 @@ -35,7 +35,8 @@ - Override Header Length (x4) + Override Header +Length (x4) @@ -66,16 +67,6 @@ - - - - false - - - ... - - - @@ -106,13 +97,6 @@ - - - - Qt::Vertical - - - diff --git a/common/ip4over4.h b/common/ip4over4.h new file mode 100644 index 0000000..cf6c5f5 --- /dev/null +++ b/common/ip4over4.h @@ -0,0 +1,101 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _IP_4_OVER_4_H +#define _IP_4_OVER_4_H + +#include "ip4over4.pb.h" + +#include "comboprotocol.h" +#include "ip4.h" + +typedef ComboProtocol Ip4over4Combo; + +class Ip4over4Protocol : public Ip4over4Combo +{ +public: + Ip4over4Protocol(StreamBase *stream, AbstractProtocol *parent = 0) + : Ip4over4Combo(stream, parent) + { + } + + static Ip4over4Protocol* createInstance(StreamBase *stream, + AbstractProtocol *parent) + { + return new Ip4over4Protocol(stream, parent); + } + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const + { + OstProto::Protocol tempProto; + + protoA->protoDataCopyInto(tempProto); + protocol.MutableExtension(OstProto::ip4over4) + ->MutableExtension(OstProto::ip4_outer) + ->CopyFrom(tempProto.GetExtension(OstProto::ip4)); + + tempProto.Clear(); + + protoB->protoDataCopyInto(tempProto); + protocol.MutableExtension(OstProto::ip4over4) + ->MutableExtension(OstProto::ip4_inner) + ->CopyFrom(tempProto.GetExtension(OstProto::ip4)); + + protocol.mutable_protocol_id()->set_id(protocolNumber()); + } + + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) + { + if (protocol.protocol_id().id() == protocolNumber() + && protocol.HasExtension(OstProto::ip4over4)) + { + OstProto::Protocol tempProto; + + // NOTE: To use protoX->protoDataCopyFrom() we need to arrange + // so that it sees its own protocolNumber() and its own extension + // in 'protocol' + tempProto.mutable_protocol_id()->set_id(protoA->protocolNumber()); + tempProto.MutableExtension(OstProto::ip4)->CopyFrom( + protocol.GetExtension(OstProto::ip4over4).GetExtension( + OstProto::ip4_outer)); + protoA->protoDataCopyFrom(tempProto); + + tempProto.Clear(); + + tempProto.mutable_protocol_id()->set_id(protoB->protocolNumber()); + tempProto.MutableExtension(OstProto::ip4)->CopyFrom( + protocol.GetExtension(OstProto::ip4over4).GetExtension( + OstProto::ip4_inner)); + protoB->protoDataCopyFrom(tempProto); + } + } + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const + { + // For a Pseudo IP cksum, we assume it is the succeeding protocol + // that is requesting it and hence return protoB's cksum; + if (cksumType == CksumIpPseudo) + return protoB->protocolFrameCksum(streamIndex, cksumType); + + return Ip4over4Combo::protocolFrameCksum(streamIndex, cksumType); + } +}; + +#endif diff --git a/common/ip4over4.proto b/common/ip4over4.proto new file mode 100644 index 0000000..df25a32 --- /dev/null +++ b/common/ip4over4.proto @@ -0,0 +1,37 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +import "protocol.proto"; +import "ip4.proto"; + +package OstProto; + +// IP 4over4 (also called IPIP) +message Ip4over4 { + extensions 1 to 2; +} + +extend Ip4over4 { + optional Ip4 ip4_outer = 1; + optional Ip4 ip4_inner = 2; +} + +extend Protocol { + optional Ip4over4 ip4over4 = 132; +} diff --git a/common/ostproto.pro b/common/ostproto.pro index 33567f8..89510ce 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -34,6 +34,7 @@ PROTOS += \ vlanstack.proto \ arp.proto \ ip4.proto \ + ip4over4.proto \ icmp.proto \ tcp.proto \ udp.proto \ @@ -60,6 +61,7 @@ HEADERS += \ vlanstack.h \ arp.h \ ip4.h \ + ip4over4.h \ icmp.h \ tcp.h \ udp.h \ diff --git a/common/protocol.proto b/common/protocol.proto index bafbe8a..6f88c78 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -101,6 +101,7 @@ message Protocol { kIp4FieldNumber = 130; kArpFieldNumber = 131; + kIp4over4FieldNumber = 132; kTcpFieldNumber = 140; kUdpFieldNumber = 141; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index b543ac0..e8e6570 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -33,6 +33,7 @@ along with this program. If not, see #include "vlanstack.h" #include "arp.h" #include "ip4.h" +#include "ip4over4.h" #include "icmp.h" #include "tcp.h" #include "udp.h" @@ -49,6 +50,7 @@ ProtocolManager::ProtocolManager() */ registerProtocol(OstProto::Protocol::kMacFieldNumber, (void*) MacProtocol::createInstance); + registerProtocol(OstProto::Protocol::kEth2FieldNumber, (void*) Eth2Protocol::createInstance); registerProtocol(OstProto::Protocol::kDot3FieldNumber, @@ -61,23 +63,27 @@ ProtocolManager::ProtocolManager() (void*) Dot2LlcProtocol::createInstance); registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber, (void*) Dot2SnapProtocol::createInstance); + registerProtocol(OstProto::Protocol::kSvlanFieldNumber, (void*) SVlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanFieldNumber, (void*) VlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanStackFieldNumber, (void*) VlanStackProtocol::createInstance); + registerProtocol(OstProto::Protocol::kArpFieldNumber, (void*) ArpProtocol::createInstance); registerProtocol(OstProto::Protocol::kIp4FieldNumber, (void*) Ip4Protocol::createInstance); + registerProtocol(OstProto::Protocol::kIp4over4FieldNumber, + (void*) Ip4over4Protocol::createInstance); + registerProtocol(OstProto::Protocol::kIcmpFieldNumber, (void*) IcmpProtocol::createInstance); registerProtocol(OstProto::Protocol::kTcpFieldNumber, (void*) TcpProtocol::createInstance); registerProtocol(OstProto::Protocol::kUdpFieldNumber, (void*) UdpProtocol::createInstance); - registerProtocol(OstProto::Protocol::kTextProtocolFieldNumber, (void*) TextProtocol::createInstance); From ed13bba83be854f8326bddf870b4afcd46e40d24 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 16 May 2010 11:46:41 +0530 Subject: [PATCH 73/98] Fixed Segfault caused by uninitialized ModelTester pointers in Release mode (Fixes issue 5) --- client/portgrouplist.cpp | 7 +++++-- client/streamconfigdialog.cpp | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/client/portgrouplist.cpp b/client/portgrouplist.cpp index a8e688c..cfdc74b 100644 --- a/client/portgrouplist.cpp +++ b/client/portgrouplist.cpp @@ -29,8 +29,11 @@ PortGroupList::PortGroupList() { PortGroup *pg; -#ifndef QT_NO_DEBUG - // TODO(LOW): Remove +#ifdef QT_NO_DEBUG + streamModelTester_ = NULL; + portModelTester_ = NULL; + portStatsModelTester_ = NULL; +#else streamModelTester_ = new ModelTest(getStreamModel()); portModelTester_ = new ModelTest(getPortModel()); portStatsModelTester_ = new ModelTest(getPortStatsModel()); diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 6d336e3..2171701 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -136,7 +136,9 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, LoadCurrentStream(); mpPacketModel = new PacketModel(this); tvPacketTree->setModel(mpPacketModel); -#ifndef QT_NO_DEBUG +#ifdef QT_NO_DEBUG + mpPacketModelTester = NULL; +#else mpPacketModelTester = new ModelTest(mpPacketModel); #endif tvPacketTree->header()->hide(); From 4a70d52e3e03a0b7fce1e8e58c2e317163dbec0c Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 22 May 2010 22:02:46 +0530 Subject: [PATCH 74/98] Implemented IPv6 protocol; found and fixed a bug in AbstractProtocol::protocolFrameValue() in the process --- client/streamconfigdialog.cpp | 5 +- common/abstractprotocol.cpp | 13 +- common/ip6.cpp | 939 ++++++++++++++++++++++++++++++++++ common/ip6.h | 130 +++++ common/ip6.proto | 61 +++ common/ip6.ui | 467 +++++++++++++++++ common/ipv6addressvalidator.h | 75 +++ common/ostproto.pro | 4 + common/protocol.proto | 1 + common/protocolmanager.cpp | 3 + 10 files changed, 1691 insertions(+), 7 deletions(-) create mode 100644 common/ip6.cpp create mode 100644 common/ip6.h create mode 100644 common/ip6.proto create mode 100644 common/ip6.ui create mode 100644 common/ipv6addressvalidator.h diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 2171701..e4544e5 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -147,8 +147,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // TODO(MED): - //! \todo Implement then enable these protocols - IPv6, IGMP - rbL3Ipv6->setHidden(true); + //! \todo Implement then enable these protocols - IGMP rbL4Igmp->setHidden(true); //! \todo Enable navigation of streams pbPrev->setDisabled(true); @@ -200,7 +199,7 @@ void StreamConfigDialog::setupUiExtra() #else bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone); bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); - bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Ipv6, OstProto::Protocol::kIp6FieldNumber); bgProto[ProtoL3]->addButton(rbL3Arp, OstProto::Protocol::kArpFieldNumber); bgProto[ProtoL3]->addButton(rbL3Ip4over4, OstProto::Protocol::kIp4over4FieldNumber); diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 8ed7513..0dc3178 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -249,7 +249,7 @@ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const \note If a subclass uses any of the below functions to derive FieldFrameValue, the subclass should handle and return a value for - FieldBitSize to prevent endless recrusion - + FieldBitSize to prevent endless recursion - - protocolFrameCksum() - protocolFramePayloadSize() */ @@ -454,7 +454,10 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) } else field = fieldData(i, FieldFrameValue, streamIndex).toByteArray(); - qDebug("<<< %d, %d/%d >>>>", proto.size(), bits, field.size()); + qDebug("<<< (%d, %db) %s >>>", proto.size(), lastbitpos, + QString(proto.toHex()).toAscii().constData()); + qDebug(" < (%db/%dB) %s >", bits, field.size(), + QString(field.toHex()).toAscii().constData()); if (bits == (uint) field.size() * 8) { @@ -465,10 +468,12 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) Q_ASSERT(field.size() > 0); char c = proto[proto.size() - 1]; - proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos); + proto[proto.size() - 1] = + c | ((uchar)field.at(0) >> lastbitpos); for (int j = 0; j < field.size() - 1; j++) proto.append(field.at(j) << lastbitpos | - field.at(j+1) >> lastbitpos); + (uchar)field.at(j+1) >> lastbitpos); + proto.append(field.at(field.size() - 1) << lastbitpos); } } else if (bits < (uint) field.size() * 8) diff --git a/common/ip6.cpp b/common/ip6.cpp new file mode 100644 index 0000000..ea1f22c --- /dev/null +++ b/common/ip6.cpp @@ -0,0 +1,939 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#include "ip6.h" + +#include "ipv6addressvalidator.h" + +#include +#include + +Ip6ConfigForm::Ip6ConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + version->setValidator(new QIntValidator(0, 0xF, this)); + payloadLength->setValidator(new QIntValidator(0, 0xFFFF, this)); + hopLimit->setValidator(new QIntValidator(0, 0xFF, this)); + + srcAddr->setValidator(new IPv6AddressValidator(this)); + srcAddrCount->setValidator(new QIntValidator(this)); + //srcAddrPrefix->setValidator(new QIntValidator(0, 128, this)); + + dstAddr->setValidator(new IPv6AddressValidator(this)); + dstAddrCount->setValidator(new QIntValidator(this)); + //dstAddrPrefix->setValidator(new QIntValidator(0, 128, this)); +} + +void Ip6ConfigForm::on_srcAddr_editingFinished() +{ + srcAddr->setText(QHostAddress(srcAddr->text()).toString()); +} + +void Ip6ConfigForm::on_dstAddr_editingFinished() +{ + dstAddr->setText(QHostAddress(dstAddr->text()).toString()); +} + +void Ip6ConfigForm::on_srcAddrModeCombo_currentIndexChanged(int index) +{ + bool enabled = (index > 0); + + srcAddrCount->setEnabled(enabled); + srcAddrPrefix->setEnabled(enabled); +} + +void Ip6ConfigForm::on_dstAddrModeCombo_currentIndexChanged(int index) +{ + bool enabled = (index > 0); + + dstAddrCount->setEnabled(enabled); + dstAddrPrefix->setEnabled(enabled); +} + +Ip6Protocol::Ip6Protocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) +{ + /* The configWidget is created lazily */ + configForm = NULL; +} + +Ip6Protocol::~Ip6Protocol() +{ + delete configForm; +} + +AbstractProtocol* Ip6Protocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) +{ + return new Ip6Protocol(stream, parent); +} + +quint32 Ip6Protocol::protocolNumber() const +{ + return OstProto::Protocol::kIp6FieldNumber; +} + +void Ip6Protocol::protoDataCopyInto(OstProto::Protocol &protocol) const +{ + protocol.MutableExtension(OstProto::ip6)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void Ip6Protocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::ip6)) + data.MergeFrom(protocol.GetExtension(OstProto::ip6)); +} + +QString Ip6Protocol::name() const +{ + return QString("Internet Protocol ver 6"); +} + +QString Ip6Protocol::shortName() const +{ + return QString("IPv6"); +} + +AbstractProtocol::ProtocolIdType Ip6Protocol::protocolIdType() const +{ + return ProtocolIdIp; +} + +quint32 Ip6Protocol::protocolId(ProtocolIdType type) const +{ + switch(type) + { + case ProtocolIdEth: return 0x86dd; + case ProtocolIdIp: return 0x29; + default:break; + } + + return AbstractProtocol::protocolId(type); +} + +int Ip6Protocol::fieldCount() const +{ + return ip6_fieldCount; +} + +AbstractProtocol::FieldFlags Ip6Protocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case ip6_version: + case ip6_trafficClass: + case ip6_flowLabel: + case ip6_payloadLength: + case ip6_nextHeader: + case ip6_hopLimit: + case ip6_srcAddress: + case ip6_dstAddress: + break; + + case ip6_isOverrideVersion: + case ip6_isOverridePayloadLength: + case ip6_isOverrideNextHeader: + + case ip6_srcAddrMode: + case ip6_srcAddrCount: + case ip6_srcAddrPrefix: + + case ip6_dstAddrMode: + case ip6_dstAddrCount: + case ip6_dstAddrPrefix: + flags |= FieldIsMeta; + break; + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return flags; +} + +QVariant Ip6Protocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case ip6_version: + { + quint8 ver; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + if (data.is_override_version()) + ver = data.version() & 0xF; + else + ver = 0x6; + break; + default: + ver = 0; // avoid the 'maybe used unitialized' warning + break; + } + switch(attrib) + { + case FieldName: + return QString("Version"); + case FieldValue: + return ver; + case FieldTextValue: + return QString("%1").arg(ver); + case FieldFrameValue: + return QByteArray(1, char(ver)); + case FieldBitSize: + return 4; + default: + break; + } + break; + } + case ip6_trafficClass: + { + switch(attrib) + { + case FieldName: + return QString("Traffic Class"); + case FieldValue: + return data.traffic_class() & 0xFF; + case FieldTextValue: + return QString("%1").arg(data.traffic_class() & 0xFF, + 2, BASE_HEX, QChar('0')); + case FieldFrameValue: + return QByteArray(1, char(data.traffic_class() & 0xFF)); + default: + break; + } + break; + } + case ip6_flowLabel: + { + switch(attrib) + { + case FieldName: + return QString("Flow Label"); + case FieldValue: + return data.flow_label() & 0xFFFFF; + case FieldTextValue: + return QString("%1").arg(data.flow_label() & 0xFFFFF, + 5, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(4); + qToBigEndian((quint32) data.flow_label() & 0xFFFFF, + (uchar*) fv.data()); + fv = fv.right(3); + return fv; + } + case FieldBitSize: + return 20; + default: + break; + } + break; + } + case ip6_payloadLength: + { + quint16 len; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + if (data.is_override_payload_length()) + len = data.payload_length(); + else + len = protocolFramePayloadSize(streamIndex); + break; + default: + len = 0; // avoid the 'maybe used unitialized' warning + break; + } + switch(attrib) + { + case FieldName: + return QString("Payload Length"); + case FieldValue: + return len; + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian(len, (uchar*) fv.data()); + return fv; + } + case FieldTextValue: + return QString("%1").arg(len); + case FieldBitSize: + return 16; + default: + break; + } + break; + } + case ip6_nextHeader: + { + quint8 nextHdr; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + if (data.is_override_next_header()) + nextHdr = data.next_header(); + else + nextHdr = payloadProtocolId(ProtocolIdIp); + break; + default: + nextHdr = 0; // avoid the 'maybe used unitialized' warning + break; + } + switch(attrib) + { + case FieldName: + return QString("Next Header"); + case FieldValue: + return nextHdr; + case FieldTextValue: + return QString("%1").arg(nextHdr, 2, BASE_HEX, QChar('0')); + case FieldFrameValue: + return QByteArray(1, char(nextHdr)); + default: + break; + } + break; + } + case ip6_hopLimit: + { + switch(attrib) + { + case FieldName: + return QString("Hop Limit"); + case FieldValue: + return data.hop_limit() & 0xFF; + case FieldTextValue: + return QString("%1").arg(data.hop_limit() & 0xFF); + case FieldFrameValue: + return QByteArray(1, char(data.hop_limit() & 0xFF)); + default: + break; + } + break; + } + + case ip6_srcAddress: + { + int u, p, q; + quint64 maskHi = 0, maskLo = 0; + quint64 prefixHi, prefixLo; + quint64 hostHi, hostLo; + quint64 srcHi = 0, srcLo = 0; + + switch(data.src_addr_mode()) + { + case OstProto::Ip6::kFixed: + srcHi = data.src_addr_hi(); + srcLo = data.src_addr_lo(); + break; + case OstProto::Ip6::kIncHost: + case OstProto::Ip6::kDecHost: + case OstProto::Ip6::kRandomHost: + u = streamIndex % data.src_addr_count(); + if (data.src_addr_prefix() > 64) { + p = 64; + q = data.src_addr_prefix() - 64; + } else { + p = data.src_addr_prefix(); + q = 0; + } + if (p > 0) + maskHi = ~((quint64(1) << p) - 1); + if (q > 0) + maskLo = ~((quint64(1) << q) - 1); + prefixHi = data.src_addr_hi() & maskHi; + prefixLo = data.src_addr_lo() & maskLo; + if (data.src_addr_mode() == OstProto::Ip6::kIncHost) { + hostHi = ((data.src_addr_hi() & ~maskHi) + u) & ~maskHi; + hostLo = ((data.src_addr_lo() & ~maskLo) + u) & ~maskLo; + } + else if (data.src_addr_mode() == OstProto::Ip6::kDecHost) { + hostHi = ((data.src_addr_hi() & ~maskHi) - u) & ~maskHi; + hostLo = ((data.src_addr_lo() & ~maskLo) - u) & ~maskLo; + } + else if (data.src_addr_mode()==OstProto::Ip6::kRandomHost) { + hostHi = qrand() & ~maskHi; + hostLo = qrand() & ~maskLo; + } + srcHi = prefixHi | hostHi; + srcLo = prefixLo | hostLo; + break; + default: + qWarning("Unhandled src_addr_mode = %d", + data.src_addr_mode()); + } + + switch(attrib) + { + case FieldName: + return QString("Source"); + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + { + QByteArray fv; + fv.resize(16); + qToBigEndian(srcHi, (uchar*) fv.data()); + qToBigEndian(srcLo, (uchar*) (fv.data() + 8)); + if (attrib == FieldTextValue) + return QHostAddress((quint8*)fv.constData()).toString(); + else + return fv; + } + default: + break; + } + break; + } + + case ip6_dstAddress: + { + int u, p, q; + quint64 maskHi = 0, maskLo = 0; + quint64 prefixHi, prefixLo; + quint64 hostHi, hostLo; + quint64 dstHi = 0, dstLo = 0; + + switch(data.dst_addr_mode()) + { + case OstProto::Ip6::kFixed: + dstHi = data.dst_addr_hi(); + dstLo = data.dst_addr_lo(); + break; + case OstProto::Ip6::kIncHost: + case OstProto::Ip6::kDecHost: + case OstProto::Ip6::kRandomHost: + u = streamIndex % data.dst_addr_count(); + if (data.dst_addr_prefix() > 64) { + p = 64; + q = data.dst_addr_prefix() - 64; + } else { + p = data.dst_addr_prefix(); + q = 0; + } + if (p > 0) + maskHi = ~((quint64(1) << p) - 1); + if (q > 0) + maskLo = ~((quint64(1) << q) - 1); + prefixHi = data.dst_addr_hi() & maskHi; + prefixLo = data.dst_addr_lo() & maskLo; + if (data.dst_addr_mode() == OstProto::Ip6::kIncHost) { + hostHi = ((data.dst_addr_hi() & ~maskHi) + u) & ~maskHi; + hostLo = ((data.dst_addr_lo() & ~maskLo) + u) & ~maskLo; + } + else if (data.dst_addr_mode() == OstProto::Ip6::kDecHost) { + hostHi = ((data.dst_addr_hi() & ~maskHi) - u) & ~maskHi; + hostLo = ((data.dst_addr_lo() & ~maskLo) - u) & ~maskLo; + } + else if (data.dst_addr_mode()==OstProto::Ip6::kRandomHost) { + hostHi = qrand() & ~maskHi; + hostLo = qrand() & ~maskLo; + } + dstHi = prefixHi | hostHi; + dstLo = prefixLo | hostLo; + break; + default: + qWarning("Unhandled dst_addr_mode = %d", + data.dst_addr_mode()); + } + + switch(attrib) + { + case FieldName: + return QString("Destination"); + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + { + QByteArray fv; + fv.resize(16); + qToBigEndian(dstHi, (uchar*) fv.data()); + qToBigEndian(dstLo, (uchar*) (fv.data() + 8)); + if (attrib == FieldTextValue) + return QHostAddress((quint8*)fv.constData()).toString(); + else + return fv; + } + default: + break; + } + break; + } + + // Meta-Fields + case ip6_isOverrideVersion: + { + switch(attrib) + { + case FieldValue: + return data.is_override_version(); + default: + break; + } + break; + } + case ip6_isOverridePayloadLength: + { + switch(attrib) + { + case FieldValue: + return data.is_override_payload_length(); + default: + break; + } + break; + } + case ip6_isOverrideNextHeader: + { + switch(attrib) + { + case FieldValue: + return data.is_override_next_header(); + default: + break; + } + break; + } + + case ip6_srcAddrMode: + { + switch(attrib) + { + case FieldValue: + return data.src_addr_mode(); + default: + break; + } + break; + } + case ip6_srcAddrCount: + { + switch(attrib) + { + case FieldValue: + return data.src_addr_count(); + default: + break; + } + break; + } + case ip6_srcAddrPrefix: + { + switch(attrib) + { + case FieldValue: + return data.src_addr_prefix(); + default: + break; + } + break; + } + + case ip6_dstAddrMode: + { + switch(attrib) + { + case FieldValue: + return data.dst_addr_mode(); + default: + break; + } + break; + } + case ip6_dstAddrCount: + { + switch(attrib) + { + case FieldValue: + return data.dst_addr_count(); + default: + break; + } + break; + } + case ip6_dstAddrPrefix: + { + switch(attrib) + { + case FieldValue: + return data.dst_addr_prefix(); + default: + break; + } + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool Ip6Protocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + bool isOk = false; + + if (attrib != FieldValue) + goto _exit; + + switch (index) + { + case ip6_version: + { + uint ver = value.toUInt(&isOk); + if (isOk) + data.set_version(ver & 0xF); + break; + } + case ip6_trafficClass: + { + uint trfClass = value.toUInt(&isOk); + if (isOk) + data.set_traffic_class(trfClass & 0xFF); + break; + } + case ip6_flowLabel: + { + uint fl = value.toUInt(&isOk); + if (isOk) + data.set_flow_label(fl & 0xFFFFF); + break; + } + case ip6_payloadLength: + { + uint len = value.toUInt(&isOk); + if (isOk) + data.set_payload_length(len & 0xFFFF); + break; + } + case ip6_nextHeader: + { + uint ver = value.toUInt(&isOk); + if (isOk) + data.set_next_header(ver & 0xFF); + break; + } + case ip6_hopLimit: + { + uint hl = value.toUInt(&isOk); + if (isOk) + data.set_hop_limit(hl & 0xFF); + break; + } + case ip6_srcAddress: + { + Q_IPV6ADDR addr = QHostAddress(value.toString()).toIPv6Address(); + quint64 x; + + x = (quint64(addr[0]) << 56) + | (quint64(addr[1]) << 48) + | (quint64(addr[2]) << 40) + | (quint64(addr[3]) << 32) + | (quint64(addr[4]) << 24) + | (quint64(addr[5]) << 16) + | (quint64(addr[6]) << 8) + | (quint64(addr[7]) << 0); + data.set_src_addr_hi(x); + + x = (quint64(addr[ 8]) << 56) + | (quint64(addr[ 9]) << 48) + | (quint64(addr[10]) << 40) + | (quint64(addr[11]) << 32) + | (quint64(addr[12]) << 24) + | (quint64(addr[13]) << 16) + | (quint64(addr[14]) << 8) + | (quint64(addr[15]) << 0); + data.set_src_addr_lo(x); + break; + } + case ip6_dstAddress: + { + Q_IPV6ADDR addr = QHostAddress(value.toString()).toIPv6Address(); + quint64 x; + + x = (quint64(addr[0]) << 56) + | (quint64(addr[1]) << 48) + | (quint64(addr[2]) << 40) + | (quint64(addr[3]) << 32) + | (quint64(addr[4]) << 24) + | (quint64(addr[5]) << 16) + | (quint64(addr[6]) << 8) + | (quint64(addr[7]) << 0); + data.set_dst_addr_hi(x); + + x = (quint64(addr[ 8]) << 56) + | (quint64(addr[ 9]) << 48) + | (quint64(addr[10]) << 40) + | (quint64(addr[11]) << 32) + | (quint64(addr[12]) << 24) + | (quint64(addr[13]) << 16) + | (quint64(addr[14]) << 8) + | (quint64(addr[15]) << 0); + data.set_dst_addr_lo(x); + break; + } + + // Meta-Fields + case ip6_isOverrideVersion: + { + bool ovr = value.toBool(); + data.set_is_override_version(ovr); + isOk = true; + break; + } + case ip6_isOverridePayloadLength: + { + bool ovr = value.toBool(); + data.set_is_override_payload_length(ovr); + isOk = true; + break; + } + case ip6_isOverrideNextHeader: + { + bool ovr = value.toBool(); + data.set_is_override_next_header(ovr); + isOk = true; + break; + } + + case ip6_srcAddrMode: + { + uint mode = value.toUInt(&isOk); + if (isOk && data.AddrMode_IsValid(mode)) + data.set_src_addr_mode((OstProto::Ip6::AddrMode) mode); + else + isOk = false; + break; + } + case ip6_srcAddrCount: + { + uint count = value.toUInt(&isOk); + if (isOk) + data.set_src_addr_count(count); + break; + } + case ip6_srcAddrPrefix: + { + uint prefix = value.toUInt(&isOk); + if (isOk) + data.set_src_addr_prefix(prefix); + break; + } + + case ip6_dstAddrMode: + { + uint mode = value.toUInt(&isOk); + if (isOk && data.AddrMode_IsValid(mode)) + data.set_dst_addr_mode((OstProto::Ip6::AddrMode) mode); + else + isOk = false; + break; + } + case ip6_dstAddrCount: + { + uint count = value.toUInt(&isOk); + if (isOk) + data.set_dst_addr_count(count); + break; + } + case ip6_dstAddrPrefix: + { + uint prefix = value.toUInt(&isOk); + if (isOk) + data.set_dst_addr_prefix(prefix); + break; + } + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + +_exit: + return isOk; +} + +bool Ip6Protocol::isProtocolFrameValueVariable() const +{ + if ((data.src_addr_mode() != OstProto::Ip6::kFixed) + || (data.dst_addr_mode() != OstProto::Ip6::kFixed)) + return true; + else + return false; +} + +quint32 Ip6Protocol::protocolFrameCksum(int streamIndex, + CksumType cksumType) const +{ + if (cksumType == CksumIpPseudo) + { + QByteArray addr; + quint32 sum = 0; + + addr = fieldData(ip6_srcAddress, FieldFrameValue, streamIndex) + .toByteArray(); + Q_ASSERT(addr.size() == 16); + for (int i = 0; i < addr.size(); i+=2) + sum += (addr.at(i) << 8) + addr.at(i+1); + + addr = fieldData(ip6_dstAddress, FieldFrameValue, streamIndex) + .toByteArray(); + Q_ASSERT(addr.size() == 16); + for (int i = 0; i < addr.size(); i+=2) + sum += (addr.at(i) << 8) + addr.at(i+1); + + sum += fieldData(ip6_payloadLength, FieldValue, streamIndex) + .toUInt() & 0xFFFF; + sum += fieldData(ip6_nextHeader, FieldValue, streamIndex) + .toUInt() & 0xFF; + + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); + + return ~sum; + } + return AbstractProtocol::protocolFrameCksum(streamIndex, cksumType); +} + +QWidget* Ip6Protocol::configWidget() +{ + /* Lazy creation of the configWidget */ + if (configForm == NULL) + { + configForm = new Ip6ConfigForm; + loadConfigWidget(); + } + + return configForm; +} + +void Ip6Protocol::loadConfigWidget() +{ + configWidget(); + + configForm->isVersionOverride->setChecked( + fieldData(ip6_isOverrideVersion, FieldValue).toBool()); + configForm->version->setText( + fieldData(ip6_version, FieldValue).toString()); + + configForm->trafficClass->setText(uintToHexStr( + fieldData(ip6_trafficClass, FieldValue).toUInt(), 1)); + + configForm->flowLabel->setText(QString("%1").arg( + fieldData(ip6_flowLabel, FieldValue).toUInt(),5, BASE_HEX, QChar('0'))); + + configForm->isPayloadLengthOverride->setChecked( + fieldData(ip6_isOverridePayloadLength, FieldValue).toBool()); + configForm->payloadLength->setText( + fieldData(ip6_payloadLength, FieldValue).toString()); + + configForm->isNextHeaderOverride->setChecked( + fieldData(ip6_isOverrideNextHeader, FieldValue).toBool()); + configForm->nextHeader->setText(uintToHexStr( + fieldData(ip6_nextHeader, FieldValue).toUInt(), 1)); + + configForm->hopLimit->setText( + fieldData(ip6_hopLimit, FieldValue).toString()); + + configForm->srcAddr->setText( + fieldData(ip6_srcAddress, FieldTextValue).toString()); + configForm->srcAddrModeCombo->setCurrentIndex( + fieldData(ip6_srcAddrMode, FieldValue).toUInt()); + configForm->srcAddrCount->setText( + fieldData(ip6_srcAddrCount, FieldValue).toString()); + configForm->srcAddrPrefix->setText( + fieldData(ip6_srcAddrPrefix, FieldValue).toString()); + + configForm->dstAddr->setText( + fieldData(ip6_dstAddress, FieldTextValue).toString()); + configForm->dstAddrModeCombo->setCurrentIndex( + fieldData(ip6_dstAddrMode, FieldValue).toUInt()); + configForm->dstAddrCount->setText( + fieldData(ip6_dstAddrCount, FieldValue).toString()); + configForm->dstAddrPrefix->setText( + fieldData(ip6_dstAddrPrefix, FieldValue).toString()); +} + +void Ip6Protocol::storeConfigWidget() +{ + bool isOk; + + configWidget(); + + setFieldData(ip6_isOverrideVersion, + configForm->isVersionOverride->isChecked()); + setFieldData(ip6_version, configForm->version->text()); + + setFieldData(ip6_trafficClass, + configForm->trafficClass->text().remove(QChar(' ')).toUInt(&isOk, BASE_HEX)); + + setFieldData(ip6_flowLabel, + configForm->flowLabel->text().remove(QChar(' ')).toUInt(&isOk, BASE_HEX)); + + setFieldData(ip6_isOverridePayloadLength, + configForm->isPayloadLengthOverride->isChecked()); + setFieldData(ip6_payloadLength, configForm->payloadLength->text()); + + setFieldData(ip6_isOverrideNextHeader, + configForm->isNextHeaderOverride->isChecked()); + setFieldData(ip6_nextHeader, + configForm->nextHeader->text().remove(QChar(' ')).toUInt(&isOk, BASE_HEX)); + + setFieldData(ip6_hopLimit, configForm->hopLimit->text()); + + setFieldData(ip6_srcAddress, configForm->srcAddr->text()); + setFieldData(ip6_srcAddrMode, configForm->srcAddrModeCombo->currentIndex()); + setFieldData(ip6_srcAddrCount, configForm->srcAddrCount->text()); + setFieldData(ip6_srcAddrPrefix, configForm->srcAddrPrefix->text()); + + setFieldData(ip6_dstAddress, configForm->dstAddr->text()); + setFieldData(ip6_dstAddrMode, configForm->dstAddrModeCombo->currentIndex()); + setFieldData(ip6_dstAddrCount, configForm->dstAddrCount->text()); + setFieldData(ip6_dstAddrPrefix, configForm->dstAddrPrefix->text()); +} + diff --git a/common/ip6.h b/common/ip6.h new file mode 100644 index 0000000..1856bc8 --- /dev/null +++ b/common/ip6.h @@ -0,0 +1,130 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _IP6_H +#define _IP6_H + +#include "ip6.pb.h" +#include "ui_ip6.h" + +#include "abstractprotocol.h" + +/* +IPv6 Protocol Frame Format - + +-----+----------+-----------------------+ + | Ver | TrfClass | FlowLabel | + | (4) | (8) | (20) | + +-----+-------------+---------+----------+ + | Payload Length | NextHdr | HopLimit | + | (16) | (8) | (8) | + +-------------------+---------+----------+ + | | + | Source Address | + | (128) | + | | + +-----+------+------+------+------+------+ + | | + | Destination Address | + | (128) | + | | + +-----+------+------+------+------+------+ +Figures in brackets represent field width in bits +*/ + +class Ip6ConfigForm : public QWidget, public Ui::Ip6 +{ + Q_OBJECT +public: + Ip6ConfigForm(QWidget *parent = 0); +private slots: + void on_srcAddr_editingFinished(); + void on_dstAddr_editingFinished(); + void on_srcAddrModeCombo_currentIndexChanged(int index); + void on_dstAddrModeCombo_currentIndexChanged(int index); +}; + +class Ip6Protocol : public AbstractProtocol +{ +private: + OstProto::Ip6 data; + Ip6ConfigForm *configForm; + enum ip6field + { + // Frame Fields + ip6_version = 0, + ip6_trafficClass, + ip6_flowLabel, + ip6_payloadLength, + ip6_nextHeader, + ip6_hopLimit, + ip6_srcAddress, + ip6_dstAddress, + + // Meta Fields + ip6_isOverrideVersion, + ip6_isOverridePayloadLength, + ip6_isOverrideNextHeader, + + ip6_srcAddrMode, + ip6_srcAddrCount, + ip6_srcAddrPrefix, + + ip6_dstAddrMode, + ip6_dstAddrCount, + ip6_dstAddrPrefix, + + ip6_fieldCount + }; + +public: + Ip6Protocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~Ip6Protocol(); + + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + + virtual ProtocolIdType protocolIdType() const; + virtual quint32 protocolId(ProtocolIdType type) const; + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual bool isProtocolFrameValueVariable() const; + + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/ip6.proto b/common/ip6.proto new file mode 100644 index 0000000..f47f26a --- /dev/null +++ b/common/ip6.proto @@ -0,0 +1,61 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +import "protocol.proto"; + +package OstProto; + +// Ip6 Protocol +message Ip6 { + + enum AddrMode { + kFixed = 0; + kIncHost = 1; + kDecHost = 2; + kRandomHost = 3; + } + + optional bool is_override_version = 1; + optional bool is_override_payload_length = 2; + optional bool is_override_next_header = 3; + + optional uint32 version = 4 [default = 0x6]; + optional uint32 traffic_class = 5; + optional uint32 flow_label = 6; + + optional uint32 payload_length = 7; + optional uint32 next_header = 8; + optional uint32 hop_limit = 9 [default = 127]; + + optional uint64 src_addr_hi = 10; + optional uint64 src_addr_lo = 11; + optional AddrMode src_addr_mode = 12 [default = kFixed]; + optional uint32 src_addr_count = 13 [default = 16]; + optional uint32 src_addr_prefix = 14 [default = 64]; + + optional uint64 dst_addr_hi = 15; + optional uint64 dst_addr_lo = 16; + optional AddrMode dst_addr_mode = 17 [default = kFixed]; + optional uint32 dst_addr_count = 18 [default = 16]; + optional uint32 dst_addr_prefix = 19 [default = 64]; +} + +extend Protocol { + optional Ip6 ip6 = 133; +} diff --git a/common/ip6.ui b/common/ip6.ui new file mode 100644 index 0000000..b9c10f2 --- /dev/null +++ b/common/ip6.ui @@ -0,0 +1,467 @@ + + Ip6 + + + + 0 + 0 + 506 + 233 + + + + Form + + + + + + + + Version + + + + + + + false + + + + + + + + + + + + + Qt::Vertical + + + + + + + Payload Length + + + + + + + false + + + + + + + Traffic Class + + + trafficClass + + + + + + + >HH; + + + + + + + + + + Next Header + + + + + + + false + + + HH; + + + + + + + + + + Flow Label + + + flowLabel + + + + + + + >H HH HH; + + + + + + + Hop Limit + + + hopLimit + + + + + + + + + + + + + + + + + + + false + + + + + + Qt::Horizontal + + + + 51 + 20 + + + + + + + + Address + + + + + + + Mode + + + + + + + Count + + + + + + + Prefix + + + + + + + Source + + + + + + + + 1 + 0 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment Host + + + + + Decrement Host + + + + + Random Host + + + + + + + + false + + + + 0 + 0 + + + + + 50 + 16777215 + + + + + + + 10 + + + + + + + false + + + + 0 + 0 + + + + + 50 + 16777215 + + + + /009; + + + /64 + + + + + + + Destination + + + + + + + + 1 + 0 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Fixed + + + + + Increment Host + + + + + Decrement Host + + + + + Random Host + + + + + + + + false + + + + 0 + 0 + + + + + 50 + 16777215 + + + + + + + 10 + + + + + + + false + + + + 0 + 0 + + + + + 50 + 16777215 + + + + /009; + + + /64 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + isVersionOverride + version + trafficClass + flowLabel + isPayloadLengthOverride + payloadLength + isNextHeaderOverride + nextHeader + hopLimit + srcAddr + srcAddrModeCombo + srcAddrCount + srcAddrPrefix + dstAddr + dstAddrModeCombo + dstAddrCount + dstAddrPrefix + + + + + isVersionOverride + toggled(bool) + version + setEnabled(bool) + + + 67 + 22 + + + 195 + 11 + + + + + isPayloadLengthOverride + toggled(bool) + payloadLength + setEnabled(bool) + + + 319 + 28 + + + 493 + 29 + + + + + isNextHeaderOverride + toggled(bool) + nextHeader + setEnabled(bool) + + + 316 + 41 + + + 348 + 46 + + + + + diff --git a/common/ipv6addressvalidator.h b/common/ipv6addressvalidator.h new file mode 100644 index 0000000..4a0aae2 --- /dev/null +++ b/common/ipv6addressvalidator.h @@ -0,0 +1,75 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _IPV6_ADDRESS_VALIDATOR_H +#define _IPV6_ADDRESS_VALIDATOR_H + +#include +#include + +class IPv6AddressValidator : public QValidator +{ +public: + IPv6AddressValidator(QObject *parent = 0) + : QValidator(parent) + { + _ip6ValidChars.setPattern("[0-9a-fA-F]{0,4}(:[0-9a-fA-F]{0,4}){0,7}"); + } + ~IPv6AddressValidator() {} + + virtual QValidator::State validate(QString &input, int &pos) const + { + QValidator::State state; + QHostAddress addr(input); + + //qDebug("%s: %s (%d)", __FUNCTION__, input.toAscii().constData(), pos); + + if (addr.protocol() == QAbstractSocket::IPv6Protocol) + state = Acceptable; + else + if (_ip6ValidChars.exactMatch(input)) + state = Intermediate; + else + state = Invalid; + //qDebug("%s(%d): %s (%d), ", __FUNCTION__, state, + //input.toAscii().constData(), pos); + return state; + } + virtual void fixup(QString &input) const + { + input.append("::"); + QHostAddress addr(input); + int len = input.size(); + + //qDebug("%s: %s", __FUNCTION__, input.toAscii().constData()); + + while (addr.protocol() != QAbstractSocket::IPv6Protocol) + { + len--; + Q_ASSERT(len >= 0); + addr.setAddress(input.left(len)); + } + + input = addr.toString(); + } +private: + QRegExp _ip6ValidChars; +}; + +#endif diff --git a/common/ostproto.pro b/common/ostproto.pro index 89510ce..8a4c65b 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -13,6 +13,7 @@ FORMS += \ vlan.ui \ arp.ui \ ip4.ui \ + ip6.ui \ icmp.ui \ tcp.ui \ udp.ui \ @@ -34,6 +35,7 @@ PROTOS += \ vlanstack.proto \ arp.proto \ ip4.proto \ + ip6.proto \ ip4over4.proto \ icmp.proto \ tcp.proto \ @@ -61,6 +63,7 @@ HEADERS += \ vlanstack.h \ arp.h \ ip4.h \ + ip6.h \ ip4over4.h \ icmp.h \ tcp.h \ @@ -84,6 +87,7 @@ SOURCES += \ svlan.cpp \ arp.cpp \ ip4.cpp \ + ip6.cpp \ icmp.cpp \ tcp.cpp \ udp.cpp \ diff --git a/common/protocol.proto b/common/protocol.proto index 6f88c78..dddc087 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -102,6 +102,7 @@ message Protocol { kIp4FieldNumber = 130; kArpFieldNumber = 131; kIp4over4FieldNumber = 132; + kIp6FieldNumber = 133; kTcpFieldNumber = 140; kUdpFieldNumber = 141; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index e8e6570..64a537a 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -33,6 +33,7 @@ along with this program. If not, see #include "vlanstack.h" #include "arp.h" #include "ip4.h" +#include "ip6.h" #include "ip4over4.h" #include "icmp.h" #include "tcp.h" @@ -75,6 +76,8 @@ ProtocolManager::ProtocolManager() (void*) ArpProtocol::createInstance); registerProtocol(OstProto::Protocol::kIp4FieldNumber, (void*) Ip4Protocol::createInstance); + registerProtocol(OstProto::Protocol::kIp6FieldNumber, + (void*) Ip6Protocol::createInstance); registerProtocol(OstProto::Protocol::kIp4over4FieldNumber, (void*) Ip4over4Protocol::createInstance); From 956455137cfdbc41e4ec65d453fb0869aba7d115 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 23 May 2010 16:46:43 +0530 Subject: [PATCH 75/98] Implemented the remaining IP Tunneling protocols - IP6over4, IP4over6, IP6over6; renumbered L3 protocol protobuf "field numbers". ComboProtocol now implements PseudoIp cksum as protoB's cksum as a convenience for the IP tunneling protocols. Also found and fixed an issue with IPv6's pseudoIp cksum which was causing the TCP/UDP cksums to be incorrect --- client/streamconfigdialog.cpp | 8 ++- client/streamconfigdialog.ui | 85 +++++++++++++++++++++++--------- common/arp.proto | 2 +- common/comboprotocol.h | 12 ++++- common/ip4.proto | 2 +- common/ip4over4.h | 10 ---- common/ip4over4.proto | 2 +- common/ip4over6.h | 30 ++++++++++++ common/ip4over6.proto | 31 ++++++++++++ common/ip6.cpp | 4 +- common/ip6.proto | 2 +- common/ip6over4.h | 30 ++++++++++++ common/ip6over4.proto | 31 ++++++++++++ common/ip6over6.h | 91 +++++++++++++++++++++++++++++++++++ common/ip6over6.proto | 37 ++++++++++++++ common/ostproto.pro | 6 +++ common/protocol.proto | 11 +++-- common/protocolmanager.cpp | 9 ++++ 18 files changed, 357 insertions(+), 46 deletions(-) create mode 100644 common/ip4over6.h create mode 100644 common/ip4over6.proto create mode 100644 common/ip6over4.h create mode 100644 common/ip6over4.proto create mode 100644 common/ip6over6.h create mode 100644 common/ip6over6.proto diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index e4544e5..993cd1c 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -198,11 +198,17 @@ void StreamConfigDialog::setupUiExtra() bgProto[ProtoL3]->addButton(btn); #else bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone); + bgProto[ProtoL3]->addButton(rbL3Arp, OstProto::Protocol::kArpFieldNumber); bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); bgProto[ProtoL3]->addButton(rbL3Ipv6, OstProto::Protocol::kIp6FieldNumber); - bgProto[ProtoL3]->addButton(rbL3Arp, OstProto::Protocol::kArpFieldNumber); + bgProto[ProtoL3]->addButton(rbL3Ip6over4, + OstProto::Protocol::kIp6over4FieldNumber); + bgProto[ProtoL3]->addButton(rbL3Ip4over6, + OstProto::Protocol::kIp4over6FieldNumber); bgProto[ProtoL3]->addButton(rbL3Ip4over4, OstProto::Protocol::kIp4over4FieldNumber); + bgProto[ProtoL3]->addButton(rbL3Ip6over6, + OstProto::Protocol::kIp6over6FieldNumber); bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther); #endif diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 687b970..43c56b6 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,8 +8,8 @@ 0 0 - 579 - 481 + 626 + 507 @@ -173,8 +173,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff 0 0 - 537 - 243 + 584 + 269 @@ -306,6 +306,16 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + false + + + ARP + + + + false @@ -318,7 +328,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + false @@ -328,17 +338,33 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - + + false - ARP + IP 6over4 + + + false - + + + + false + + + IP 4over6 + + + false + + + + false @@ -351,7 +377,20 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + + + + false + + + IP 6over6 + + + false + + + + false @@ -520,19 +559,6 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - - - Qt::Vertical - - - - 20 - 71 - - - - @@ -575,6 +601,19 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/common/arp.proto b/common/arp.proto index 9a4bd52..c4a60e4 100644 --- a/common/arp.proto +++ b/common/arp.proto @@ -63,5 +63,5 @@ message Arp { } extend Protocol { - optional Arp arp = 131; + optional Arp arp = 130; } diff --git a/common/comboprotocol.h b/common/comboprotocol.h index c7d4053..29cf71d 100644 --- a/common/comboprotocol.h +++ b/common/comboprotocol.h @@ -170,9 +170,17 @@ public: || protoB->isProtocolFrameSizeVariable()); } -#if 0 virtual quint32 protocolFrameCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const; + CksumType cksumType = CksumIp) const + { + // For a Pseudo IP cksum, we assume it is the succeeding protocol + // that is requesting it and hence return protoB's cksum; + if (cksumType == CksumIpPseudo) + return protoB->protocolFrameCksum(streamIndex, cksumType); + + return AbstractProtocol::protocolFrameCksum(streamIndex, cksumType); + } +#if 0 quint32 protocolFrameHeaderCksum(int streamIndex = 0, CksumType cksumType = CksumIp) const; quint32 protocolFramePayloadCksum(int streamIndex = 0, diff --git a/common/ip4.proto b/common/ip4.proto index 9914977..6014321 100644 --- a/common/ip4.proto +++ b/common/ip4.proto @@ -61,5 +61,5 @@ message Ip4 { } extend Protocol { - optional Ip4 ip4 = 130; + optional Ip4 ip4 = 131; } diff --git a/common/ip4over4.h b/common/ip4over4.h index cf6c5f5..9ca1be7 100644 --- a/common/ip4over4.h +++ b/common/ip4over4.h @@ -86,16 +86,6 @@ public: protoB->protoDataCopyFrom(tempProto); } } - virtual quint32 protocolFrameCksum(int streamIndex = 0, - CksumType cksumType = CksumIp) const - { - // For a Pseudo IP cksum, we assume it is the succeeding protocol - // that is requesting it and hence return protoB's cksum; - if (cksumType == CksumIpPseudo) - return protoB->protocolFrameCksum(streamIndex, cksumType); - - return Ip4over4Combo::protocolFrameCksum(streamIndex, cksumType); - } }; #endif diff --git a/common/ip4over4.proto b/common/ip4over4.proto index df25a32..3da405a 100644 --- a/common/ip4over4.proto +++ b/common/ip4over4.proto @@ -33,5 +33,5 @@ extend Ip4over4 { } extend Protocol { - optional Ip4over4 ip4over4 = 132; + optional Ip4over4 ip4over4 = 135; } diff --git a/common/ip4over6.h b/common/ip4over6.h new file mode 100644 index 0000000..41bcce0 --- /dev/null +++ b/common/ip4over6.h @@ -0,0 +1,30 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _IP_4_OVER_6_H +#define _IP_4_OVER_6_H + +#include "comboprotocol.h" +#include "ip4.h" +#include "ip6.h" + +typedef ComboProtocol Ip4over6Protocol; + +#endif diff --git a/common/ip4over6.proto b/common/ip4over6.proto new file mode 100644 index 0000000..11d26e4 --- /dev/null +++ b/common/ip4over6.proto @@ -0,0 +1,31 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +import "protocol.proto"; + +package OstProto; + +// IP Tunelling - IP 4over6 +message Ip4over6 { + // Empty since this is a 'combo' protocol +} + +extend Protocol { + optional Ip4over6 ip4over6 = 134; +} diff --git a/common/ip6.cpp b/common/ip6.cpp index ea1f22c..8ac6fca 100644 --- a/common/ip6.cpp +++ b/common/ip6.cpp @@ -819,13 +819,13 @@ quint32 Ip6Protocol::protocolFrameCksum(int streamIndex, .toByteArray(); Q_ASSERT(addr.size() == 16); for (int i = 0; i < addr.size(); i+=2) - sum += (addr.at(i) << 8) + addr.at(i+1); + sum += (quint8(addr.at(i)) << 8) + quint8(addr.at(i+1)); addr = fieldData(ip6_dstAddress, FieldFrameValue, streamIndex) .toByteArray(); Q_ASSERT(addr.size() == 16); for (int i = 0; i < addr.size(); i+=2) - sum += (addr.at(i) << 8) + addr.at(i+1); + sum += (quint8(addr.at(i)) << 8) + quint8(addr.at(i+1)); sum += fieldData(ip6_payloadLength, FieldValue, streamIndex) .toUInt() & 0xFFFF; diff --git a/common/ip6.proto b/common/ip6.proto index f47f26a..aed96f2 100644 --- a/common/ip6.proto +++ b/common/ip6.proto @@ -57,5 +57,5 @@ message Ip6 { } extend Protocol { - optional Ip6 ip6 = 133; + optional Ip6 ip6 = 132; } diff --git a/common/ip6over4.h b/common/ip6over4.h new file mode 100644 index 0000000..08ee19b --- /dev/null +++ b/common/ip6over4.h @@ -0,0 +1,30 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _IP_6_OVER_4_H +#define _IP_6_OVER_4_H + +#include "comboprotocol.h" +#include "ip4.h" +#include "ip6.h" + +typedef ComboProtocol Ip6over4Protocol; + +#endif diff --git a/common/ip6over4.proto b/common/ip6over4.proto new file mode 100644 index 0000000..47fee75 --- /dev/null +++ b/common/ip6over4.proto @@ -0,0 +1,31 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +import "protocol.proto"; + +package OstProto; + +// IP Tunelling - IP 6over4 +message Ip6over4 { + // Empty since this is a 'combo' protocol +} + +extend Protocol { + optional Ip6over4 ip6over4 = 133; +} diff --git a/common/ip6over6.h b/common/ip6over6.h new file mode 100644 index 0000000..133d4f9 --- /dev/null +++ b/common/ip6over6.h @@ -0,0 +1,91 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _IP_6_OVER_6_H +#define _IP_6_OVER_6_H + +#include "ip6over6.pb.h" + +#include "comboprotocol.h" +#include "ip6.h" + +typedef ComboProtocol Ip6over6Combo; + +class Ip6over6Protocol : public Ip6over6Combo +{ +public: + Ip6over6Protocol(StreamBase *stream, AbstractProtocol *parent = 0) + : Ip6over6Combo(stream, parent) + { + } + + static Ip6over6Protocol* createInstance(StreamBase *stream, + AbstractProtocol *parent) + { + return new Ip6over6Protocol(stream, parent); + } + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const + { + OstProto::Protocol tempProto; + + protoA->protoDataCopyInto(tempProto); + protocol.MutableExtension(OstProto::ip6over6) + ->MutableExtension(OstProto::ip6_outer) + ->CopyFrom(tempProto.GetExtension(OstProto::ip6)); + + tempProto.Clear(); + + protoB->protoDataCopyInto(tempProto); + protocol.MutableExtension(OstProto::ip6over6) + ->MutableExtension(OstProto::ip6_inner) + ->CopyFrom(tempProto.GetExtension(OstProto::ip6)); + + protocol.mutable_protocol_id()->set_id(protocolNumber()); + } + + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) + { + if (protocol.protocol_id().id() == protocolNumber() + && protocol.HasExtension(OstProto::ip6over6)) + { + OstProto::Protocol tempProto; + + // NOTE: To use protoX->protoDataCopyFrom() we need to arrange + // so that it sees its own protocolNumber() and its own extension + // in 'protocol' + tempProto.mutable_protocol_id()->set_id(protoA->protocolNumber()); + tempProto.MutableExtension(OstProto::ip6)->CopyFrom( + protocol.GetExtension(OstProto::ip6over6).GetExtension( + OstProto::ip6_outer)); + protoA->protoDataCopyFrom(tempProto); + + tempProto.Clear(); + + tempProto.mutable_protocol_id()->set_id(protoB->protocolNumber()); + tempProto.MutableExtension(OstProto::ip6)->CopyFrom( + protocol.GetExtension(OstProto::ip6over6).GetExtension( + OstProto::ip6_inner)); + protoB->protoDataCopyFrom(tempProto); + } + } +}; + +#endif diff --git a/common/ip6over6.proto b/common/ip6over6.proto new file mode 100644 index 0000000..f260916 --- /dev/null +++ b/common/ip6over6.proto @@ -0,0 +1,37 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +import "protocol.proto"; +import "ip6.proto"; + +package OstProto; + +// IP Tunnelling - IP 6over6 +message Ip6over6 { + extensions 1 to 2; +} + +extend Ip6over6 { + optional Ip6 ip6_outer = 1; + optional Ip6 ip6_inner = 2; +} + +extend Protocol { + optional Ip6over6 ip6over6 = 136; +} diff --git a/common/ostproto.pro b/common/ostproto.pro index 8a4c65b..e16b4b3 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -36,7 +36,10 @@ PROTOS += \ arp.proto \ ip4.proto \ ip6.proto \ + ip6over4.proto \ + ip4over6.proto \ ip4over4.proto \ + ip6over6.proto \ icmp.proto \ tcp.proto \ udp.proto \ @@ -64,7 +67,10 @@ HEADERS += \ arp.h \ ip4.h \ ip6.h \ + ip6over4.h \ + ip4over6.h \ ip4over4.h \ + ip6over6.h \ icmp.h \ tcp.h \ udp.h \ diff --git a/common/protocol.proto b/common/protocol.proto index dddc087..2a5502a 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -99,10 +99,13 @@ message Protocol { kDot2SnapFieldNumber = 128; kVlanStackFieldNumber = 129; - kIp4FieldNumber = 130; - kArpFieldNumber = 131; - kIp4over4FieldNumber = 132; - kIp6FieldNumber = 133; + kArpFieldNumber = 130; + kIp4FieldNumber = 131; + kIp6FieldNumber = 132; + kIp6over4FieldNumber = 133; + kIp4over6FieldNumber = 134; + kIp4over4FieldNumber = 135; + kIp6over6FieldNumber = 136; kTcpFieldNumber = 140; kUdpFieldNumber = 141; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 64a537a..0910e1a 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -34,7 +34,10 @@ along with this program. If not, see #include "arp.h" #include "ip4.h" #include "ip6.h" +#include "ip6over4.h" +#include "ip4over6.h" #include "ip4over4.h" +#include "ip6over6.h" #include "icmp.h" #include "tcp.h" #include "udp.h" @@ -78,8 +81,14 @@ ProtocolManager::ProtocolManager() (void*) Ip4Protocol::createInstance); registerProtocol(OstProto::Protocol::kIp6FieldNumber, (void*) Ip6Protocol::createInstance); + registerProtocol(OstProto::Protocol::kIp6over4FieldNumber, + (void*) Ip6over4Protocol::createInstance); + registerProtocol(OstProto::Protocol::kIp4over6FieldNumber, + (void*) Ip4over6Protocol::createInstance); registerProtocol(OstProto::Protocol::kIp4over4FieldNumber, (void*) Ip4over4Protocol::createInstance); + registerProtocol(OstProto::Protocol::kIp6over6FieldNumber, + (void*) Ip6over6Protocol::createInstance); registerProtocol(OstProto::Protocol::kIcmpFieldNumber, (void*) IcmpProtocol::createInstance); From 7327fbb58d6bbbe8f4bd4a7a61b298b9dd003088 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 23 May 2010 22:30:32 +0530 Subject: [PATCH 76/98] Fixed a bug in IPv4 pseudoIP cksum calculation which would cause invalid TCP and UDP cksums in certain cases --- common/ip4.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/ip4.cpp b/common/ip4.cpp index f3bb887..54d069f 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -622,6 +622,9 @@ quint32 Ip4Protocol::protocolFrameCksum(int streamIndex, sum += fieldData(ip4_proto, FieldValue, streamIndex).toUInt() & 0x00FF; sum += (fieldData(ip4_totLen, FieldValue, streamIndex).toUInt() & 0xFFFF) - 20; + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); + // Above calculation done assuming 'big endian' // - so convert to host order //return qFromBigEndian(sum); From 4cba17e6c8212fcfdb3a243d1da19b98145b687f Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 24 May 2010 21:49:59 +0530 Subject: [PATCH 77/98] Fixed compiler warning --- common/ipv6addressvalidator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/ipv6addressvalidator.h b/common/ipv6addressvalidator.h index 4a0aae2..ffbd7d5 100644 --- a/common/ipv6addressvalidator.h +++ b/common/ipv6addressvalidator.h @@ -33,7 +33,7 @@ public: } ~IPv6AddressValidator() {} - virtual QValidator::State validate(QString &input, int &pos) const + virtual QValidator::State validate(QString &input, int& /*pos*/) const { QValidator::State state; QHostAddress addr(input); From 4d83432a5d6246241b27528a716f97e51aec8fed Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Thu, 3 Jun 2010 20:52:49 +0530 Subject: [PATCH 78/98] Replaced top-level Makefile with a qmake .pro so the top-level Makefile is also generated now; having a top-level .pro makes it easier for folks who use Qt Creator. Also 'make install' is now supported - a custom install path prefix can be provided, if required, by passing PREFIX=/absolute/path/prefix to qmake --- .hgignore | 2 +- Makefile | 30 ------------------------------ client/ostinato.pro | 1 + install.pri | 9 +++++++++ ost.pro | 7 +++++++ server/drone.pro | 1 + 6 files changed, 19 insertions(+), 31 deletions(-) delete mode 100644 Makefile create mode 100644 install.pri create mode 100644 ost.pro diff --git a/.hgignore b/.hgignore index b0a474f..e27298d 100644 --- a/.hgignore +++ b/.hgignore @@ -11,7 +11,7 @@ moc_*.cpp qrc_*.cpp # QMake generated files -*\Makefile* +Makefile* *\object_script.* # protobuf generated files diff --git a/Makefile b/Makefile deleted file mode 100644 index 0b49aa8..0000000 --- a/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -debug: QMAKE_CONFIG=-config debug -release: QMAKE_CONFIG=-config release - -all: - $(MAKE) -C rpc - $(MAKE) -C common - $(MAKE) -C server - $(MAKE) -C client - -release: qmake all -debug: qmake all - -clean: - -$(MAKE) -C client $@ - -$(MAKE) -C server $@ - -$(MAKE) -C common $@ - -$(MAKE) -C rpc $@ - -distclean: - -$(MAKE) -C client $@ - -$(MAKE) -C server $@ - -$(MAKE) -C common $@ - -$(MAKE) -C rpc $@ - -qmake: - cd rpc && qmake $(QMAKE_CONFIG) && cd .. - cd common && qmake $(QMAKE_CONFIG) && cd .. - cd server && qmake $(QMAKE_CONFIG) && cd .. - cd client && qmake $(QMAKE_CONFIG) && cd .. - diff --git a/client/ostinato.pro b/client/ostinato.pro index 3655802..7ab270d 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -75,6 +75,7 @@ SOURCES += \ QMAKE_DISTCLEAN += object_script.* +include(../install.pri) include(../version.pri) # TODO(LOW): Test only diff --git a/install.pri b/install.pri new file mode 100644 index 0000000..649c98e --- /dev/null +++ b/install.pri @@ -0,0 +1,9 @@ +# A custom install path prefix can be provided by passing PREFIX=/absolute/path +# to qmake; if one is not provided, we use the below defaults - +isEmpty(PREFIX) { + unix:PREFIX = "/usr/local/" + win32:PREFIX = "../" +} +target.path = $$PREFIX/bin + +INSTALLS += target diff --git a/ost.pro b/ost.pro new file mode 100644 index 0000000..bfe4e1a --- /dev/null +++ b/ost.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS = \ + rpc/pbrpc.pro \ + common/ostproto.pro \ + server/drone.pro \ + client/ostinato.pro diff --git a/server/drone.pro b/server/drone.pro index 34ea026..b2b25d1 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -40,4 +40,5 @@ SOURCES += pcapextra.cpp QMAKE_DISTCLEAN += object_script.* +include (../install.pri) include (../version.pri) From 11acbf201db0d945e354995288f9698aa8377ddd Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 6 Jun 2010 22:42:19 +0530 Subject: [PATCH 79/98] Modified ICMP protocol such that the 'Id' and 'Seq' fields are shown and used only for those ICMP types that actually have those fields --- client/packetmodel.cpp | 5 +++ common/abstractprotocol.h | 2 +- common/icmp.cpp | 67 +++++++++++++++++++++++++++++++-------- common/icmp.h | 13 +++++--- common/icmp.ui | 66 ++++++++++++++++++++++---------------- 5 files changed, 107 insertions(+), 46 deletions(-) diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index b095c45..4fabe9b 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -41,6 +41,11 @@ void PacketModel::setSelectedProtocols(ProtocolListIterator &iter) mSelectedProtocols = currentProtocols; reset(); } + else + { + emit layoutAboutToBeChanged(); + emit layoutChanged(); + } } int PacketModel::rowCount(const QModelIndex &parent) const diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index a36bbef..ac3c863 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -119,7 +119,7 @@ public: virtual int fieldCount() const; int metaFieldCount() const; - int frameFieldCount() const; + virtual int frameFieldCount() const; virtual FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, diff --git a/common/icmp.cpp b/common/icmp.cpp index 67290c4..2cf08c9 100644 --- a/common/icmp.cpp +++ b/common/icmp.cpp @@ -17,32 +17,61 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -#include #include "icmp.h" +#include +#include + +const int kIcmpEchoReply = 0; +const int kIcmpDestinationUnreachable = 3; +const int kIcmpSourceQuench = 4; +const int kIcmpRedirect = 5; +const int kIcmpEchoRequest = 8; +const int kIcmpTimeExceeded = 11; +const int kIcmpParameterProblem = 12; +const int kIcmpTimestampRequest = 13; +const int kIcmpTimestampReply = 14; +const int kIcmpInformationRequest = 15; +const int kIcmpInformationReply = 16; +const int kIcmpAddressMaskRequest = 17; +const int kIcmpAddressMaskReply = 18; + +static QSet idSeqSet = QSet() + << kIcmpEchoRequest + << kIcmpEchoReply + << kIcmpInformationRequest + << kIcmpInformationReply; + IcmpConfigForm::IcmpConfigForm(QWidget *parent) : QWidget(parent) { setupUi(this); typeCombo->setValidator(new QIntValidator(0, 0xFF, this)); - typeCombo->addItem(0, "Echo Reply"); - typeCombo->addItem(3, "Destination Unreachable"); - typeCombo->addItem(4, "Source Quench"); - typeCombo->addItem(5, "Redirect"); - typeCombo->addItem(8, "Echo Request"); - typeCombo->addItem(11, "Time Exceeded"); - typeCombo->addItem(12, "Parameter Problem"); - typeCombo->addItem(13, "Timestamp Request"); - typeCombo->addItem(14, "Timestamp Reply"); - typeCombo->addItem(17, "Address Mask Request"); - typeCombo->addItem(18, "Address Mask Reply"); + typeCombo->addItem(kIcmpEchoReply, "Echo Reply"); + typeCombo->addItem(kIcmpDestinationUnreachable, "Destination Unreachable"); + typeCombo->addItem(kIcmpSourceQuench, "Source Quench"); + typeCombo->addItem(kIcmpRedirect, "Redirect"); + typeCombo->addItem(kIcmpEchoRequest, "Echo Request"); + typeCombo->addItem(kIcmpTimeExceeded, "Time Exceeded"); + typeCombo->addItem(kIcmpParameterProblem, "Parameter Problem"); + typeCombo->addItem(kIcmpTimestampRequest, "Timestamp Request"); + typeCombo->addItem(kIcmpTimestampReply, "Timestamp Reply"); + typeCombo->addItem(kIcmpInformationRequest, "Information Request"); + typeCombo->addItem(kIcmpInformationReply, "Information Reply"); + typeCombo->addItem(kIcmpAddressMaskRequest, "Address Mask Request"); + typeCombo->addItem(kIcmpAddressMaskReply, "Address Mask Reply"); idEdit->setValidator(new QIntValidator(0, 0xFFFF, this)); seqEdit->setValidator(new QIntValidator(0, 0xFFFF, this)); } +void IcmpConfigForm::on_typeCombo_currentIndexChanged(int /*index*/) +{ + idSeqFrame->setVisible(idSeqSet.contains(typeCombo->currentValue())); +} + IcmpProtocol::IcmpProtocol(StreamBase *stream, AbstractProtocol *parent) : AbstractProtocol(stream, parent) { @@ -104,6 +133,16 @@ int IcmpProtocol::fieldCount() const return icmp_fieldCount; } +int IcmpProtocol::frameFieldCount() const +{ + int count = AbstractProtocol::frameFieldCount(); + + if (!idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt())) + count -=2; + + return count; +} + AbstractProtocol::FieldFlags IcmpProtocol::fieldFlags(int index) const { AbstractProtocol::FieldFlags flags; @@ -122,6 +161,8 @@ AbstractProtocol::FieldFlags IcmpProtocol::fieldFlags(int index) const case icmp_identifier: case icmp_sequence: + if (!idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt())) + flags |= FieldIsMeta; break; case icmp_is_override_checksum: @@ -169,7 +210,7 @@ QVariant IcmpProtocol::fieldData(int index, FieldAttrib attrib, switch(attrib) { case FieldName: - return QString("code"); + return QString("Code"); case FieldValue: return code; case FieldTextValue: diff --git a/common/icmp.h b/common/icmp.h index 0d6f218..ad72432 100644 --- a/common/icmp.h +++ b/common/icmp.h @@ -27,11 +27,12 @@ along with this program. If not, see /* Icmp Protocol Frame Format - - +-----+------+------+-----+-----+ - | TYP | CODE | CSUM | ID | SEQ | - | (1) | (1) | (2) | (2) | (2) | - +-----+------+------+-----+-----+ -Figures in brackets represent field width in bytes + +-----+------+------+------+-------+ + | TYP | CODE | CSUM | [ID] | [SEQ] | + | (1) | (1) | (2) | (2) | (2) | + +-----+------+------+------+-------+ +Fields within [] are applicable only to certain TYPEs +Figures in braces represent field width in bytes */ class IcmpConfigForm : public QWidget, public Ui::Icmp @@ -40,6 +41,7 @@ class IcmpConfigForm : public QWidget, public Ui::Icmp public: IcmpConfigForm(QWidget *parent = 0); private slots: + void on_typeCombo_currentIndexChanged(int index); }; class IcmpProtocol : public AbstractProtocol @@ -79,6 +81,7 @@ public: virtual QString shortName() const; virtual int fieldCount() const; + virtual int frameFieldCount() const; virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, diff --git a/common/icmp.ui b/common/icmp.ui index bf54421..6e62349 100644 --- a/common/icmp.ui +++ b/common/icmp.ui @@ -5,8 +5,8 @@ 0 0 - 258 - 168 + 291 + 190 @@ -66,41 +66,53 @@ - - - - Identifier + + + + QFrame::StyledPanel - - idEdit + + QFrame::Plain + + + + + Identifier + + + idEdit + + + + + + + + + + Sequence + + + seqEdit + + + + + + + - - - - - - - Sequence - - - seqEdit - - - - - - - + Qt::Vertical - 20 - 40 + 137 + 16 From 710eb7f836110c57129aae194727cf714a1514a5 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 7 Jun 2010 19:20:35 +0530 Subject: [PATCH 80/98] Fixed a bug in IcmpProtocol::frameFieldCount() which would return incorrect values sometimes --- common/icmp.cpp | 11 +++++++---- common/icmp.h | 7 +++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/common/icmp.cpp b/common/icmp.cpp index 2cf08c9..0529438 100644 --- a/common/icmp.cpp +++ b/common/icmp.cpp @@ -135,12 +135,15 @@ int IcmpProtocol::fieldCount() const int IcmpProtocol::frameFieldCount() const { - int count = AbstractProtocol::frameFieldCount(); + int count; + + if (idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt())) + count = icmp_idSeqFrameFieldCount; + else + count = icmp_commonFrameFieldCount; - if (!idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt())) - count -=2; - return count; + } AbstractProtocol::FieldFlags IcmpProtocol::fieldFlags(int index) const diff --git a/common/icmp.h b/common/icmp.h index ad72432..7433a5a 100644 --- a/common/icmp.h +++ b/common/icmp.h @@ -55,11 +55,14 @@ private: icmp_type = 0, icmp_code, icmp_checksum, - icmp_identifier, + icmp_commonFrameFieldCount, + + icmp_identifier = icmp_commonFrameFieldCount, icmp_sequence, + icmp_idSeqFrameFieldCount, // Meta Fields - icmp_is_override_checksum, + icmp_is_override_checksum = icmp_idSeqFrameFieldCount, icmp_fieldCount }; From 069cc162797cbdd9508c652d02048a57d203b373 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 7 Jun 2010 20:52:50 +0530 Subject: [PATCH 81/98] Protocol Framework Change: FieldFlags - FrameField and MetaField are no longer exclusive. A field can be neither. Also frameFieldCount() now actually counts the number of frameFields instead of deriving it from metaFieldCount() - these changes allow protocols to export different sets of fields based on a opcode/type field. --- client/packetmodel.cpp | 3 +-- common/abstractprotocol.cpp | 45 ++++++++++++++++++++++++------------- common/abstractprotocol.h | 9 ++++---- common/arp.cpp | 3 ++- common/icmp.cpp | 7 +++--- common/ip4.cpp | 5 +++-- common/ip6.cpp | 3 ++- common/mac.cpp | 3 ++- common/payload.cpp | 3 ++- common/sample.cpp | 19 ++++++++++++++-- common/sample.h | 1 + common/tcp.cpp | 5 +++-- common/textproto.cpp | 3 ++- common/udp.cpp | 5 +++-- common/vlan.cpp | 3 ++- 15 files changed, 79 insertions(+), 38 deletions(-) diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 4fabe9b..ecb4196 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -172,8 +172,7 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const while (n) { - if (!(p->fieldFlags(fieldIdx).testFlag( - AbstractProtocol::FieldIsMeta))) + if (p->fieldFlags(fieldIdx).testFlag(AbstractProtocol::FrameField)) n--; fieldIdx++; } diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 0dc3178..522605b 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -76,7 +76,8 @@ AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent) mpStream = stream; this->parent = parent; prev = next = NULL; - metaCount = -1; + _metaFieldCount = -1; + _frameFieldCount = -1; protoSize = -1; } @@ -184,45 +185,59 @@ int AbstractProtocol::fieldCount() const Returns the number of meta fields The default implementation counts and returns the number of fields for which - the FieldIsMeta flag is set\n + the MetaField flag is set\n The default implementation caches the count on its first invocation and subsequently returns the cached count */ int AbstractProtocol::metaFieldCount() const { - if (metaCount < 0) + if (_metaFieldCount < 0) { int c = 0; for (int i = 0; i < fieldCount() ; i++) - if (fieldFlags(i).testFlag(FieldIsMeta)) + if (fieldFlags(i).testFlag(MetaField)) c++; - metaCount = c; + _metaFieldCount = c; } - return metaCount; + return _metaFieldCount; } /*! Returns the number of frame fields - Convenience method - same as fieldCount() minus metaFieldCount() + The default implementation counts and returns the number of fields for which + the FrameField flag is set\n + The default implementation caches the count on its first invocation + and subsequently returns the cached count + + Subclasses which export different sets of fields based on a opcode/type + (e.g. icmp) should re-implement this function */ int AbstractProtocol::frameFieldCount() const { - //qDebug("%s:%d, %d", __FUNCTION__, fieldCount(), metaFieldCount()); - return (fieldCount() - metaFieldCount()); + if (_frameFieldCount < 0) + { + int c = 0; + for (int i = 0; i < fieldCount() ; i++) + if (fieldFlags(i).testFlag(FrameField)) + c++; + _frameFieldCount = c; + } + + return _frameFieldCount; } /*! Returns the field flags for the passed in field index The default implementation assumes all fields to be frame fields and returns - 'FieldIsNormal'. Subclasses must reimplement this method if they have any + 'FrameField'. Subclasses must reimplement this method if they have any meta fields or checksum fields. See the SampleProtocol for an example. */ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const { - return FieldIsNormal; + return FrameField; } /*! @@ -261,7 +276,7 @@ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString(); case FieldBitSize: - Q_ASSERT_X(!fieldFlags(index).testFlag(FieldIsCksum), + Q_ASSERT_X(!fieldFlags(index).testFlag(CksumField), "AbstractProtocol::fieldData()", "FieldBitSize for checksum fields need to be handled by the subclass"); return fieldData(index, FieldFrameValue, streamIndex). @@ -366,7 +381,7 @@ int AbstractProtocol::protocolFrameSize(int streamIndex) const for (int i = 0; i < fieldCount(); i++) { - if (!fieldFlags(i).testFlag(FieldIsMeta)) + if (fieldFlags(i).testFlag(FrameField)) bitsize += fieldData(i, FieldBitSize, streamIndex).toUInt(); } protoSize = (bitsize+7)/8; @@ -440,14 +455,14 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) for (int i=0; i < fieldCount() ; i++) { flags = fieldFlags(i); - if (!flags.testFlag(FieldIsMeta)) + if (flags.testFlag(FrameField)) { bits = fieldData(i, FieldBitSize, streamIndex).toUInt(); if (bits == 0) continue; Q_ASSERT(bits > 0); - if (forCksum && flags.testFlag(FieldIsCksum)) + if (forCksum && flags.testFlag(CksumField)) { field.resize((bits+7)/8); field.fill('\0'); diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index ac3c863..053e303 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -48,7 +48,8 @@ class AbstractProtocol friend class ProtocolListIterator; private: - mutable int metaCount; + mutable int _metaFieldCount; + mutable int _frameFieldCount; mutable int protoSize; mutable QString protoAbbr; @@ -61,9 +62,9 @@ protected: public: //! Properties of a field, can be OR'd enum FieldFlag { - FieldIsNormal = 0x0, //!< field appears in frame content - FieldIsMeta = 0x1, //!< field does not appear in frame, is meta data - FieldIsCksum = 0x2 //!< field is a checksum, appears in frame content + FrameField = 0x1, //!< field appears in frame content + MetaField = 0x2, //!< field does not appear in frame, is meta data + CksumField = 0x4 //!< field is a checksum and appears in frame content }; Q_DECLARE_FLAGS(FieldFlags, FieldFlag); //!< \private abcd diff --git a/common/arp.cpp b/common/arp.cpp index 84a6094..844a2d7 100644 --- a/common/arp.cpp +++ b/common/arp.cpp @@ -203,7 +203,8 @@ AbstractProtocol::FieldFlags ArpProtocol::fieldFlags(int index) const case arp_targetProtoAddrMode: case arp_targetProtoAddrCount: case arp_targetProtoAddrMask: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; default: diff --git a/common/icmp.cpp b/common/icmp.cpp index 0529438..4bdc73d 100644 --- a/common/icmp.cpp +++ b/common/icmp.cpp @@ -159,17 +159,18 @@ AbstractProtocol::FieldFlags IcmpProtocol::fieldFlags(int index) const break; case icmp_checksum: - flags |= FieldIsCksum; + flags |= CksumField; break; case icmp_identifier: case icmp_sequence: if (!idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt())) - flags |= FieldIsMeta; + flags &= ~FrameField; break; case icmp_is_override_checksum: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; default: diff --git a/common/ip4.cpp b/common/ip4.cpp index 54d069f..776752f 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -156,7 +156,7 @@ AbstractProtocol::FieldFlags Ip4Protocol::fieldFlags(int index) const break; case ip4_cksum: - flags |= FieldIsCksum; + flags |= CksumField; break; case ip4_srcAddr: @@ -173,7 +173,8 @@ AbstractProtocol::FieldFlags Ip4Protocol::fieldFlags(int index) const case ip4_dstAddrMode: case ip4_dstAddrCount: case ip4_dstAddrMask: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; default: diff --git a/common/ip6.cpp b/common/ip6.cpp index 8ac6fca..f8b7555 100644 --- a/common/ip6.cpp +++ b/common/ip6.cpp @@ -165,7 +165,8 @@ AbstractProtocol::FieldFlags Ip6Protocol::fieldFlags(int index) const case ip6_dstAddrMode: case ip6_dstAddrCount: case ip6_dstAddrPrefix: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; default: diff --git a/common/mac.cpp b/common/mac.cpp index 706931a..040f870 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -136,7 +136,8 @@ AbstractProtocol::FieldFlags MacProtocol::fieldFlags(int index) const case mac_srcMacMode: case mac_srcMacCount: case mac_srcMacStep: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; } diff --git a/common/payload.cpp b/common/payload.cpp index 4536a82..d5fb2e5 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -126,7 +126,8 @@ AbstractProtocol::FieldFlags PayloadProtocol::fieldFlags(int index) const // Meta fields case payload_dataPatternMode: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; } diff --git a/common/sample.cpp b/common/sample.cpp index d83ab54..2a79660 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -109,6 +109,20 @@ int SampleProtocol::fieldCount() const return sample_fieldCount; } +/*! + TODO Return the number of frame fields for your protocol. A frame field + is a field which has the FrameField flag set \n + + If your protocol has different sets of fields based on a OpCode/Type field + (e.g. icmp), you MUST re-implement this function; however, if your protocol + has a fixed set of frame fields always, you don't need to reimplement this + method - the base class implementation will do the right thing +*/ +int SampleProtocol::frameFieldCount() const +{ + return 0; +} + /*! TODO Edit this function to return the appropriate flags for each field \n @@ -128,7 +142,7 @@ AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const break; case sample_checksum: - flags |= FieldIsCksum; + flags |= CksumField; break; case sample_x: @@ -136,7 +150,8 @@ AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const break; case sample_is_override_checksum: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; default: diff --git a/common/sample.h b/common/sample.h index b92152b..91e6573 100644 --- a/common/sample.h +++ b/common/sample.h @@ -81,6 +81,7 @@ public: virtual QString shortName() const; virtual int fieldCount() const; + virtual int frameFieldCount() const; virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, diff --git a/common/tcp.cpp b/common/tcp.cpp index f29b1a1..02faa6a 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -113,7 +113,7 @@ AbstractProtocol::FieldFlags TcpProtocol::fieldFlags(int index) const break; case tcp_cksum: - flags |= FieldIsCksum; + flags |= CksumField; break; case tcp_urg_ptr: @@ -123,7 +123,8 @@ AbstractProtocol::FieldFlags TcpProtocol::fieldFlags(int index) const case tcp_is_override_dst_port: case tcp_is_override_hdrlen: case tcp_is_override_cksum: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; default: diff --git a/common/textproto.cpp b/common/textproto.cpp index 90327ea..c86f7ff 100644 --- a/common/textproto.cpp +++ b/common/textproto.cpp @@ -108,7 +108,8 @@ AbstractProtocol::FieldFlags TextProtocol::fieldFlags(int index) const case textProto_portNum: case textProto_encoding: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; default: diff --git a/common/udp.cpp b/common/udp.cpp index 4097ff8..8f3c35b 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -108,14 +108,15 @@ AbstractProtocol::FieldFlags UdpProtocol::fieldFlags(int index) const break; case udp_cksum: - flags |= FieldIsCksum; + flags |= CksumField; break; case udp_isOverrideSrcPort: case udp_isOverrideDstPort: case udp_isOverrideTotLen: case udp_isOverrideCksum: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; default: diff --git a/common/vlan.cpp b/common/vlan.cpp index 2946068..95b2304 100644 --- a/common/vlan.cpp +++ b/common/vlan.cpp @@ -93,7 +93,8 @@ AbstractProtocol::FieldFlags VlanProtocol::fieldFlags(int index) const // meta-fields case vlan_isOverrideTpid: - flags |= FieldIsMeta; + flags &= ~FrameField; + flags |= MetaField; break; } From fedc4ec5d10b857d4aed894e26a011a30f7212a4 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Fri, 11 Jun 2010 20:48:24 +0530 Subject: [PATCH 82/98] Extended ICMP to work for ICMPv6 as well as ICMPv4 --- common/icmp.cpp | 193 ++++++++++++++++++++++++++++++++++++++-------- common/icmp.h | 17 ++++ common/icmp.proto | 18 +++-- common/icmp.ui | 94 +++++++++++++--------- 4 files changed, 249 insertions(+), 73 deletions(-) diff --git a/common/icmp.cpp b/common/icmp.cpp index 4bdc73d..e7f6267 100644 --- a/common/icmp.cpp +++ b/common/icmp.cpp @@ -23,45 +23,86 @@ along with this program. If not, see #include #include -const int kIcmpEchoReply = 0; -const int kIcmpDestinationUnreachable = 3; -const int kIcmpSourceQuench = 4; -const int kIcmpRedirect = 5; -const int kIcmpEchoRequest = 8; -const int kIcmpTimeExceeded = 11; -const int kIcmpParameterProblem = 12; -const int kIcmpTimestampRequest = 13; -const int kIcmpTimestampReply = 14; -const int kIcmpInformationRequest = 15; -const int kIcmpInformationReply = 16; -const int kIcmpAddressMaskRequest = 17; -const int kIcmpAddressMaskReply = 18; +enum IcmpType +{ + kIcmpEchoReply = 0, + kIcmpDestinationUnreachable = 3, + kIcmpSourceQuench = 4, + kIcmpRedirect = 5, + kIcmpEchoRequest = 8, + kIcmpTimeExceeded = 11, + kIcmpParameterProblem = 12, + kIcmpTimestampRequest = 13, + kIcmpTimestampReply = 14, + kIcmpInformationRequest = 15, + kIcmpInformationReply = 16, + kIcmpAddressMaskRequest = 17, + kIcmpAddressMaskReply = 18 +}; -static QSet idSeqSet = QSet() +enum Icmp6Type +{ + kIcmp6DestinationUnreachable = 1, + kIcmp6PacketTooBig = 2, + kIcmp6TimeExceeded = 3, + kIcmp6ParameterProblem = 4, + kIcmp6EchoRequest = 128, + kIcmp6EchoReply = 129, + kIcmp6RouterSolicitation = 133, + kIcmp6RouterAdvertisement = 134, + kIcmp6NeighbourSolicitation = 135, + kIcmp6NeighbourAdvertisement = 136, + kIcmp6Redirect = 137, + kIcmp6InformationQuery = 139, + kIcmp6InformationResponse = 140 +}; + +static QSet icmpIdSeqSet = QSet() << kIcmpEchoRequest << kIcmpEchoReply << kIcmpInformationRequest << kIcmpInformationReply; +static QSet icmp6IdSeqSet = QSet() + << kIcmp6EchoRequest + << kIcmp6EchoReply; + +static bool isIdSeqType(OstProto::Icmp::Version ver, int type) +{ + //qDebug("%s: ver = %d, type = %d", __FUNCTION__, ver, type); + switch(ver) + { + case OstProto::Icmp::kIcmp4: + return icmpIdSeqSet.contains(type); + case OstProto::Icmp::kIcmp6: + return icmp6IdSeqSet.contains(type); + default: + break; + } + + Q_ASSERT(false); // unreachable + return false; +} + IcmpConfigForm::IcmpConfigForm(QWidget *parent) : QWidget(parent) { + versionGroup = new QButtonGroup(this); setupUi(this); + // auto-connect's not working, for some reason I can't figure out! + // slot name changed to when_ instead of on_ so that connectSlotsByName() + // doesn't complain + connect(versionGroup, + SIGNAL(buttonClicked(int)), + SLOT(when_versionGroup_buttonClicked(int))); + + versionGroup->addButton(icmp4Button, OstProto::Icmp::kIcmp4); + versionGroup->addButton(icmp6Button, OstProto::Icmp::kIcmp6); + typeCombo->setValidator(new QIntValidator(0, 0xFF, this)); - typeCombo->addItem(kIcmpEchoReply, "Echo Reply"); - typeCombo->addItem(kIcmpDestinationUnreachable, "Destination Unreachable"); - typeCombo->addItem(kIcmpSourceQuench, "Source Quench"); - typeCombo->addItem(kIcmpRedirect, "Redirect"); - typeCombo->addItem(kIcmpEchoRequest, "Echo Request"); - typeCombo->addItem(kIcmpTimeExceeded, "Time Exceeded"); - typeCombo->addItem(kIcmpParameterProblem, "Parameter Problem"); - typeCombo->addItem(kIcmpTimestampRequest, "Timestamp Request"); - typeCombo->addItem(kIcmpTimestampReply, "Timestamp Reply"); - typeCombo->addItem(kIcmpInformationRequest, "Information Request"); - typeCombo->addItem(kIcmpInformationReply, "Information Reply"); - typeCombo->addItem(kIcmpAddressMaskRequest, "Address Mask Request"); - typeCombo->addItem(kIcmpAddressMaskReply, "Address Mask Reply"); + + icmp4Button->click(); idEdit->setValidator(new QIntValidator(0, 0xFFFF, this)); seqEdit->setValidator(new QIntValidator(0, 0xFFFF, this)); @@ -69,7 +110,61 @@ IcmpConfigForm::IcmpConfigForm(QWidget *parent) void IcmpConfigForm::on_typeCombo_currentIndexChanged(int /*index*/) { - idSeqFrame->setVisible(idSeqSet.contains(typeCombo->currentValue())); + idSeqFrame->setVisible( + isIdSeqType( + OstProto::Icmp::Version(versionGroup->checkedId()), + typeCombo->currentValue())); +} + +void IcmpConfigForm::when_versionGroup_buttonClicked(int id) +{ + int value = typeCombo->currentValue(); + + typeCombo->clear(); + + switch(id) + { + case OstProto::Icmp::kIcmp4: + typeCombo->addItem(kIcmpEchoReply, "Echo Reply"); + typeCombo->addItem(kIcmpDestinationUnreachable, + "Destination Unreachable"); + typeCombo->addItem(kIcmpSourceQuench, "Source Quench"); + typeCombo->addItem(kIcmpRedirect, "Redirect"); + typeCombo->addItem(kIcmpEchoRequest, "Echo Request"); + typeCombo->addItem(kIcmpTimeExceeded, "Time Exceeded"); + typeCombo->addItem(kIcmpParameterProblem, "Parameter Problem"); + typeCombo->addItem(kIcmpTimestampRequest, "Timestamp Request"); + typeCombo->addItem(kIcmpTimestampReply, "Timestamp Reply"); + typeCombo->addItem(kIcmpInformationRequest, "Information Request"); + typeCombo->addItem(kIcmpInformationReply, "Information Reply"); + typeCombo->addItem(kIcmpAddressMaskRequest, "Address Mask Request"); + typeCombo->addItem(kIcmpAddressMaskReply, "Address Mask Reply"); + break; + + case OstProto::Icmp::kIcmp6: + typeCombo->addItem(kIcmp6DestinationUnreachable, + "Destination Unreachable"); + typeCombo->addItem(kIcmp6PacketTooBig, "Packet Too Big"); + typeCombo->addItem(kIcmp6TimeExceeded, "Time Exceeded"); + typeCombo->addItem(kIcmp6ParameterProblem, "Parameter Problem"); + + typeCombo->addItem(kIcmp6EchoRequest, "Echo Request"); + typeCombo->addItem(kIcmp6EchoReply, "Echo Reply"); + typeCombo->addItem(kIcmp6RouterSolicitation, "Router Solicitation"); + typeCombo->addItem(kIcmp6RouterAdvertisement, "Router Advertisement"); + typeCombo->addItem(kIcmp6NeighbourSolicitation, + "Neighbour Solicitation"); + typeCombo->addItem(kIcmp6NeighbourAdvertisement, + "Neighbour Advertisement"); + typeCombo->addItem(kIcmp6Redirect, "Redirect"); + typeCombo->addItem(kIcmp6InformationQuery, "Information Query"); + typeCombo->addItem(kIcmp6InformationResponse, "Information Response"); + break; + default: + Q_ASSERT(false); + } + + typeCombo->setValue(value); } IcmpProtocol::IcmpProtocol(StreamBase *stream, AbstractProtocol *parent) @@ -121,7 +216,13 @@ quint32 IcmpProtocol::protocolId(ProtocolIdType type) const { switch(type) { - case ProtocolIdIp: return 0x1; + case ProtocolIdIp: + switch(icmpVersion()) + { + case OstProto::Icmp::kIcmp4: return 0x1; + case OstProto::Icmp::kIcmp6: return 0x3A; + default:break; + } default:break; } @@ -137,7 +238,7 @@ int IcmpProtocol::frameFieldCount() const { int count; - if (idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt())) + if (isIdSeqType(icmpVersion(), icmpType())) count = icmp_idSeqFrameFieldCount; else count = icmp_commonFrameFieldCount; @@ -164,10 +265,11 @@ AbstractProtocol::FieldFlags IcmpProtocol::fieldFlags(int index) const case icmp_identifier: case icmp_sequence: - if (!idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt())) + if (!isIdSeqType(icmpVersion(), icmpType())) flags &= ~FrameField; break; + case icmp_version: case icmp_is_override_checksum: flags &= ~FrameField; flags |= MetaField; @@ -249,6 +351,12 @@ QVariant IcmpProtocol::fieldData(int index, FieldAttrib attrib, sum += (quint16) ~cks; cks = protocolFramePayloadCksum(streamIndex, CksumIp); sum += (quint16) ~cks; + if (icmpVersion() == OstProto::Icmp::kIcmp6) + { + cks = protocolFrameHeaderCksum(streamIndex, + CksumIpPseudo); + sum += (quint16) ~cks; + } while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); @@ -333,6 +441,17 @@ QVariant IcmpProtocol::fieldData(int index, FieldAttrib attrib, // Meta fields + case icmp_version: + { + switch(attrib) + { + case FieldValue: + return data.icmp_version(); + default: + break; + } + break; + } case icmp_is_override_checksum: { switch(attrib) @@ -398,6 +517,13 @@ bool IcmpProtocol::setFieldData(int index, const QVariant &value, data.set_sequence(seq); break; } + case icmp_version: + { + int ver = value.toUInt(&isOk); + if (isOk) + data.set_icmp_version(OstProto::Icmp::Version(ver)); + break; + } case icmp_is_override_checksum: { bool ovr = value.toBool(); @@ -430,6 +556,8 @@ void IcmpProtocol::loadConfigWidget() { configWidget(); + configForm->versionGroup->button(icmpVersion())->click(); + configForm->typeCombo->setValue(fieldData(icmp_type, FieldValue).toUInt()); configForm->codeEdit->setText(fieldData(icmp_code, FieldValue).toString()); @@ -450,6 +578,9 @@ void IcmpProtocol::storeConfigWidget() bool isOk; configWidget(); + + setFieldData(icmp_version, configForm->versionGroup->checkedId()); + setFieldData(icmp_type, configForm->typeCombo->currentValue()); setFieldData(icmp_code, configForm->codeEdit->text()); diff --git a/common/icmp.h b/common/icmp.h index 7433a5a..a3fc296 100644 --- a/common/icmp.h +++ b/common/icmp.h @@ -25,6 +25,8 @@ along with this program. If not, see #include "abstractprotocol.h" +#include + /* Icmp Protocol Frame Format - +-----+------+------+------+-------+ @@ -39,9 +41,12 @@ class IcmpConfigForm : public QWidget, public Ui::Icmp { Q_OBJECT public: + QButtonGroup *versionGroup; + IcmpConfigForm(QWidget *parent = 0); private slots: void on_typeCombo_currentIndexChanged(int index); + void when_versionGroup_buttonClicked(int id); }; class IcmpProtocol : public AbstractProtocol @@ -63,10 +68,22 @@ private: // Meta Fields icmp_is_override_checksum = icmp_idSeqFrameFieldCount, + icmp_version, icmp_fieldCount }; + OstProto::Icmp::Version icmpVersion() const + { + return OstProto::Icmp::Version( + fieldData(icmp_version, FieldValue).toUInt()); + } + + int icmpType() const + { + return fieldData(icmp_type, FieldValue).toInt(); + } + public: IcmpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~IcmpProtocol(); diff --git a/common/icmp.proto b/common/icmp.proto index f48e9a7..2cd6025 100644 --- a/common/icmp.proto +++ b/common/icmp.proto @@ -24,13 +24,19 @@ package OstProto; // Icmp Protocol message Icmp { - optional bool is_override_checksum = 1; + enum Version { + kIcmp4 = 4; + kIcmp6 = 6; + } - optional uint32 type = 2 [default = 0x8]; // echo request - optional uint32 code = 3; - optional uint32 checksum = 4; - optional uint32 identifier = 5 [default = 1234]; - optional uint32 sequence = 6; + optional Version icmp_version = 1 [default = kIcmp4]; + optional bool is_override_checksum = 2; + + optional uint32 type = 6 [default = 0x8]; // echo request + optional uint32 code = 7; + optional uint32 checksum = 8; + optional uint32 identifier = 9 [default = 1234]; + optional uint32 sequence = 10; } extend Protocol { diff --git a/common/icmp.ui b/common/icmp.ui index 6e62349..7ba1938 100644 --- a/common/icmp.ui +++ b/common/icmp.ui @@ -5,15 +5,38 @@ 0 0 - 291 - 190 + 373 + 166 Form - + + + + Version + + + + + + ICMPv4 + + + + + + + ICMPv6 + + + + + + + Type @@ -23,10 +46,10 @@ - + - + Code @@ -36,46 +59,43 @@ - + - - - - Checksum - - - - - - - false - - - - + Qt::Horizontal - 40 + 31 20 - - - - QFrame::StyledPanel + + + + Checksum - - QFrame::Plain + + + + + + false - - + + + + + + + + + Identifier @@ -85,10 +105,10 @@ - + - + Sequence @@ -98,21 +118,21 @@ - + - + Qt::Vertical - 137 - 16 + 211 + 71 @@ -127,6 +147,8 @@ + icmp4Button + icmp6Button typeCombo codeEdit overrideCksum From 2e6503faad581d358dc589eb109985904641abc4 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 28 Jun 2010 21:10:29 +0530 Subject: [PATCH 83/98] Bumped version to 0.1.1 --- version.pri | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.pri b/version.pri index 103b6e9..236cdfa 100644 --- a/version.pri +++ b/version.pri @@ -1,7 +1,7 @@ -APP_VERSION = 0.1 +APP_VERSION = 0.1.1 APP_REVISION = $(shell hg identify -i) #uncomment the below line in a source package and fill-in the correct revision -#APP_REVISION = +#APP_REVISION = @ APP_VERSION_FILE = version.cpp revtarget.target = $$APP_VERSION_FILE win32:revtarget.commands = echo "const char *version = \"$$APP_VERSION\";" \ From c2fac2db70ab030ae90a32bcc690d5f8f4114e9f Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Tue, 13 Jul 2010 20:36:35 +0530 Subject: [PATCH 84/98] Added streams save/restore; Ostinato file format specified; Protocol Field Numbering scheme changed - existing protocol field numbers changed accordingly --- client/main.cpp | 9 +- client/port.cpp | 52 ++++- client/port.h | 5 +- client/portswindow.cpp | 152 +++++++++------ client/portswindow.h | 9 +- client/portswindow.ui | 10 + client/streammodel.cpp | 22 +++ client/streammodel.h | 2 + common/arp.proto | 2 +- common/crc32c.cpp | 134 +++++++++++++ common/crc32c.h | 23 +++ common/dot2llc.proto | 2 +- common/dot2snap.proto | 2 +- common/dot3.proto | 2 +- common/eth2.proto | 2 +- common/fileformat.cpp | 411 ++++++++++++++++++++++++++++++++++++++++ common/fileformat.h | 59 ++++++ common/fileformat.proto | 98 ++++++++++ common/icmp.proto | 2 +- common/ip4.proto | 2 +- common/ip4over4.proto | 2 +- common/ip4over6.proto | 2 +- common/ip6.proto | 2 +- common/ip6over4.proto | 2 +- common/ip6over6.proto | 2 +- common/llc.proto | 2 +- common/mac.proto | 2 +- common/ostproto.pro | 23 +-- common/payload.proto | 2 +- common/protocol.proto | 54 +++--- common/sample.proto | 2 +- common/snap.proto | 2 +- common/svlan.proto | 2 +- common/tcp.proto | 2 +- common/textproto.proto | 2 +- common/udp.proto | 2 +- common/userscript.proto | 2 +- common/vlan.proto | 2 +- common/vlanstack.proto | 2 +- protobuf.pri | 33 ++++ 40 files changed, 1008 insertions(+), 136 deletions(-) create mode 100644 common/crc32c.cpp create mode 100644 common/crc32c.h create mode 100644 common/fileformat.cpp create mode 100644 common/fileformat.h create mode 100644 common/fileformat.proto create mode 100644 protobuf.pri diff --git a/client/main.cpp b/client/main.cpp index 91f61d8..a13ff77 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -24,6 +24,8 @@ along with this program. If not, see #include #include +extern const char* version; +extern const char* revision; extern ProtocolManager *OstProtocolManager; QSettings *appSettings; @@ -34,6 +36,11 @@ int main(int argc, char* argv[]) QApplication app(argc, argv); int exitCode; + app.setApplicationName("Ostinato"); + app.setOrganizationName("Ostinato"); + app.setProperty("version", version); + app.setProperty("revision", revision); + OstProtocolManager = new ProtocolManager(); /* (Portable Mode) If we have a .ini file in the same directory as the @@ -44,7 +51,7 @@ int main(int argc, char* argv[]) if (QFile::exists(portableIni)) appSettings = new QSettings(portableIni, QSettings::IniFormat); else - appSettings = new QSettings("Ostinato", "Ostinato"); + appSettings = new QSettings(); mainWindow = new MainWindow; mainWindow->show(); diff --git a/client/port.cpp b/client/port.cpp index eda09f6..6b5e13e 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -17,12 +17,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -#include - -#include - #include "port.h" -#include "pbhelper.h" + +#include "fileformat.h" + +#include +#include +#include +#include uint Port::mAllocStreamId = 0; @@ -218,3 +220,43 @@ void Port::updateStats(OstProto::PortStats *portStats) } } +bool Port::openStreams(QString fileName, bool append, QString &error) +{ + OstProto::StreamConfigList streams; + + if (!fileFormat.openStreams(fileName, streams, error)) + goto _fail; + + if (!append) + { + while (numStreams()) + deleteStreamAt(0); + } + + for (int i = 0; i < streams.stream_size(); i++) + { + newStreamAt(mStreams.size()); + streamByIndex(mStreams.size()-1)->protoDataCopyFrom(streams.stream(i)); + } + + emit streamListChanged(mPortGroupId, mPortId); + + return true; + +_fail: + return false; +} + +bool Port::saveStreams(QString fileName, QString &error) +{ + OstProto::StreamConfigList streams; + + streams.mutable_port_id()->set_id(0); + for (int i = 0; i < mStreams.size(); i++) + { + OstProto::Stream *s = streams.add_stream(); + mStreams[i]->protoDataCopyInto(*s); + } + + return fileFormat.saveStreams(streams, fileName, error); +} diff --git a/client/port.h b/client/port.h index 91f6d8a..e4bb9c9 100644 --- a/client/port.h +++ b/client/port.h @@ -114,13 +114,16 @@ public: void getModifiedStreamsSinceLastSync( OstProto::StreamConfigList &streamConfigList); - void when_syncComplete(); void updateStats(OstProto::PortStats *portStats); + bool openStreams(QString fileName, bool append, QString &error); + bool saveStreams(QString fileName, QString &error); + signals: void portDataChanged(int portGroupId, int portId); + void streamListChanged(int portGroupId, int portId); }; diff --git a/client/portswindow.cpp b/client/portswindow.cpp index ccaed5a..58070a0 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -29,6 +29,8 @@ along with this program. If not, see PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) : QWidget(parent) { + QAction *sep; + delegate = new StreamListDelegate; //slm = new StreamListModel(); //plm = new PortGroupList(); @@ -43,7 +45,7 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) tvStreamList->verticalHeader()->setDefaultSectionSize( tvStreamList->verticalHeader()->minimumSectionSize()); - // Populate Context Menu Actions + // Populate PortList Context Menu Actions tvPortList->addAction(actionNew_Port_Group); tvPortList->addAction(actionDelete_Port_Group); tvPortList->addAction(actionConnect_Port_Group); @@ -51,12 +53,21 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) tvPortList->addAction(actionExclusive_Control); + // Populate StramList Context Menu Actions tvStreamList->addAction(actionNew_Stream); tvStreamList->addAction(actionEdit_Stream); tvStreamList->addAction(actionDelete_Stream); + sep = new QAction(this); + sep->setSeparator(true); + tvStreamList->addAction(sep); + + tvStreamList->addAction(actionOpen_Streams); + tvStreamList->addAction(actionSave_Streams); + + // PortList and StreamList actions combined make this window's actions addActions(tvPortList->actions()); - QAction *sep = new QAction(this); + sep = new QAction(this); sep->setSeparator(true); addAction(sep); addActions(tvStreamList->actions()); @@ -77,26 +88,24 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent) this, SLOT(when_portView_currentChanged(const QModelIndex&, const QModelIndex&))); - connect( tvStreamList->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(when_streamView_currentChanged(const QModelIndex&, - const QModelIndex&))); - connect( tvStreamList->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, SLOT(when_streamView_selectionChanged())); + connect(plm->getStreamModel(), SIGNAL(rowsInserted(QModelIndex, int, int)), + SLOT(updateStreamViewActions())); + connect(plm->getStreamModel(), SIGNAL(rowsRemoved(QModelIndex, int, int)), + SLOT(updateStreamViewActions())); -#if 0 - connect( tvPortList->selectionModel(), + connect(tvStreamList->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&))); -#endif + SLOT(updateStreamViewActions())); + connect(tvStreamList->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + SLOT(updateStreamViewActions())); tvStreamList->resizeColumnToContents(StreamModel::StreamIcon); tvStreamList->resizeColumnToContents(StreamModel::StreamStatus); // Initially we don't have any ports/streams - so send signal triggers when_portView_currentChanged(QModelIndex(), QModelIndex()); - when_streamView_currentChanged(QModelIndex(), QModelIndex()); + updateStreamViewActions(); //! \todo Hide the Aggregate Box till we add support frAggregate->setHidden(true); @@ -148,19 +157,6 @@ void PortsWindow::when_portView_currentChanged(const QModelIndex& current, } } -void PortsWindow::when_streamView_currentChanged(const QModelIndex& /*current*/, - const QModelIndex& /*previous*/) -{ - qDebug("stream view current changed"); - updateStreamViewActions(); -} - -void PortsWindow::when_streamView_selectionChanged() -{ - qDebug("stream view selection changed"); - updateStreamViewActions(); -} - void PortsWindow::when_portModel_dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { @@ -182,16 +178,6 @@ void PortsWindow::when_portModel_reset() when_portView_currentChanged(QModelIndex(), tvPortList->currentIndex()); } -#if 0 -void PortsWindow::updateStreamViewActions(const QModelIndex& current) -{ - if (current.isValid()) - actionDelete_Stream->setEnabled(true); - else - actionDelete_Stream->setDisabled(true); -} -#endif - void PortsWindow::updateStreamViewActions() { // For some reason hasSelection() returns true even if selection size is 0 @@ -233,6 +219,9 @@ void PortsWindow::updateStreamViewActions() actionEdit_Stream->setDisabled(true); actionDelete_Stream->setDisabled(true); } + actionOpen_Streams->setEnabled(plm->isPort( + tvPortList->selectionModel()->currentIndex())); + actionSave_Streams->setEnabled(tvStreamList->model()->rowCount() > 0); } void PortsWindow::updatePortViewActions(const QModelIndex& current) @@ -406,26 +395,6 @@ void PortsWindow::on_actionExclusive_Control_triggered(bool checked) plm->portGroup(current.parent()).modifyPort(current.row(), checked); } -#if 0 -void PortsWindow::on_actionNew_Stream_triggered() -{ - qDebug("New Stream Action"); - - int row = 0; - - if (tvStreamList->currentIndex().isValid()) - row = tvStreamList->currentIndex().row(); - plm->getStreamModel()->insertRows(row, 1); -} - -void PortsWindow::on_actionDelete_Stream_triggered() -{ - qDebug("Delete Stream Action"); - if (tvStreamList->currentIndex().isValid()) - plm->getStreamModel()->removeRows(tvStreamList->currentIndex().row(), 1); -} -#endif - void PortsWindow::on_actionNew_Stream_triggered() { qDebug("New Stream Action"); @@ -477,4 +446,73 @@ void PortsWindow::on_actionDelete_Stream_triggered() qDebug("No selection"); } +void PortsWindow::on_actionOpen_Streams_triggered() +{ + qDebug("Open Streams Action"); + + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + QString fileName; + QString errorStr; + bool append = true; + + Q_ASSERT(plm->isPort(current)); + + fileName = QFileDialog::getOpenFileName(this, tr("Open Streams")); + if (fileName.isEmpty()) + goto _exit; + + if (tvStreamList->model()->rowCount()) + { + QMessageBox msgBox(QMessageBox::Question, qApp->applicationName(), + tr("Append to existing streams? Or overwrite?")); + QPushButton *appendBtn = msgBox.addButton(tr("Append"), + QMessageBox::ActionRole); + QPushButton *overwriteBtn = msgBox.addButton(tr("Overwrite"), + QMessageBox::ActionRole); + QPushButton *cancelBtn = msgBox.addButton(QMessageBox::Cancel); + + msgBox.exec(); + + if (msgBox.clickedButton() == cancelBtn) + goto _exit; + else if (msgBox.clickedButton() == appendBtn) + append = true; + else if (msgBox.clickedButton() == overwriteBtn) + append = false; + else + Q_ASSERT(false); + } + + if (!plm->port(current).openStreams(fileName, append, errorStr)) + QMessageBox::critical(this, qApp->applicationName(), errorStr); + else if (!errorStr.isEmpty()) + QMessageBox::warning(this, qApp->applicationName(), errorStr); +_exit: + return; +} + +void PortsWindow::on_actionSave_Streams_triggered() +{ + qDebug("Save Streams Action"); + + QModelIndex current = tvPortList->selectionModel()->currentIndex(); + QString fileName; + QString errorStr; + + Q_ASSERT(plm->isPort(current)); + + fileName = QFileDialog::getSaveFileName(this, tr("Save Streams")); + if (fileName.isEmpty()) + goto _exit; + + // TODO: all or selected? + + if (!plm->port(current).saveStreams(fileName, errorStr)) + QMessageBox::critical(this, qApp->applicationName(), errorStr); + else if (!errorStr.isEmpty()) + QMessageBox::warning(this, qApp->applicationName(), errorStr); +_exit: + return; +} + diff --git a/client/portswindow.h b/client/portswindow.h index 607c40a..ed93854 100644 --- a/client/portswindow.h +++ b/client/portswindow.h @@ -48,17 +48,13 @@ private: QString lastNewPortGroup; QAbstractItemDelegate *delegate; +private slots: void updatePortViewActions(const QModelIndex& current); - //void updateStreamViewActions(const QModelIndex& current); void updateStreamViewActions(); -private slots: void on_tvStreamList_activated(const QModelIndex & index); void when_portView_currentChanged(const QModelIndex& current, const QModelIndex& previous); - void when_streamView_currentChanged(const QModelIndex& current, - const QModelIndex& previous); - void when_streamView_selectionChanged(); void when_portModel_dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); void when_portModel_reset(); @@ -75,6 +71,9 @@ private slots: void on_actionNew_Stream_triggered(); void on_actionEdit_Stream_triggered(); void on_actionDelete_Stream_triggered(); + + void on_actionOpen_Streams_triggered(); + void on_actionSave_Streams_triggered(); }; #endif diff --git a/client/portswindow.ui b/client/portswindow.ui index 3032b79..a724c06 100644 --- a/client/portswindow.ui +++ b/client/portswindow.ui @@ -230,6 +230,16 @@ Exclusive Port Control (EXPERIMENTAL) + + + Open Streams ... + + + + + Save Streams ... + + diff --git a/client/streammodel.cpp b/client/streammodel.cpp index 5c57cdb..19942fd 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -254,8 +254,30 @@ void StreamModel::setCurrentPortIndex(const QModelIndex ¤t) else { qDebug("change to valid port"); + // Disconnect any existing connection to avoid duplication + // Qt 4.6 has Qt::UniqueConnection, but we want to remain compatible + // with earlier Qt versions + if (mCurrentPort) + { + disconnect(mCurrentPort, SIGNAL(streamListChanged(int, int)), + this, SLOT(when_mCurrentPort_streamListChanged(int, int))); + } quint16 pg = current.internalId() >> 16; mCurrentPort = pgl->mPortGroups[pgl->indexOfPortGroup(pg)]->mPorts[current.row()]; + connect(mCurrentPort, SIGNAL(streamListChanged(int, int)), + this, SLOT(when_mCurrentPort_streamListChanged(int, int))); } reset(); } + +void StreamModel::when_mCurrentPort_streamListChanged(int portGroupId, + int portId) +{ + qDebug("In %s", __FUNCTION__); + if (mCurrentPort) + { + if ((quint32(portGroupId) == mCurrentPort->portGroupId()) + && (quint32(portId) == mCurrentPort->id())) + reset(); + } +} diff --git a/client/streammodel.h b/client/streammodel.h index b0b41d2..9c7e1aa 100644 --- a/client/streammodel.h +++ b/client/streammodel.h @@ -71,6 +71,8 @@ class StreamModel : public QAbstractTableModel public slots: void setCurrentPortIndex(const QModelIndex ¤t); + private slots: + void when_mCurrentPort_streamListChanged(int portGroupId, int portId); }; #endif diff --git a/common/arp.proto b/common/arp.proto index c4a60e4..12ccebb 100644 --- a/common/arp.proto +++ b/common/arp.proto @@ -63,5 +63,5 @@ message Arp { } extend Protocol { - optional Arp arp = 130; + optional Arp arp = 300; } diff --git a/common/crc32c.cpp b/common/crc32c.cpp new file mode 100644 index 0000000..b4206f8 --- /dev/null +++ b/common/crc32c.cpp @@ -0,0 +1,134 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +/******************************************************************* +** IMPORTANT NOTE: +** This code is from RFC 4960 Stream Control Transmission Protocol +** It has been modified suitably while keeping the algorithm intact. +********************************************************************/ + +#include "crc32c.h" + +#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF]) + +quint32 crc_c[256] = +{ + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, + 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, + 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, + 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, + 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, + 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, + 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, + 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, + 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, + 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, + 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, + 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, + 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, + 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, + 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, + 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, + 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, + 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, + 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, + 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, + 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, + 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, + 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, + 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, + 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, + 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, + 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, + 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, + 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, + 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, + 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, + 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, + 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, + 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, + 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, + 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, + 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, + 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, + 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, + 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, + 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, + 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, + 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, + 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, + 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, + 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, + 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, + 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, + 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, + 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, + 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, + 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L, +}; + +quint32 checksumCrc32C(quint8 *buffer, uint length) +{ + uint i; + quint32 crc32 = ~0L; + quint32 result; + quint8 byte0,byte1,byte2,byte3; + + for (i = 0; i < length; i++) { + CRC32C(crc32, buffer[i]); + } + + result = ~crc32; + + /* result now holds the negated polynomial remainder; + * since the table and algorithm is "reflected" [williams95]. + * That is, result has the same value as if we mapped the message + * to a polynomial, computed the host-bit-order polynomial + * remainder, performed final negation, then did an end-for-end + * bit-reversal. + * Note that a 32-bit bit-reversal is identical to four inplace + * 8-bit reversals followed by an end-for-end byteswap. + * In other words, the bytes of each bit are in the right order, + * but the bytes have been byteswapped. So we now do an explicit + * byteswap. On a little-endian machine, this byteswap and + * the final ntohl cancel out and could be elided. + */ + + byte0 = result & 0xff; + byte1 = (result>>8) & 0xff; + byte2 = (result>>16) & 0xff; + byte3 = (result>>24) & 0xff; + crc32 = ((byte0 << 24) | + (byte1 << 16) | + (byte2 << 8) | + byte3); + return ( crc32 ); +} diff --git a/common/crc32c.h b/common/crc32c.h new file mode 100644 index 0000000..84cdc76 --- /dev/null +++ b/common/crc32c.h @@ -0,0 +1,23 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#include + +quint32 checksumCrc32C(quint8 *buffer, uint length); + diff --git a/common/dot2llc.proto b/common/dot2llc.proto index 08e857c..8223650 100644 --- a/common/dot2llc.proto +++ b/common/dot2llc.proto @@ -29,5 +29,5 @@ message Dot2Llc { } extend Protocol { - optional Dot2Llc dot2Llc = 127; + optional Dot2Llc dot2Llc = 206; } diff --git a/common/dot2snap.proto b/common/dot2snap.proto index 3af4261..d49059f 100644 --- a/common/dot2snap.proto +++ b/common/dot2snap.proto @@ -27,5 +27,5 @@ message Dot2Snap { } extend Protocol { - optional Dot2Snap dot2Snap = 128; + optional Dot2Snap dot2Snap = 207; } diff --git a/common/dot3.proto b/common/dot3.proto index e3f4344..2e4070c 100644 --- a/common/dot3.proto +++ b/common/dot3.proto @@ -27,5 +27,5 @@ message Dot3 { } extend Protocol { - optional Dot3 dot3 = 122; + optional Dot3 dot3 = 201; } diff --git a/common/eth2.proto b/common/eth2.proto index e0c52a2..72d58c8 100644 --- a/common/eth2.proto +++ b/common/eth2.proto @@ -27,5 +27,5 @@ message Eth2 { } extend Protocol { - optional Eth2 eth2 = 121; + optional Eth2 eth2 = 200; } diff --git a/common/fileformat.cpp b/common/fileformat.cpp new file mode 100644 index 0000000..619ab37 --- /dev/null +++ b/common/fileformat.cpp @@ -0,0 +1,411 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#include "fileformat.h" + +#include "crc32c.h" + +#include +#include +#include + +#include + +const std::string FileFormat::kFileMagicValue = "\xa7\xb7OSTINATO"; + +FileFormat fileFormat; + +const int kBaseHex = 16; + +FileFormat::FileFormat() +{ + /* + * We don't have any "real" work to do here in the constructor. + * What we do is run some "assert" tests so that these get caught + * at init itself instead of while saving/restoring when a user + * might lose some data! + */ + OstProto::FileMagic magic; + OstProto::FileChecksum cksum; + + magic.set_value(kFileMagicValue); + cksum.set_value(quint32(0)); + + // TODO: convert Q_ASSERT to something that will run in RELEASE mode also + Q_ASSERT(magic.IsInitialized()); + Q_ASSERT(cksum.IsInitialized()); + Q_ASSERT(magic.ByteSize() == kFileMagicSize); + Q_ASSERT(cksum.ByteSize() == kFileChecksumSize); +} + +FileFormat::~FileFormat() +{ +} + +bool FileFormat::openStreams(const QString fileName, + OstProto::StreamConfigList &streams, QString &error) +{ + QFile file(fileName); + QByteArray buf; + int size, contentOffset, contentSize; + quint32 calcCksum; + OstProto::FileMagic magic; + OstProto::FileMeta meta; + OstProto::FileContent content; + OstProto::FileChecksum cksum, zeroCksum; + + if (!file.open(QIODevice::ReadOnly)) + goto _open_fail; + + if (file.size() < kFileMagicSize) + goto _magic_missing; + + if (file.size() < kFileMinSize) + goto _checksum_missing; + + buf.resize(file.size()); + size = file.read(buf.data(), buf.size()); + if (size < 0) + goto _read_fail; + + Q_ASSERT(file.atEnd()); + file.close(); + + qDebug("%s: file.size() = %lld", __FUNCTION__, file.size()); + qDebug("%s: size = %d", __FUNCTION__, size); + + //qDebug("Read %d bytes", buf.size()); + //qDebug("%s", QString(buf.toHex()).toAscii().constData()); + + // Parse and verify magic + if (!magic.ParseFromArray( + (void*)(buf.constData() + kFileMagicOffset), + kFileMagicSize)) + { + goto _magic_parse_fail; + } + if (magic.value() != kFileMagicValue) + goto _magic_match_fail; + + // Parse and verify checksum + if (!cksum.ParseFromArray( + (void*)(buf.constData() + size - kFileChecksumSize), + kFileChecksumSize)) + { + goto _cksum_parse_fail; + } + + zeroCksum.set_value(0); + if (!zeroCksum.SerializeToArray( + (void*) (buf.data() + size - kFileChecksumSize), + kFileChecksumSize)) + { + goto _zero_cksum_serialize_fail; + } + + calcCksum = checksumCrc32C((quint8*) buf.constData(), size); + + qDebug("checksum \nExpected:%x Actual:%x", + calcCksum, cksum.value()); + + if (cksum.value() != calcCksum) + goto _cksum_verify_fail; + + // Parse the metadata first before we parse the full contents + if (!meta.ParseFromArray( + (void*)(buf.constData() + kFileMetaDataOffset), + size - kFileMetaDataOffset)) + { + goto _metadata_parse_fail; + } + + qDebug("%s: File MetaData (INFORMATION) - \n%s", __FUNCTION__, + QString().fromStdString(meta.DebugString()).toAscii().constData()); + + // MetaData Validation(s) + if (meta.data().file_type() != OstProto::kStreamsFileType) + goto _unexpected_file_type; + + if (meta.data().format_version_major() != kFileFormatVersionMajor) + goto _incompatible_file_version; + + if (meta.data().format_version_minor() > kFileFormatVersionMinor) + goto _incompatible_file_version; + + if (meta.data().format_version_minor() < kFileFormatVersionMinor) + { + // TODO: need to modify 'buf' such that we can parse successfully + // assuming the native minor version + } + + if (meta.data().format_version_revision() > kFileFormatVersionRevision) + { + error = QString(tr("%1 was created using a newer version of Ostinato." + " New features/protocols will not be available.")).arg(fileName); + } + + Q_ASSERT(meta.data().format_version_major() == kFileFormatVersionMajor); + Q_ASSERT(meta.data().format_version_minor() == kFileFormatVersionMinor); + + // ByteSize() does not include the Tag/Key, so we add 2 for that + contentOffset = kFileMetaDataOffset + meta.data().ByteSize() + 2; + contentSize = size - contentOffset - kFileChecksumSize; + + // Parse full contents + if (!content.ParseFromArray( + (void*)(buf.constData() + contentOffset), + contentSize)) + { + goto _content_parse_fail; + } + + if (!content.matter().has_streams()) + goto _missing_streams; + + streams.CopyFrom(content.matter().streams()); + + return true; + +_missing_streams: + error = QString(tr("%1 does not contain any streams")).arg(fileName); + goto _fail; +_content_parse_fail: + error = QString(tr("Failed parsing %1 contents")).arg(fileName); + qDebug("Error: %s", QString().fromStdString( + content.matter().InitializationErrorString()) + .toAscii().constData()); + qDebug("Debug: %s", QString().fromStdString( + content.matter().DebugString()).toAscii().constData()); + goto _fail; +_incompatible_file_version: + error = QString(tr("%1 is in an incompatible format version - %2.%3.%4" + " (Native version is %5.%6.%7)")) + .arg(fileName) + .arg(meta.data().format_version_major()) + .arg(meta.data().format_version_minor()) + .arg(meta.data().format_version_revision()) + .arg(kFileFormatVersionMajor) + .arg(kFileFormatVersionMinor) + .arg(kFileFormatVersionRevision); + goto _fail; +_unexpected_file_type: + error = QString(tr("%1 is not a streams file")).arg(fileName); + goto _fail; +_metadata_parse_fail: + error = QString(tr("Failed parsing %1 meta data")).arg(fileName); + qDebug("Error: %s", QString().fromStdString( + meta.data().InitializationErrorString()) + .toAscii().constData()); + goto _fail; +_cksum_verify_fail: + error = QString(tr("%1 checksum validation failed!\nExpected:%2 Actual:%3")) + .arg(fileName) + .arg(calcCksum, 0, kBaseHex) + .arg(cksum.value(), 0, kBaseHex); + goto _fail; +_zero_cksum_serialize_fail: + error = QString(tr("Internal Error: Zero Checksum Serialize failed!\n" + "Error: %1\nDebug: %2")) + .arg(QString().fromStdString( + cksum.InitializationErrorString())) + .arg(QString().fromStdString(cksum.DebugString())); + goto _fail; +_cksum_parse_fail: + error = QString(tr("Failed parsing %1 checksum")).arg(fileName); + qDebug("Error: %s", QString().fromStdString( + cksum.InitializationErrorString()) + .toAscii().constData()); + goto _fail; +_magic_match_fail: + error = QString(tr("%1 is not an Ostinato file")).arg(fileName); + goto _fail; +_magic_parse_fail: + error = QString(tr("%1 does not look like an Ostinato file")).arg(fileName); + qDebug("Error: %s", QString().fromStdString( + magic.InitializationErrorString()) + .toAscii().constData()); + goto _fail; +_read_fail: + error = QString(tr("Error reading from %1")).arg(fileName); + goto _fail; +_checksum_missing: + error = QString(tr("%1 is too small (missing checksum)")).arg(fileName); + goto _fail; +_magic_missing: + error = QString(tr("%1 is too small (missing magic value)")) + .arg(fileName); + goto _fail; +_open_fail: + error = QString(tr("Error opening %1")).arg(fileName); + goto _fail; +_fail: + qDebug("%s", error.toAscii().constData()); + return false; +} + +bool FileFormat::saveStreams(const OstProto::StreamConfigList streams, + const QString fileName, QString &error) +{ + OstProto::FileMagic magic; + OstProto::FileMeta meta; + OstProto::FileContent content; + OstProto::FileChecksum cksum; + QFile file(fileName); + int metaSize, contentSize; + int contentOffset, cksumOffset; + QByteArray buf; + quint32 calcCksum; + + magic.set_value(kFileMagicValue); + Q_ASSERT(magic.IsInitialized()); + + cksum.set_value(0); + Q_ASSERT(cksum.IsInitialized()); + + initFileMetaData(*(meta.mutable_data())); + meta.mutable_data()->set_file_type(OstProto::kStreamsFileType); + Q_ASSERT(meta.IsInitialized()); + + if (!streams.IsInitialized()) + goto _stream_not_init; + + content.mutable_matter()->mutable_streams()->CopyFrom(streams); + Q_ASSERT(content.IsInitialized()); + + metaSize = meta.ByteSize(); + contentSize = content.ByteSize(); + contentOffset = kFileMetaDataOffset + metaSize; + cksumOffset = contentOffset + contentSize; + + Q_ASSERT(magic.ByteSize() == kFileMagicSize); + Q_ASSERT(cksum.ByteSize() == kFileChecksumSize); + buf.resize(kFileMagicSize + metaSize + contentSize + kFileChecksumSize); + + // Serialize everything + if (!magic.SerializeToArray((void*) (buf.data() + kFileMagicOffset), + kFileMagicSize)) + { + goto _magic_serialize_fail; + } + + if (!meta.SerializeToArray((void*) (buf.data() + kFileMetaDataOffset), + metaSize)) + { + goto _meta_serialize_fail; + } + + if (!content.SerializeToArray((void*) (buf.data() + contentOffset), + contentSize)) + { + goto _content_serialize_fail; + } + + if (!cksum.SerializeToArray((void*) (buf.data() + cksumOffset), + kFileChecksumSize)) + { + goto _zero_cksum_serialize_fail; + } + + // Calculate and write checksum + calcCksum = checksumCrc32C((quint8*)buf.constData(), buf.size()); + cksum.set_value(calcCksum); + if (!cksum.SerializeToArray( + (void*) (buf.data() + cksumOffset), + kFileChecksumSize)) + { + goto _cksum_serialize_fail; + } + + qDebug("Writing %d bytes", buf.size()); + //qDebug("%s", QString(buf.toHex()).toAscii().constData()); + + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) + goto _open_fail; + + if (file.write(buf) < 0) + goto _write_fail; + + file.close(); + + return true; + +_write_fail: + error = QString(tr("Error writing to %1")).arg(fileName); + goto _fail; +_open_fail: + error = QString(tr("Error opening %1 (Error Code = %2)")) + .arg(fileName) + .arg(file.error()); + goto _fail; +_cksum_serialize_fail: + error = QString(tr("Internal Error: Checksum Serialize failed\n%1\n%2")) + .arg(QString().fromStdString( + cksum.InitializationErrorString())) + .arg(QString().fromStdString(cksum.DebugString())); + goto _fail; +_zero_cksum_serialize_fail: + error = QString(tr("Internal Eror: Zero Checksum Serialize failed\n%1\n%2")) + .arg(QString().fromStdString( + cksum.InitializationErrorString())) + .arg(QString().fromStdString(cksum.DebugString())); + goto _fail; +_content_serialize_fail: + error = QString(tr("Internal Error: Content Serialize failed\n%1\n%2")) + .arg(QString().fromStdString( + content.InitializationErrorString())) + .arg(QString().fromStdString(content.DebugString())); + goto _fail; +_meta_serialize_fail: + error = QString(tr("Internal Error: Meta Data Serialize failed\n%1\n%2")) + .arg(QString().fromStdString( + meta.InitializationErrorString())) + .arg(QString().fromStdString(meta.DebugString())); + goto _fail; +_magic_serialize_fail: + error = QString(tr("Internal Error: Magic Serialize failed\n%1\n%2")) + .arg(QString().fromStdString( + magic.InitializationErrorString())) + .arg(QString().fromStdString(magic.DebugString())); + goto _fail; +_stream_not_init: + error = QString(tr("Internal Error: Streams not initialized\n%1\n%2")) + .arg(QString().fromStdString( + streams.InitializationErrorString())) + .arg(QString().fromStdString(streams.DebugString())); + goto _fail; +_fail: + qDebug("%s", error.toAscii().constData()); + return false; +} + +void FileFormat::initFileMetaData(OstProto::FileMetaData &metaData) +{ + // Fill in the "native" file format version + metaData.set_format_version_major(kFileFormatVersionMajor); + metaData.set_format_version_minor(kFileFormatVersionMinor); + metaData.set_format_version_revision(kFileFormatVersionRevision); + + metaData.set_generator_name( + qApp->applicationName().toUtf8().constData()); + metaData.set_generator_version( + qApp->property("version").toString().toUtf8().constData()); + metaData.set_generator_revision( + qApp->property("revision").toString().toUtf8().constData()); +} + diff --git a/common/fileformat.h b/common/fileformat.h new file mode 100644 index 0000000..d181567 --- /dev/null +++ b/common/fileformat.h @@ -0,0 +1,59 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ +#ifndef _FILE_FORMAT_H +#define _FILE_FORMAT_H + +#include "fileformat.pb.h" + +#include +#include + +class FileFormat : public QObject +{ + Q_OBJECT +public: + FileFormat(); + ~FileFormat(); + + bool openStreams(const QString fileName, + OstProto::StreamConfigList &streams, QString &error); + bool saveStreams(const OstProto::StreamConfigList streams, + const QString fileName, QString &error); + +private: + static const int kFileMagicSize = 12; + static const int kFileChecksumSize = 5; + static const int kFileMinSize = kFileMagicSize + kFileChecksumSize; + + static const int kFileMagicOffset = 0; + static const int kFileMetaDataOffset = kFileMagicSize; + + static const std::string kFileMagicValue; + + // Native file format version + static const uint kFileFormatVersionMajor = 0; + static const uint kFileFormatVersionMinor = 1; + static const uint kFileFormatVersionRevision = 0; + + void initFileMetaData(OstProto::FileMetaData &metaData); +}; + +extern FileFormat fileFormat; + +#endif diff --git a/common/fileformat.proto b/common/fileformat.proto new file mode 100644 index 0000000..ce2a688 --- /dev/null +++ b/common/fileformat.proto @@ -0,0 +1,98 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +import "protocol.proto"; + +package OstProto; + +enum FileType { + kReservedFileType = 0; + kStreamsFileType = 1; +} + +message FileMetaData { + required FileType file_type = 1; + required uint32 format_version_major = 2; + required uint32 format_version_minor = 3; + required uint32 format_version_revision = 4; + required string generator_name = 5; + required string generator_version = 6; + required string generator_revision = 7; +} + +message FileContentMatter { + optional StreamConfigList streams = 1; +} + +/* + An Ostinato file is the binary encoding of the File message below + STRICTLY in increasing order of field number for the top level fields + + We do not use field number '1' for magic value because its encoded key + is '0a' (LF or \n) which occurs commonly in text files. Checksum should + be the last field, so top level field numbers greater than 15 are not + permitted. We use 15 as the checksum field number because it is the + largest field number that can fit in a 1-byte tag + + The magic value is of a fixed length so that meta data has a fixed offset + from the start in the encoded message. + + Checksum is fixed length so that it is at a fixed negative offset from + the end in the encoded message. + + Because the protobuf serialization API does not _guarantee_ + strict ordering, so we define wrapper messages for each top level field + and serialize the individual wrapper messages. The field numbers MUST + be the same in 'File' and the wrapper messages +*/ +message File { + // FieldNumber 1 is reserved and MUST not be used! + required bytes magic_value = 2; + required FileMetaData meta_data = 3; + optional FileContent content_matter = 9; + required fixed32 checksum_value = 15; +} + +/* + The magic value is 10 bytes - "\xa7\xb7OSTINATO" + The 1st-2nd byte has the MSB set to avoid mixup with text files + The 3rd-10th byte spell OSTINATO (duh!) + + Encoded Size : Key(1) + Length(1) + Value(10) = 12 bytes + Encoded Value: 120aa7b7 4f535449 4e41544f +*/ +message FileMagic { + required bytes value = 2; +} + +message FileMeta { + required FileMetaData data = 3; +} + +message FileContent { + optional FileContentMatter matter = 9; +} + +/* + Encoded Size : Key(1) + Value(4) = 5 bytes + Encoded Value: 7d xxXXxxXX +*/ +message FileChecksum { + required fixed32 value = 15; // should always be a fixed 32-bit size +} diff --git a/common/icmp.proto b/common/icmp.proto index 2cd6025..6abc686 100644 --- a/common/icmp.proto +++ b/common/icmp.proto @@ -40,5 +40,5 @@ message Icmp { } extend Protocol { - optional Icmp icmp = 142; + optional Icmp icmp = 402; } diff --git a/common/ip4.proto b/common/ip4.proto index 6014321..64407ad 100644 --- a/common/ip4.proto +++ b/common/ip4.proto @@ -61,5 +61,5 @@ message Ip4 { } extend Protocol { - optional Ip4 ip4 = 131; + optional Ip4 ip4 = 301; } diff --git a/common/ip4over4.proto b/common/ip4over4.proto index 3da405a..5a146c3 100644 --- a/common/ip4over4.proto +++ b/common/ip4over4.proto @@ -33,5 +33,5 @@ extend Ip4over4 { } extend Protocol { - optional Ip4over4 ip4over4 = 135; + optional Ip4over4 ip4over4 = 305; } diff --git a/common/ip4over6.proto b/common/ip4over6.proto index 11d26e4..0482045 100644 --- a/common/ip4over6.proto +++ b/common/ip4over6.proto @@ -27,5 +27,5 @@ message Ip4over6 { } extend Protocol { - optional Ip4over6 ip4over6 = 134; + optional Ip4over6 ip4over6 = 304; } diff --git a/common/ip6.proto b/common/ip6.proto index aed96f2..d4831ed 100644 --- a/common/ip6.proto +++ b/common/ip6.proto @@ -57,5 +57,5 @@ message Ip6 { } extend Protocol { - optional Ip6 ip6 = 132; + optional Ip6 ip6 = 302; } diff --git a/common/ip6over4.proto b/common/ip6over4.proto index 47fee75..b8b0afd 100644 --- a/common/ip6over4.proto +++ b/common/ip6over4.proto @@ -27,5 +27,5 @@ message Ip6over4 { } extend Protocol { - optional Ip6over4 ip6over4 = 133; + optional Ip6over4 ip6over4 = 303; } diff --git a/common/ip6over6.proto b/common/ip6over6.proto index f260916..f65f6ea 100644 --- a/common/ip6over6.proto +++ b/common/ip6over6.proto @@ -33,5 +33,5 @@ extend Ip6over6 { } extend Protocol { - optional Ip6over6 ip6over6 = 136; + optional Ip6over6 ip6over6 = 306; } diff --git a/common/llc.proto b/common/llc.proto index 1bb6324..e0681aa 100644 --- a/common/llc.proto +++ b/common/llc.proto @@ -28,5 +28,5 @@ message Llc { } extend Protocol { - optional Llc llc = 123; + optional Llc llc = 202; } diff --git a/common/mac.proto b/common/mac.proto index 475590d..2055223 100644 --- a/common/mac.proto +++ b/common/mac.proto @@ -44,5 +44,5 @@ message Mac { } extend Protocol { - optional Mac mac = 51; + optional Mac mac = 100; } diff --git a/common/ostproto.pro b/common/ostproto.pro index e16b4b3..68f1cc6 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -22,6 +22,7 @@ FORMS += \ sample.ui PROTOS += \ protocol.proto \ + fileformat.proto \ mac.proto \ payload.proto \ eth2.proto \ @@ -45,10 +46,11 @@ PROTOS += \ udp.proto \ textproto.proto \ userscript.proto \ - sample.proto + sample.proto HEADERS += \ abstractprotocol.h \ comboprotocol.h \ + fileformat.h \ protocolmanager.h \ protocollist.h \ protocollistiterator.h \ @@ -79,6 +81,8 @@ HEADERS += \ sample.h SOURCES += \ abstractprotocol.cpp \ + crc32c.cpp \ + fileformat.cpp \ protocolmanager.cpp \ protocollist.cpp \ protocollistiterator.cpp \ @@ -101,19 +105,6 @@ SOURCES += \ userscript.cpp \ sample.cpp -protobuf_decl.name = protobuf header -protobuf_decl.input = PROTOS -protobuf_decl.output = ${QMAKE_FILE_BASE}.pb.h -protobuf_decl.commands = protoc --cpp_out="." ${QMAKE_FILE_NAME} -protobuf_decl.variable_out = GENERATED_FILES -QMAKE_EXTRA_COMPILERS += protobuf_decl - -protobuf_impl.name = protobuf implementation -protobuf_impl.input = PROTOS -protobuf_impl.output = ${QMAKE_FILE_BASE}.pb.cc -protobuf_impl.depends = ${QMAKE_FILE_BASE}.pb.h -protobuf_impl.commands = $$escape_expand(\n) -protobuf_impl.variable_out = GENERATED_SOURCES -QMAKE_EXTRA_COMPILERS += protobuf_impl - QMAKE_DISTCLEAN += object_script.* + +include(../protobuf.pri) diff --git a/common/payload.proto b/common/payload.proto index 02cfc04..bafa4c3 100644 --- a/common/payload.proto +++ b/common/payload.proto @@ -37,5 +37,5 @@ message Payload { } extend Protocol { - optional Payload payload = 52; + optional Payload payload = 101; } diff --git a/common/protocol.proto b/common/protocol.proto index 2a5502a..3510e2b 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -78,41 +78,41 @@ message Protocol { required ProtocolId protocol_id = 1; - extensions 51 to 100; // Reserved for Ostinato Use - extensions 101 to 200; // Available for use by protocols + extensions 100 to 199; // Reserved for Ostinato Use + extensions 200 to 500; // Available for use by protocols enum k { - kMacFieldNumber = 51; - kPayloadFieldNumber = 52; - kSampleFieldNumber = 53; - kUserScriptFieldNumber = 54; + kMacFieldNumber = 100; + kPayloadFieldNumber = 101; + kSampleFieldNumber = 102; + kUserScriptFieldNumber = 103; - kEth2FieldNumber = 121; - kDot3FieldNumber = 122; - kLlcFieldNumber = 123; - kSnapFieldNumber = 124; + kEth2FieldNumber = 200; + kDot3FieldNumber = 201; + kLlcFieldNumber = 202; + kSnapFieldNumber = 203; - kSvlanFieldNumber = 125; - kVlanFieldNumber = 126; + kSvlanFieldNumber = 204; + kVlanFieldNumber = 205; - kDot2LlcFieldNumber = 127; - kDot2SnapFieldNumber = 128; - kVlanStackFieldNumber = 129; + kDot2LlcFieldNumber = 206; + kDot2SnapFieldNumber = 207; + kVlanStackFieldNumber = 208; - kArpFieldNumber = 130; - kIp4FieldNumber = 131; - kIp6FieldNumber = 132; - kIp6over4FieldNumber = 133; - kIp4over6FieldNumber = 134; - kIp4over4FieldNumber = 135; - kIp6over6FieldNumber = 136; + kArpFieldNumber = 300; + kIp4FieldNumber = 301; + kIp6FieldNumber = 302; + kIp6over4FieldNumber = 303; + kIp4over6FieldNumber = 304; + kIp4over4FieldNumber = 305; + kIp6over6FieldNumber = 306; - kTcpFieldNumber = 140; - kUdpFieldNumber = 141; - kIcmpFieldNumber = 142; - kIgmpFieldNumber = 143; + kTcpFieldNumber = 400; + kUdpFieldNumber = 401; + kIcmpFieldNumber = 402; + kIgmpFieldNumber = 403; - kTextProtocolFieldNumber = 150; + kTextProtocolFieldNumber = 500; } } diff --git a/common/sample.proto b/common/sample.proto index 6d74304..eeebfda 100644 --- a/common/sample.proto +++ b/common/sample.proto @@ -34,5 +34,5 @@ message Sample { } extend Protocol { - optional Sample sample = 53; + optional Sample sample = 102; } diff --git a/common/snap.proto b/common/snap.proto index bf54803..1354100 100644 --- a/common/snap.proto +++ b/common/snap.proto @@ -27,5 +27,5 @@ message Snap { } extend Protocol { - optional Snap snap = 124; + optional Snap snap = 203; } diff --git a/common/svlan.proto b/common/svlan.proto index aa02f70..937a9c1 100644 --- a/common/svlan.proto +++ b/common/svlan.proto @@ -23,5 +23,5 @@ import "vlan.proto"; package OstProto; extend Protocol { - optional Vlan svlan = 125; + optional Vlan svlan = 204; } diff --git a/common/tcp.proto b/common/tcp.proto index 3aa4382..93bd762 100644 --- a/common/tcp.proto +++ b/common/tcp.proto @@ -42,6 +42,6 @@ message Tcp { } extend Protocol { - optional Tcp tcp = 140; + optional Tcp tcp = 400; } diff --git a/common/textproto.proto b/common/textproto.proto index 8bb290b..12e5b4e 100644 --- a/common/textproto.proto +++ b/common/textproto.proto @@ -33,5 +33,5 @@ message TextProtocol { } extend Protocol { - optional TextProtocol textProtocol = 150; + optional TextProtocol textProtocol = 500; } diff --git a/common/udp.proto b/common/udp.proto index 8852c11..802135e 100644 --- a/common/udp.proto +++ b/common/udp.proto @@ -35,5 +35,5 @@ message Udp { } extend Protocol { - optional Udp udp = 141; + optional Udp udp = 401; } diff --git a/common/userscript.proto b/common/userscript.proto index 484223f..aa1e195 100644 --- a/common/userscript.proto +++ b/common/userscript.proto @@ -29,5 +29,5 @@ message UserScript { } extend Protocol { - optional UserScript userScript = 54; + optional UserScript userScript = 103; } diff --git a/common/vlan.proto b/common/vlan.proto index 802627c..0bfc2a0 100644 --- a/common/vlan.proto +++ b/common/vlan.proto @@ -30,5 +30,5 @@ message Vlan { } extend Protocol { - optional Vlan vlan = 126; + optional Vlan vlan = 205; } diff --git a/common/vlanstack.proto b/common/vlanstack.proto index 203f3ef..d6bacd4 100644 --- a/common/vlanstack.proto +++ b/common/vlanstack.proto @@ -27,5 +27,5 @@ message VlanStack { } extend Protocol { - optional VlanStack vlanStack = 129; + optional VlanStack vlanStack = 208; } diff --git a/protobuf.pri b/protobuf.pri new file mode 100644 index 0000000..30e5130 --- /dev/null +++ b/protobuf.pri @@ -0,0 +1,33 @@ +# +# Qt qmake integration with Google Protocol Buffers compiler protoc +# +# To compile protocol buffers with qt qmake, specify PROTOS variable and +# include this file +# +# Example: +# PROTOS = a.proto b.proto +# include(protobuf.pri) +# +# By default protoc looks for .proto files (including the imported ones) in +# the current directory where protoc is run. If you need to include additional +# paths specify the PROTOPATH variable +# + +PROTOPATH += . +PROTOPATHS = +for(p, PROTOPATH):PROTOPATHS += --proto_path=$${p} + +protobuf_decl.name = protobuf header +protobuf_decl.input = PROTOS +protobuf_decl.output = ${QMAKE_FILE_BASE}.pb.h +protobuf_decl.commands = protoc --cpp_out="." $${PROTOPATHS} ${QMAKE_FILE_NAME} +protobuf_decl.variable_out = GENERATED_FILES +QMAKE_EXTRA_COMPILERS += protobuf_decl + +protobuf_impl.name = protobuf implementation +protobuf_impl.input = PROTOS +protobuf_impl.output = ${QMAKE_FILE_BASE}.pb.cc +protobuf_impl.depends = ${QMAKE_FILE_BASE}.pb.h +protobuf_impl.commands = $$escape_expand(\n) +protobuf_impl.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += protobuf_impl From 8c0bfa84037ce5eaab1d59251423644087b36ce1 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Thu, 15 Jul 2010 03:11:07 +0530 Subject: [PATCH 85/98] Short term fix for the local portgroup showing up as disconnected at startup --- client/mainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index ff947a9..dde1fd7 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -51,6 +51,8 @@ MainWindow::MainWindow(QWidget *parent) localServer_ = new QProcess(this); localServer_->setProcessChannelMode(QProcess::ForwardedChannels); localServer_->start(serverApp); + // TODO: waitForReadyRead() is a kludge till we implement auto-retry! + localServer_->waitForReadyRead(1000); pgl = new PortGroupList; From 716f5fb8f30f3bec7d0317799a0da93199e83f24 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Thu, 15 Jul 2010 07:01:43 +0530 Subject: [PATCH 86/98] Set the icon for the MainWindow --- client/mainwindow.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/mainwindow.ui b/client/mainwindow.ui index 45db008..333b2db 100644 --- a/client/mainwindow.ui +++ b/client/mainwindow.ui @@ -12,6 +12,9 @@ Ostinato + + :/icons/about.png + From 9b1dbfb1e63a18404e2e0a44b8dad9c079150614 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Fri, 16 Jul 2010 03:14:36 +0530 Subject: [PATCH 87/98] Mac OS X improvements - Application icon; 'make install' installs to /Applications; Ostinato is able to find drone at startup (as long as both bundles are present together) --- .hgignore | 3 +++ client/icons/logo.icns | Bin 0 -> 35391 bytes client/mainwindow.cpp | 5 +++++ client/ostinato.pro | 3 ++- install.pri | 7 ++++++- 5 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 client/icons/logo.icns diff --git a/.hgignore b/.hgignore index e27298d..e1d0ab6 100644 --- a/.hgignore +++ b/.hgignore @@ -4,6 +4,8 @@ syntax: glob *.o *.a *.exe +drone.app +ostinato.app # Qt generated files ui_*.h @@ -23,6 +25,7 @@ version.cpp # vim swap files *.swp +.DS_Store # ctags tags diff --git a/client/icons/logo.icns b/client/icons/logo.icns new file mode 100644 index 0000000000000000000000000000000000000000..259376a97074a83086b44222761016de8573cfc0 GIT binary patch literal 35391 zcmeI3iF;K=wzu~_Ck!IWkc5N;*gI$EWS$@i0Rk96nTG&j6cw2wvj{YTz|BY?ga82o z5rWYmIE2P-6mBkpc0>g(9Yh8jT0t9$KqJVM&dpTcTYI0V_x=Un^YrQG_B|)3err|L zs#>dRzwDkpeZgWy$$e_};@EDAV*8)}c%_%96OH$JiK!ccsscs5cwr3xPi)KfeD$fS z`2VJH*ejx;@yC~!y%gRjY_$+IBBn&tSBLeiTK#sRcS&R2ca1(5MdgCeKFKfIFl*)+ zXS-S7`G`>`#oP&>E}S^pGt@awWW+5JwIXU**nsOZJ9pTYESVYHD`=&h zdc+%|{!vi;_18+bw%aYI?s-A{bza4>yzT3!Ppb@gV*0mUV%P~WJLQx4<3_e|28
G!v_cV zyFT5|vp6S7lT+{V@Nsk1M=jY=9l_K$&D=0ZPJJp<4<*Fy&$VLeK{sapC?+xWX{)WN zKNB>vyEXOx*3@5=tG+L;Kiid6Z&@IxKDtH3o7U8Oc5s9mDZftL_;u=wd(5A!C~8ab zZ~mXz^JD>NwcXw|Ks%i!{2Imf$BT(p6>b0d@uV)n@%;nhL~S~azl8fOmbPtw zYW3L>AMX}XM)bl#hW|&Rf!4-r0X}bt#x&8k;epQ-|A5k)54$9ZU%G@nwj)C{YZQO= z^ZhbIbh_@}vAEN{|EYKO6#p{(vs<1Llrcv3j<4fqM)2Yn%|8|0J`^G>R{W3A;giJ! znDC7cj@OB0K7&PlgLu{Fp?JHes1NEbe$jo7?(f)8H{ZwGv->U4uS2$|yWizG@;YLj z&_;?YeqI+>ME=m*FW4E>`2|ts@I5EyKY1oiJo!_biJfPQPrUVY_AUMafoaC$jtN4% z;W_+`mLznVXni9gAZA`lXUAhpMQ{+!LEc}8{}E3Ic#o9Z+P^_8@E!h?!|3~iXfS-7 z&LGdTLj3DM&%mw?b?L&tUPNlQYeIb4^kP+Igr^qJZ$uye=FTujHPx3?zH8caNcP(GR;u5V|3OQmIM&hsPLjjEOFr)aMAVz|am)WwiQ6h`UFh_ccN~w;lfvQNLDrKIQGx$uH1| z4(Zh1&)+j>Hp6Jh6>YEWpQi^pdnENAIdk)WbGp{A7cJ@=#pTDtp17JR)cS^vG6su` zWumsezM*lGut#?G|8Fx1x3$>GaA!uo{X{>J*IE{RaWBKm&y|GpAG=xKv+dYwKi_}e z^3$v&oY*nim4qFZ9Bm!=gkb+g!K$ zM^V0<93mz>g3u;zqCgEvsuP;c#AAP)c`I3YI-NnB&pG^BnR}${^>|!S2 z=jtaS`XJ>#TGVLmkG`D5gl`=9tWGTPd`7O$()JIg^sQis2oX|p+{sytaJ5B_3p%jv6S&z3H(dPA%866&5 zNlT+R>g98%PnUoPvaL@1eVXoQ(b6$pCSilP*wO2+gZ%@3bS2>#^~gV6N%)nI_I?i^ zr#;wWN!Yucr*8*ciwN|6(%YwvBh{6J|0tW|uLs2Sd1~0SO{acK!b>fJT3-1r z2^VNfeoextE}g8Cu(0JWnS@bqx9KnPo-mW}ex|p7QxdkiS>LN&O0~b=KX3W#RuWF~ zi*Y5P&(fn$INNL<^W+gRxUK6X?BV}ZQxbN*AM9v%Y;!A;@X0x@B#iFJ9Y!Xhdby(Y zKaY&}5A2rIrJE}WLpxYW_*3(WBVO%2BJ_y)&*;7%x{|Pq*KSu5dQJB2^486V{(Z$S z{=v<+TS?f#+e|{=4!b&%gbtEW_s#NXO2U0!nw5n1Pecq!7#t&NbkAdpeoexqUR+8W z#2-9K!tSCzu$TCyv)9LE9UAK9dbMvGdrLg!nMD%%Kg-q&T`M{b7vK4`yRba$hn_xx z4#V#`QKfl*E#|f|lkoBJeyQSE`_4H^fp3?9H2rZ+CSjW)#U4Cg$dfRxOXQp}ep>Uz zBG91OXeX1ff0y>dT}e34duVS>Pb3L-FNecuD^J2dCIm#ek}$l}?HZ@IOv06a4Q<=0 z%TvR8`Pv-8nw5m@`ib3Motu(yf`5P!H~B5m-`h&UDQycxZ$FBnbrSxXgx*#X`ug81 z_wxL|N!ZhACE*nBRMEZDL~}8tewT#p$D1eN`3^pJH~RXTN$6=Np?MOHZe=B5qF45h z9emc9N%)F=Oj8oJT*hEX!Vd8wSaT&|>-Hnt?kt(<(`pqhB%!zOoj#hQDG8?s7>_+> z%y1>4Ux&XA?&N4X3D4MmO~SLjdRb53ATtS{``<~}E_SuieyEv*{y~Suxuzr>+pgO{ zPj4#;1A^N3PH$l)p||ezdm_a;3H!A7>gW@oM>;#U>EPSeXiCCsWpg?QIO6+0HEjC- zO2U@Gt$vq;3-zT?QK?G$B*rKWhzjZsQ)Iz8jor zD9iGNay;Fzg^J_ZhB7o$DD$%nWynUc&QNmS7V0NXL_70@dOSMaun!QTFS4o(p`7LO zRKBnqMz8QShEn#nPNKGw@g=f0g9m_E z{1oJuGhb%`jBw-?N1JMI5eQqb--u<8-kC%f1bHLb;bN)S475o~y^= zo6rn%2MxeVoT46N@kSJX(O$KFoC`!(YR2P7{Vn#Az$Sehgs@_n?LZzD(aD z)Qk8~it&0U8n5H%{qO4ydnrMY^Q*;Y8eal`MEY?c(m(AH%66O{!C4W?*cx$+PA?!l z#pj-_{LH9=D@ui0-4mCi5N^mb>>r7Hf%N$J79 zBWPZkC6rWpj&IybRL3KXyYdz>Ok&B9e24Oo5E&?wQNB*sm$nJ@=e`L0-g-+YIdnaf zuIJ|(9`V&e9B!IUCDM{Yp)*EWqBy`0^LU}L8P&U6I z)ce7-|IAuR-T5?OzfrcR#|}f8@w!mnMDy+&LK#HUWlLhe^JxF%U4|N6PrJD~CwB{F z3W6`BfV6Thi+aOQ&h8Y-CPp52tyn0p(ENdH-fO6<8)-?WWyqsl>?vA`Wy?0B`NI74 zC9_hZ$ki8bz0S6phbUF5Uq_Ui#%7(6YuMxG?^#8R$})tl@yfCsL+xIHxMmWw&O>`3 z!|+%tYI1{e413(%(#tHtUgUd;*1LFiet`Ji5V`pn|8XMu;)wxk412jeHZDC#B4(iJxjdMDxqtb-m&^MBnQGGgkP*TlsC~`?uxGGjU7VyV1uFD$q~v$ z6kAYS$YX<}I2D2-xn{dicCIy)@N`0i>ISL}sID=h$s}*r9~ssG{#b}`4c$e)SA_H+ z(i)^WNbeJt{aetc$R)@{TUbblvkm*$@5M#LTh|IDoU}?qT#buTAvbV7V`xl8eS~D0 zl4&$|ZsGy3v3r`KOv4}%gB6x{`|F~9NIKbc2a`v`7j*d)Z6Ksw*FQ>fRwV>93pwZq(8rwHtRnm)y(A13oLxy?XWQe{5<#8zWd zNqCgS1?IL@LuxR&g-JRleK1MI7Dm)COf6&4PKnyZmIU(m~81|QL3r=cf zD9&qxvJH>ELflFu`JWZ{82#6=+c+#~Yj{D9naH0HL49NclOKvI{>WdTQwUwY#}RWnu*k55Y^cr@uTv&( zvc{DZz0DNKi#s^S=Kmv`1|^+!n@)LLN|oAPXxN@Ex|Jh}40ReTQ#qe&s4vvgGM6A$~r4xOgTJ$;uVmP_4eQk$p||AO15% z{~!Y!Pslh{l+#k6M6&>2OrU+l9ZJPw+BdT{^|G4xY_t@4!uIIkc!FKFi|QNM~$u6OE9ww&6BX*V~Ft?ax-`#FdnF}nxhC`xg+6?fYikYQZpdiKS@ zGQ1O#JuoA;IVBfP?Z$&nS&mnlJz{@f=t+66o*sd22 z*=2Z)E^ja|HjCuq;B6-|&Q;~SlhlZNNbtfz6fNyas< zL6)G+9Firt<5r~JkmqagO{qKjn@+hyubhu+HD{7?25+nIwtze{ihrlNii(SzQiw>V z<8>}+N~KgS`km?wsuSD{@5LfJj<1!dQa7U-@H^FEGC8Q4nQTHe7H8kek%fG}SuXEw zc>|X-zv-0iI6Q*Gmr%{4-)e5o$}8Ih^DLz}nByZ#ccO{R zQ2J5crRS&{_>=d*@EcO8hMuPkxunW6ITb3_m2h0j!}TLN-cl%V(DgKX$<%G4*t16l zH89lLWL%B_wX1)Z4>BWa3I$E!pHeVQE!9FM(+6~(hcb|VSyLYjL>coB_Rv7I!TTx4 zrj{M~k&^)|U;roOQM8%?%wYgW*zebSV?O_9HoU2ohcoM;!Xsa`MCA5-`x@fPD)z?bk#jN@bwCFpDU95I7`-?HTEgze6TXeqmZ zUfv4JkYA2PlyHmN$;mh_xg+-1n!Y*vudm^;R1H4DxUb1QwG8$5J^0Cal8b&-3Pm+e zUd5v`g}wSOnS=Pd&l$w^jH%hM8X<1sWBcqDe$s2<^KD$=EQF?Y`t@CPz5e94-ftg|4KhvCp`M2us58} z9moS)?3_JUisaEv`zj$$#?n6d(LqiY4vhH0&%Ltd^#kV{i0LWmVNs*_QwWOZsy}qa zmf=^hx$JZ6#a7}lwdNyN!&^cfa-AY=LQynlgeNcbucb9{l>d z@i<60S|+ogZ$(oUuz&Bp%1xwS$tdjS+}SVK9JApC*6a#}t!8&TKTS%dIp)9tE~==V zORhC-;H?}!dlUIBXh0N_=c+ycn%F|pBsVYvMDeQKpTr5>bARKX1nczN!5Xt+ldzpx z%{|K&x`9>7Cy$rOotP)=jh73b-cC+k`-p>Ejp7F1tp3&~n_h_K#`El{!(0klhV&fz zZ0hus{$1Hp&iQA{#m9y%Y}G%GaMv$4Y!ga~D$G6YvTgs(x!S2eMuZ8{RzijEfgL~Dm=_|GzxqVqEBi9*E#%_4Mq;$`|_sR}@ zaOm{4+V44G!nhmsy2F=nz6`u8lyQ8%!e(Q^F@r>mIU3Q{I1DaB0?5{RmgP>9VO8=O;!WB7 zm++}KUqU5(s*A?Igio_5j0>^oZ^Ea<3{4H-ZlHeN71yuQCdX4j7t66s{1rYWV==jo zJ}x>l%ps`Xhw_uTiOyk>fyHq?P59J{xh`k;nGEMt2KPncRKQ^RGK3MCEKV$6rc%T% z;zQYm*Eldkr)@Yb$5|oD=o)d9PA&LE7^!$W z7?n{`%7GS-%i#!f^ECTGaZjhueRST~l`nItaIc^Y{i>9Ebf#vn5~2Xz9wCO%ygW-N zGwHdT37^Iy>?+|?U2m2Q$#*Dug(My2NR&kk;Ts8`5)md!_>@i8FVgj#T+O2!Wa$vT z%;{7j-Aw_#6oz!Lgij|jv}QpPJ|z>Rcd)sQe=OginEJCz$Xl8owrd%3wA& zBUv6&{gLfs6e;u(Wx^*1`cw&@79wAcWKV`>n_2M?(W_Zn%K=N%a<`SU#p%d|PcpKv zAwP&b0eLx}Jf_+%6%Svpsgb?W?c#>{PL8H*l<>)*-GWby6!=v2{=&E&Yzl6*C1~~m zpPoi?iRHwV{m#R(iMup4LXwX{hGv`qK21V!Tnb35fF)sXXv$YS6XeqzBjM8mnh(h4 zy_&jG;-oZM20h?@o=M9t*|JS*K0hz*l^MxlOe-TFXItaa^uu?>2YO zN@DcB37?kcXlkqppT@7zlw7p?Gc^7wvSzI#N3+MImT{2XxF0UR>oCEvnO8#KG7?;xZq4pS&g_F z7o{SLvF9;{#+j(gNtQ{OTJwPXI^a`mnx?#fK>`LcPw;Lp5_N;p$tDS(9u8sHp%+O- zHi4Qb;q$^YO%0OpDG8fbu(`WN^T-#XQm6BL&im`J*d%d1wlG%4FFGh+0b{pG_*9`|eu#reRx0Ibd2l4sd&m_m!|`y4 z&r&?>!^3nuL`nFxHk!Q~`z4)hWb6?VK2Z^s-K_CD1bei6be6k=mn4)tjQ@;re~kNc z(40!jV}oxo;nPH{lj|gWiep7WBz&stgDxk7VdyxJ@M#$iP7&g34q6sU_>`t^G*?)? z#U@bJa&Ia?yG+8T05ogq?Ft*Y7USs{UuQvAGPzxp$g4>OL_;24a^5Cke;B+t*R>G%)beO{U zYer;}W)ePq8Ntc19+Pas6PBel?+SdY; z*c@MRpp_Vu_(TFr^Xn2mjU}r2fplrYC%uT<(|QS?D3cOCou=q*lzd}{W;5n~4}2nb zS+}W_$5*IQ+X^*Xza0`jY3d6SKAp?e)F~1^jpgJU(LWenFW{4A(`QNel**h2oA8Od zSW82~r>_pZ{vr{{gdCxIO~R)=RR6&eKK+@2jU{9pD<*u>ln55!cna-9Bz$_A_KmDf zy{zW(5~a#73=kXyxUq2X}us_vMHA(|eHugHbQV=S;aJ*m7zw37<5rfStE+KL^nR zitB?A6mR0L0C(FMkfvQsXaDyv<2WTaZ?o1WeBuVGIwgG45+r=u5>%qulHQ((bpf&w ze9CKV1zwi0X|?6qJc(`@v`h0Cb-2O2*esNbgSR4NoU6(?DJud#UCK{lZIZGp)2Su+ zS%Ppivvip7$-rbZ593-1@abF*6SIepE4W0ckE2~K;Zr1Ers7q`Ucx8s9r-MlskQDJ z5fU2TKY7Z${PG_pe3D098V4j>jUq49pX7lUE8&xNK$?)r5gbj@N%*u9Z}Z4A&4N#K zib|HGViP`T$~c@|=aQzJma6%`^HquJO9`K%@Ku4Y<*25ERkWnvsSc6J4hf&~Q6=N- z+dxJZcoq1hX%>94I+aCbq=Zjl2#>PvjpOjQmghH3%g_653i8ZM!(TSCVf4C>3qY)d zPns5O!6*DdC$2KQgAzUkAuPw=?MVE+4^-mNA?M5pqbo-D6O&%aum(x^G#`f}C4Ay! zv)~gBDJ?ZU>3O(>Pt3rCPoL%x7T^Z9X_7 zlkh2m$PAM3X&*g@{Y2059vD(3m8$a`Wyl;NXZjL36&@3=gy2#ht_SJ30Qkg~u;3Fe zflr&+BLhtMG!mCXBz(FoA7q9|_@t@97JNcWwUEhlfX;JK>Lz^Zk22zW_7InD)hMGJ zoBgvR4+b!Rc?{r$Jc?dp0536satWV$Vm|lhOqW(3&a4Zxi+J6WZAlV76`@{Bf`7+j znA+`dhD$BsQ!>9KNcc35FTvk1;uG?QKVHJ8vtfLjegX&PKqP!xAAu}H!Y6qvd>{Fx zXhg9RKAni+k~^df_{0n)e9GjpR5i*O_YdKWdnxLxar_i;f{Xt3WQuBxyoyIi`1EPU z)BN455^?=#j?*E)r>aE8UHB%4WJbQ$+*w$dJAZUM4-GRUd|Hku{0i`?e~!GDmkRZ8 z#2a+Ci>%zL?k@s1D~8ICR^}{5HS3TVD8MRb)tYcOtIh-4Q~mxoKj*> zYp7X5!_=BRP4J0ELQ_I9=Z1VyMsI2D+d_@A;1jJ9J}sg*=fTEZvbVrJz$eYH;1lf< zJ`KY<^2E(&u}+Zi2`3hOqMao@9z%Pt%jGe&Pmu75CwmJ%(GGlin9hc@y>MmuI!(=# z@QE0&en@pS_W(Ptf}_H26z%JVgIEclIL9lvHkj=aJ}u=Y(r5Q@>|c`bNmFOR3#?`d zpNhNj)A*S*N9;eqMHO|xA`3n-0tuh?B=DOfDGbTv>%b=#a+L+25J>n`)|(SLzD&X= z%|7|hz$Y3cd|Jspi+cmBlusTnl|M`PbZJY!?c|h%PhgG*CVV=UKP7@2&qN8Iw3g2J zK@+D>O-_nrO9jmR3izbif>wTigu8yZW*b*x!l%mY-Ul_?s9jaSr*pXj$~1dma-j*I zKHK(EVkwutdBqld`m~_u4y}3DAyb!cE|>6W=sNAm=-i^>l09#~^M2WZ4^LU}DTup4 z_d6UlA$;k7mw)8pa{-@Oe3smW5Oigc`%CzAkf7cahAd>Lucx1Y6?XsS-Zv=9^CwaJc~Zqz3|@blCIT5*Ar@TBJRCF(ZK27-4jV}^DEoS_o)|*ed1)p>~uQd&&c?H=u zlljNG;FGR)Gv9pb!;+bAKIyzm#T`v|!6)5%^Qku;d*6DCiPN=&PxEqhk605vxu#Re zXyuzvm%@<_k?`qchTbgLf={{&KIs;G3c|e!pPXnd_!NU*3qCO$Tc8P_1|ZwVc*ir| zXcv59^IGtUsSy9Y8M+HTt;o__KD{(;eIf8^os1mS0Y)tMH2 z(oOjE&A43M9y^yepGZCvJ}t}9)i@JAO<>mRc@FtwhVHRg)U0#lu%Bj|@M$k{`R3C; zJUd+QiOt9Oj}yt~zwEb0x5s6>;FE4bfkW%qrzU*rnax_uH=jOZq(N(#o(n!vBJlb7 zdUgOc|56mX?iPH~UGRx4L2)6E4UXbe5DFK3(v^^OLS){^btMngHHJSigXNL%>5u#& z;ZrudhVb^3A8XG+mjBK>`NLF}P1KibVaObh60>pZF%LQzWF3Km-Xh8Zo;R&nDAZ<@QGS0Q;L3~P54B3O!&mMRh<@m z(oOi3h=~QC@Q%q5Tw3snU0}i|T}jRs%HT9yS@4N+L?2c3VZtZMxUv@bL@iW9P52}; zFAJMJv`F|A=bFh?Op3^bG5nrv!6y>idh5r6{=KC!%MCVbK@_>>;7QI~j8y~QSQ!6!~J z37;HTucNmspV+S(x&KFF z6v}@kd?KZ7i}wX%2Yk{GoDQMFO8E349gb)GHKVv2Snw&5XrE3Uyn5^UWt+ooc}+y$L?)wowB@&?N$&bX!2Ggio`X(-0FraTjYD zXukO*;S*U4IYMQ^r@d7FAr^dM7DSn2#e`3~63GG_A5Z&G3qEnyvBQ8*RA~vHP{=o* zfKNnI!Y6r+u;3Gg6ZoX-0V6h}GT~EdFymWc!Y6t15o=jUC4AEL(G8`M8};Ad(?|I; z6G?#~CVaB)R=_7NUlKm)x&@yIv-##zD7{+niQ60l(sdVn;y5L2``8^OeBuVG21)p& zTkt8kM7QPkIx4(mj$*_(X1+@QLEa*yk{I37>QeKJ{a5n&1=m zCVXOix7d|80~x@We54k9Vq*4)Cip}|xNg)$(fKsI%GgWzq+9SwZ{002G_?DG zH$&uBq*h6Hff7FH)|*eJ4){c5+0oUq99eHZaRPyrbPGONs;j8@S47_6&@K4HCC!9S z`T`RxS*l7@CVYxUcATr#3RE+}Dtf=)sSc6JF8D+NVr1Vs8JSbUCtbJTljUv|Gce&( zIPP5ViMjLqrt21bvUKvyOeZqg$VSlXJ}ysj5(B8kjk3qJ86WWgt@o`g?qZwo$|Qs5I);fdl(C>_hg z^}`&tI`D}tVZkSKz^4NC$kQ(PB#RtJ5%7s`52PXs1>lFtz?_=MbqPm$%LK8m4$n`hhe2U?c zJ5;{;gjm9-Y&rKp6Fx;SZu#cZ)p&k#NcdDWnxYybui}vwe0qkz6HWLuhU3%)pLAvW zn;eoE`Fiu9!ou|n#&qYQ!GupM5Jkv0pZZf)XPWRS@(sGP;FI3WA>Vu&O4|q%KBWim zq)yM4@M-@V-GonLXdGp|`4mE_cbf2t*SmESKFQY67JQ1`qT6~|@QK{;$TQ)Su8y!easODF}rNJ`n;QDJw#_GtaIE zKJmn1!6zEt;>`$3i3Oi@b=q(6iAF*Le3Cchi!yrVn@{l;e4TkuJ@CrbFlbR>Mzo8S}eCVXN;+NNGz&LuBf z!Y5+vf=>w8amN$sAh2j(EDqu%d}56)_(Zz}pLAQ_lHu5!@JUxw;RV1anoal=%YKRGP;2A}#I)NRQYe9C*eOt(8nZ@1u6A@GSy-*51#*ADJgL#8b+FyDL{woZRC zCa-9B$)0`hyubgzM=tmj%-ta24o6KWUj_i3Quut?gijRIyTGSzEV2ooJ|t)XCVb*a zLhb8^|0$+>`tAt0BjApJI|A+qxFg_>fI9;22)HBQj(|G? z?g+Re;EsSh0`3U7BjApJI|A+qxFg_>fI9;22)HBQj(|G??g+Re;EsSh0`3U7BjApJ zI|A+qxFg_>fI9;22)HBQj(|G??g+Re;EsSh0`3U7BjApJI|A+qxFg_>fI9;22)HBQ Yj(|G?|9?ba_Vfkg6-8B{!T Date: Sat, 17 Jul 2010 03:54:35 +0530 Subject: [PATCH 88/98] Mac OS X improvements - Ostinato is now correctly capitalized in the MenuBar; default Wireshark path added for Mac OS X --- .hgignore | 3 +-- client/mainwindow.cpp | 2 +- client/ostinato.pro | 1 + client/settings.h | 5 ++++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.hgignore b/.hgignore index e1d0ab6..a88c51f 100644 --- a/.hgignore +++ b/.hgignore @@ -4,8 +4,7 @@ syntax: glob *.o *.a *.exe -drone.app -ostinato.app +*.app # Qt generated files ui_*.h diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 6ecc7cd..87ae5d5 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -44,7 +44,7 @@ MainWindow::MainWindow(QWidget *parent) #ifdef Q_OS_MAC // applicationDirPath() does not return bundle, but executable inside bundle - serverApp.replace("ostinato.app", "drone.app"); + serverApp.replace("Ostinato.app", "drone.app"); #endif #ifdef Q_OS_WIN32 diff --git a/client/ostinato.pro b/client/ostinato.pro index 0b352c0..299ecc5 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -1,5 +1,6 @@ TEMPLATE = app CONFIG += qt +macx: TARGET = Ostinato win32:RC_FILE = ostinato.rc macx:ICON = icons/logo.icns QT += network script diff --git a/client/settings.h b/client/settings.h index fa22e54..3fbf4cf 100644 --- a/client/settings.h +++ b/client/settings.h @@ -26,9 +26,12 @@ along with this program. If not, see extern QSettings *appSettings; const QString kWiresharkPathKey("WiresharkPath"); -#ifdef Q_OS_WIN32 +#if defined(Q_OS_WIN32) const QString kWiresharkPathDefaultValue( "C:/Program Files/Wireshark/wireshark.exe"); +#elif defined(Q_OS_MAC) +const QString kWiresharkPathDefaultValue( + "/Applications/Wireshark.app/Contents/Resources/bin/wireshark"); #else const QString kWiresharkPathDefaultValue("/usr/bin/wireshark"); #endif From 971713ae0f1d86f41c5fd1c8f7b51fbe969164b1 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 21 Jul 2010 14:10:06 +0530 Subject: [PATCH 89/98] Replaced HTONX() and NTOHX() with qToBigEndian() and qFromBigEndian() --- rpc/pbrpcchannel.cpp | 26 ++++++++++++++------------ rpc/pbrpccommon.h | 39 --------------------------------------- rpc/rpcserver.cpp | 26 ++++++++++++++------------ 3 files changed, 28 insertions(+), 63 deletions(-) diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index c89a2d6..47f1611 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -19,6 +19,8 @@ along with this program. If not, see #include "pbrpcchannel.h" +#include + PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) { isPending = false; @@ -130,9 +132,9 @@ void PbRpcChannel::CallMethod( Q_ASSERT(ret == true); len = req->ByteSize(); - *((quint16*)(msg+0)) = HTONS(PB_MSG_TYPE_REQUEST); // type - *((quint16*)(msg+2)) = HTONS(method->index()); // method id - *((quint32*)(msg+4)) = HTONL(len); // len + *((quint16*)(msg+0)) = qToBigEndian(quint16(PB_MSG_TYPE_REQUEST)); // type + *((quint16*)(msg+2)) = qToBigEndian(quint16(method->index())); // method id + *((quint32*)(msg+4)) = qToBigEndian(quint32(len)); // len // Avoid printing stats since it happens every couple of seconds if (pendingMethodId != 13) @@ -147,8 +149,8 @@ void PbRpcChannel::CallMethod( void PbRpcChannel::on_mpSocket_readyRead() { - char msg[MSGBUF_SIZE]; - char *p = (char*)&msg; + uchar msg[MSGBUF_SIZE]; + uchar *p = (uchar*) &msg; int msgLen; static bool parsing = false; static quint16 type, method; @@ -165,13 +167,13 @@ void PbRpcChannel::on_mpSocket_readyRead() return; } - msgLen = mpSocket->read(msg, PB_HDR_SIZE); + msgLen = mpSocket->read((char*)msg, PB_HDR_SIZE); Q_ASSERT(msgLen == PB_HDR_SIZE); - type = NTOHS(GET16(p+0)); - method = NTOHS(GET16(p+2)); - len = NTOHL(GET32(p+4)); + type = qFromBigEndian(p+0); + method = qFromBigEndian(p+2); + len = qFromBigEndian(p+4); //BUFDUMP(msg, PB_HDR_SIZE); //qDebug("type = %hu, method = %hu, len = %u", type, method, len); @@ -193,8 +195,8 @@ void PbRpcChannel::on_mpSocket_readyRead() { int l; - l = mpSocket->read(msg, sizeof(msg)); - blob->write(msg, l); + l = mpSocket->read((char*)msg, sizeof(msg)); + blob->write((char*)msg, l); cumLen += l; } @@ -229,7 +231,7 @@ void PbRpcChannel::on_mpSocket_readyRead() return; } - msgLen = mpSocket->read(msg, sizeof(msg)); + msgLen = mpSocket->read((char*)msg, sizeof(msg)); Q_ASSERT((unsigned) msgLen == len); diff --git a/rpc/pbrpccommon.h b/rpc/pbrpccommon.h index 5cbbb57..0f4acf9 100644 --- a/rpc/pbrpccommon.h +++ b/rpc/pbrpccommon.h @@ -20,45 +20,6 @@ along with this program. If not, see #ifndef _PB_RPC_COMMON_H #define _PB_RPC_COMMON_H -//! \todo (LOW) check which one is right - wrong one seems to be working!!!!! -#if 0 -#define GET16(p) (quint16)( \ - (*((quint8*)(p)+0) << 8 ) \ - | (*((quint8*)(p)+1))) -#else -#define GET16(p) (quint16)( \ - (*((quint8*)(p)+1) << 8 ) \ - | (*((quint8*)(p)+0))) -#define GET32(p) (quint32)( \ - (*((quint8*)(p)+3) << 24) \ - | (*((quint8*)(p)+2) << 16) \ - | (*((quint8*)(p)+1) << 8 ) \ - | (*((quint8*)(p)+0))) -#endif - -#define BYTESWAP4(x) \ - (((x & 0xFF000000) >> 24) | \ - ((x & 0x00FF0000) >> 8) | \ - ((x & 0x0000FF00) << 8) | \ - ((x & 0x000000FF) << 24)) - -#define BYTESWAP2(x) \ - (((x & 0xFF00) >> 8) | \ - ((x & 0x00FF) << 8)) - -//! \todo (LOW) : portability -#if 1 -#define HTONL(x) BYTESWAP4(x) -#define NTOHL(x) BYTESWAP4(x) -#define HTONS(x) BYTESWAP2(x) -#define NTOHS(x) BYTESWAP2(x) -#else -#define HTONL(x) (x) -#define NTOHL(x) (x) -#define HTONS(x) (x) -#define NTOHS(x) (x) -#endif - // Print a HexDump #define BUFDUMP(ptr, len) qDebug("%s", QString(QByteArray((char*)(ptr), \ (len)).toHex()).toAscii().data()); diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index 4b86b25..d48de21 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -20,6 +20,8 @@ along with this program. If not, see //#include "pbhelper.h" #include "rpcserver.h" +#include + RpcServer::RpcServer() { server = NULL; @@ -87,9 +89,9 @@ void RpcServer::done(PbRpcController *controller) len = blob->size(); qDebug("is binary blob of len %d", len); - *((quint16*)(msg+0)) = HTONS(PB_MSG_TYPE_BINBLOB); // type - *((quint16*)(msg+2)) = HTONS(pendingMethodId); // method - (*(quint32*)(msg+4)) = HTONL(len); // len + *((quint16*)(msg+0)) = qToBigEndian(quint16(PB_MSG_TYPE_BINBLOB)); // type + *((quint16*)(msg+2)) = qToBigEndian(quint16(pendingMethodId)); // method + (*(quint32*)(msg+4)) = qToBigEndian(quint32(len)); // len clientSock->write(msg, PB_HDR_SIZE); @@ -118,9 +120,9 @@ void RpcServer::done(PbRpcController *controller) len = response->ByteSize(); - *((quint16*)(msg+0)) = HTONS(PB_MSG_TYPE_RESPONSE); // type - *((quint16*)(msg+2)) = HTONS(pendingMethodId); // method - *((quint32*)(msg+4)) = HTONL(len); // len + *((quint16*)(msg+0)) = qToBigEndian(quint16(PB_MSG_TYPE_RESPONSE)); // type + *((quint16*)(msg+2)) = qToBigEndian(quint16(pendingMethodId)); // method + *((quint32*)(msg+4)) = qToBigEndian(quint32(len)); // len // Avoid printing stats since it happens once every couple of seconds if (pendingMethodId != 13) @@ -187,7 +189,7 @@ void RpcServer::when_error(QAbstractSocket::SocketError socketError) void RpcServer::when_dataAvail() { - char msg[MSGBUF_SIZE]; + uchar msg[MSGBUF_SIZE]; int msgLen; static bool parsing = false; static quint16 type, method; @@ -201,13 +203,13 @@ void RpcServer::when_dataAvail() if (clientSock->bytesAvailable() < PB_HDR_SIZE) return; - msgLen = clientSock->read(msg, PB_HDR_SIZE); + msgLen = clientSock->read((char*)msg, PB_HDR_SIZE); Q_ASSERT(msgLen == PB_HDR_SIZE); - type = NTOHS(GET16(&msg[0])); - method = NTOHS(GET16(&msg[2])); - len = NTOHL(GET32(&msg[4])); + type = qFromBigEndian(&msg[0]); + method = qFromBigEndian(&msg[2]); + len = qFromBigEndian(&msg[4]); //qDebug("type = %d, method = %d, len = %d", type, method, len); parsing = true; @@ -216,7 +218,7 @@ void RpcServer::when_dataAvail() if (clientSock->bytesAvailable() < len) return; - msgLen = clientSock->read(msg, sizeof(msg)); + msgLen = clientSock->read((char*)msg, sizeof(msg)); Q_ASSERT((unsigned) msgLen == len); if (type != PB_MSG_TYPE_REQUEST) From 3ed82b88ca1a007d37bea8f139093e3b7be1e9ec Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 26 Jul 2010 11:50:36 +0530 Subject: [PATCH 90/98] Updated .hgignore --- .hgignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.hgignore b/.hgignore index a88c51f..cd5490f 100644 --- a/.hgignore +++ b/.hgignore @@ -5,6 +5,8 @@ syntax: glob *.a *.exe *.app +drone +ostinato # Qt generated files ui_*.h From be77148b117f74f5d20fbe05b8aa973ccd465b1d Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 11 Aug 2010 18:47:25 +0530 Subject: [PATCH 91/98] Bumped version to 0.2 --- version.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.pri b/version.pri index 236cdfa..c370b32 100644 --- a/version.pri +++ b/version.pri @@ -1,4 +1,4 @@ -APP_VERSION = 0.1.1 +APP_VERSION = 0.2 APP_REVISION = $(shell hg identify -i) #uncomment the below line in a source package and fill-in the correct revision #APP_REVISION = @ From d8b9844dacbe27cac6e70d26c1151533fa5b0a48 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 15 Sep 2010 20:58:10 +0530 Subject: [PATCH 92/98] Changed QProcess()::start() to the overloaded version which plays nice with spaces in the pathname Fixes issue 9 --- client/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 87ae5d5..291865f 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -55,7 +55,7 @@ MainWindow::MainWindow(QWidget *parent) localServer_ = new QProcess(this); localServer_->setProcessChannelMode(QProcess::ForwardedChannels); - localServer_->start(serverApp); + localServer_->start(serverApp, QStringList()); // TODO: waitForReadyRead() is a kludge till we implement auto-retry! localServer_->waitForReadyRead(1000); From c5fbceebb48dff7a1aaa8322e4ec5465c2046472 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Fri, 1 Oct 2010 21:29:55 +0530 Subject: [PATCH 93/98] At port init, the sendqueue dirty flag should be false not true --- server/abstractport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/abstractport.cpp b/server/abstractport.cpp index 954278b..5a08911 100644 --- a/server/abstractport.cpp +++ b/server/abstractport.cpp @@ -34,7 +34,7 @@ AbstractPort::AbstractPort(int id, const char *device) data_.set_is_exclusive_control(false); - isSendQueueDirty_ = true; + isSendQueueDirty_ = false; linkState_ = OstProto::LinkStateUnknown; memset((void*) &stats_, 0, sizeof(stats_)); From 90fda499dd370bdfccd4459af6c4b120adfc5224 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 18 Oct 2010 17:25:27 +0530 Subject: [PATCH 94/98] RPC now uses stream instead of an array for protobuf parsing and serialization. This change removes the limit on the byte size of a protobuf. Because we are now using a new protobuf API - ParseFromBoundedZeroCopyStream(), the protobuf version has to be >= 2.2.0 Fixes issue 14 --- client/ostinato.pro | 2 +- rpc/pbqtio.h | 42 ++++++++++++++++++++++++++++++++++++++++++ rpc/pbrpc.pro | 2 +- rpc/pbrpcchannel.cpp | 44 +++++++++++++++++++++++--------------------- rpc/pbrpcchannel.h | 4 ++++ rpc/pbrpccommon.h | 2 -- rpc/rpcserver.cpp | 37 ++++++++++++++++++++++++------------- rpc/rpcserver.h | 3 +++ 8 files changed, 98 insertions(+), 38 deletions(-) create mode 100644 rpc/pbqtio.h diff --git a/client/ostinato.pro b/client/ostinato.pro index 299ecc5..e61730e 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -5,7 +5,6 @@ win32:RC_FILE = ostinato.rc macx:ICON = icons/logo.icns QT += network script INCLUDEPATH += "../rpc/" "../common/" -LIBS += -lprotobuf win32 { CONFIG(debug, debug|release) { LIBS += -L"../common/debug" -lostproto @@ -25,6 +24,7 @@ win32 { LIBS += -L"../rpc" -lpbrpc POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a" } +LIBS += -lprotobuf RESOURCES += ostinato.qrc HEADERS += \ dumpview.h \ diff --git a/rpc/pbqtio.h b/rpc/pbqtio.h new file mode 100644 index 0000000..33d36a4 --- /dev/null +++ b/rpc/pbqtio.h @@ -0,0 +1,42 @@ +#ifndef _PBQTIO_H +#define _PBQTIO_H + +#include + +class PbQtInputStream : public google::protobuf::io::CopyingInputStream +{ +public: + PbQtInputStream(QIODevice *dev) + : dev_(dev) {}; + int Read(void *buffer, int size) { + _top: + if (dev_->bytesAvailable()) + return dev_->read(static_cast(buffer), size); + else + if (dev_->waitForReadyRead(-1)) + goto _top; + else + return -1; //return dev_->atEnd() ? 0 : -1; + } + +private: + QIODevice *dev_; +}; + +class PbQtOutputStream : public google::protobuf::io::CopyingOutputStream +{ +public: + PbQtOutputStream(QIODevice *dev) + : dev_(dev) {}; + bool Write(const void *buffer, int size) { + if (dev_->write(static_cast(buffer), size) == size) + return true; + else + return false; + } + +private: + QIODevice *dev_; +}; + +#endif diff --git a/rpc/pbrpc.pro b/rpc/pbrpc.pro index 27ec61b..f53fa81 100644 --- a/rpc/pbrpc.pro +++ b/rpc/pbrpc.pro @@ -3,5 +3,5 @@ CONFIG += qt staticlib QT += network DEFINES += HAVE_REMOTE LIBS += -lprotobuf -HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h +HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h pbqtio.h SOURCES += rpcserver.cpp pbrpcchannel.cpp diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp index 47f1611..7c7789e 100644 --- a/rpc/pbrpcchannel.cpp +++ b/rpc/pbrpcchannel.cpp @@ -18,6 +18,7 @@ along with this program. If not, see */ #include "pbrpcchannel.h" +#include "pbqtio.h" #include @@ -34,6 +35,13 @@ PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) mServerPort = port; mpSocket = new QTcpSocket(this); + inStream = new google::protobuf::io::CopyingInputStreamAdaptor( + new PbQtInputStream(mpSocket)); + inStream->SetOwnsCopyingStream(true); + outStream = new google::protobuf::io::CopyingOutputStreamAdaptor( + new PbQtOutputStream(mpSocket)); + outStream->SetOwnsCopyingStream(true); + // FIXME: Not quite sure why this ain't working! // QMetaObject::connectSlotsByName(this); @@ -53,6 +61,8 @@ PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) PbRpcChannel::~PbRpcChannel() { + delete inStream; + delete outStream; delete mpSocket; } @@ -84,7 +94,7 @@ void PbRpcChannel::CallMethod( ::google::protobuf::Message *response, ::google::protobuf::Closure* done) { - char msgBuf[MSGBUF_SIZE]; + char msgBuf[PB_HDR_SIZE]; char* const msg = &msgBuf[0]; int len; bool ret; @@ -128,9 +138,6 @@ void PbRpcChannel::CallMethod( this->response=response; isPending = true; - ret = req->SerializeToArray((void*)(msg+PB_HDR_SIZE), sizeof(msgBuf)-PB_HDR_SIZE); - Q_ASSERT(ret == true); - len = req->ByteSize(); *((quint16*)(msg+0)) = qToBigEndian(quint16(PB_MSG_TYPE_REQUEST)); // type *((quint16*)(msg+2)) = qToBigEndian(quint16(method->index())); // method id @@ -141,15 +148,18 @@ void PbRpcChannel::CallMethod( { qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, PB_HDR_SIZE + len, req->DebugString().c_str()); - BUFDUMP(msg, PB_HDR_SIZE + len); + BUFDUMP(msg, PB_HDR_SIZE); } - mpSocket->write(msg, PB_HDR_SIZE + len); + mpSocket->write(msg, PB_HDR_SIZE); + ret = req->SerializeToZeroCopyStream(outStream); + Q_ASSERT(ret == true); + outStream->Flush(); } void PbRpcChannel::on_mpSocket_readyRead() { - uchar msg[MSGBUF_SIZE]; + uchar msg[PB_HDR_SIZE]; uchar *p = (uchar*) &msg; int msgLen; static bool parsing = false; @@ -210,31 +220,20 @@ void PbRpcChannel::on_mpSocket_readyRead() if (!isPending) { qDebug("not waiting for response"); - goto _error_exit; + goto _error_exit2; } if (pendingMethodId != method) { qDebug("invalid method id %d (expected = %d)", method, pendingMethodId); - goto _error_exit; + goto _error_exit2; } break; } case PB_MSG_TYPE_RESPONSE: - // Wait till we have the entire message - if (mpSocket->bytesAvailable() < len) - { - qDebug("client: not enough data available for a complete msg"); - return; - } - - msgLen = mpSocket->read((char*)msg, sizeof(msg)); - - Q_ASSERT((unsigned) msgLen == len); - //qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); //BUFDUMP(msg, msgLen); @@ -251,7 +250,8 @@ void PbRpcChannel::on_mpSocket_readyRead() goto _error_exit; } - response->ParseFromArray((void*) msg, len); + if (len) + response->ParseFromBoundedZeroCopyStream(inStream, len); // Avoid printing stats if (method != 13) @@ -295,6 +295,8 @@ void PbRpcChannel::on_mpSocket_readyRead() return; _error_exit: + inStream->Skip(len); +_error_exit2: parsing = false; qDebug("client(%s) discarding received msg", __FUNCTION__); return; diff --git a/rpc/pbrpcchannel.h b/rpc/pbrpcchannel.h index 682c553..e3f9096 100644 --- a/rpc/pbrpcchannel.h +++ b/rpc/pbrpcchannel.h @@ -23,6 +23,7 @@ along with this program. If not, see #include #include +#include #include #include #include @@ -64,6 +65,9 @@ class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel quint16 mServerPort; QTcpSocket *mpSocket; + ::google::protobuf::io::CopyingInputStreamAdaptor *inStream; + ::google::protobuf::io::CopyingOutputStreamAdaptor *outStream; + public: PbRpcChannel(QHostAddress ip, quint16 port); ~PbRpcChannel(); diff --git a/rpc/pbrpccommon.h b/rpc/pbrpccommon.h index 0f4acf9..e1fbdf9 100644 --- a/rpc/pbrpccommon.h +++ b/rpc/pbrpccommon.h @@ -36,6 +36,4 @@ along with this program. If not, see #define PB_MSG_TYPE_RESPONSE 2 #define PB_MSG_TYPE_BINBLOB 3 -#define MSGBUF_SIZE 4096 - #endif diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp index d48de21..2d1bd63 100644 --- a/rpc/rpcserver.cpp +++ b/rpc/rpcserver.cpp @@ -19,6 +19,7 @@ along with this program. If not, see //#include "pbhelper.h" #include "rpcserver.h" +#include "pbqtio.h" #include @@ -29,6 +30,9 @@ RpcServer::RpcServer() service = NULL; + inStream = NULL; + outStream = NULL; + isPending = false; pendingMethodId = -1; // don't care as long as isPending is false } @@ -71,7 +75,7 @@ void RpcServer::done(PbRpcController *controller) { google::protobuf::Message *response = controller->response(); QIODevice *blob; - char msgBuf[MSGBUF_SIZE]; + char msgBuf[PB_HDR_SIZE]; char* const msg = &msgBuf[0]; int len; @@ -116,8 +120,6 @@ void RpcServer::done(PbRpcController *controller) goto _exit; } - response->SerializeToArray((void*)(msg+PB_HDR_SIZE), sizeof(msgBuf)-PB_HDR_SIZE); - len = response->ByteSize(); *((quint16*)(msg+0)) = qToBigEndian(quint16(PB_MSG_TYPE_RESPONSE)); // type @@ -132,7 +134,9 @@ void RpcServer::done(PbRpcController *controller) //BUFDUMP(msg, len + 8); } - clientSock->write(msg, PB_HDR_SIZE + len); + clientSock->write(msg, PB_HDR_SIZE); + response->SerializeToZeroCopyStream(outStream); + outStream->Flush(); _exit: delete controller; @@ -159,6 +163,12 @@ void RpcServer::when_newConnection() qDebug("accepting new connection from %s: %d", clientSock->peerAddress().toString().toAscii().constData(), clientSock->peerPort()); + inStream = new google::protobuf::io::CopyingInputStreamAdaptor( + new PbQtInputStream(clientSock)); + inStream->SetOwnsCopyingStream(true); + outStream = new google::protobuf::io::CopyingOutputStreamAdaptor( + new PbQtOutputStream(clientSock)); + outStream->SetOwnsCopyingStream(true); connect(clientSock, SIGNAL(readyRead()), this, SLOT(when_dataAvail())); @@ -177,6 +187,9 @@ void RpcServer::when_disconnected() clientSock->peerAddress().toString().toAscii().constData(), clientSock->peerPort()); + delete inStream; + delete outStream; + clientSock->deleteLater(); clientSock = NULL; } @@ -189,7 +202,7 @@ void RpcServer::when_error(QAbstractSocket::SocketError socketError) void RpcServer::when_dataAvail() { - uchar msg[MSGBUF_SIZE]; + uchar msg[PB_HDR_SIZE]; int msgLen; static bool parsing = false; static quint16 type, method; @@ -215,12 +228,6 @@ void RpcServer::when_dataAvail() parsing = true; } - if (clientSock->bytesAvailable() < len) - return; - - msgLen = clientSock->read((char*)msg, sizeof(msg)); - Q_ASSERT((unsigned) msgLen == len); - if (type != PB_MSG_TYPE_REQUEST) { qDebug("server(%s): unexpected msg type %d (expected %d)", __FUNCTION__, @@ -247,7 +254,9 @@ void RpcServer::when_dataAvail() req = service->GetRequestPrototype(methodDesc).New(); resp = service->GetResponsePrototype(methodDesc).New(); - req->ParseFromArray((void*)msg, len); + if (len) + req->ParseFromBoundedZeroCopyStream(inStream, len); + if (!req->IsInitialized()) { qWarning("Missing required fields in request"); @@ -256,7 +265,7 @@ void RpcServer::when_dataAvail() delete req; delete resp; - goto _error_exit; + goto _error_exit2; } //qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__, //resp->DebugString().c_str()); @@ -273,6 +282,8 @@ void RpcServer::when_dataAvail() return; _error_exit: + inStream->Skip(len); +_error_exit2: parsing = false; qDebug("server(%s): discarding msg from client", __FUNCTION__); return; diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h index 1e9c93e..76f179a 100644 --- a/rpc/rpcserver.h +++ b/rpc/rpcserver.h @@ -23,6 +23,7 @@ along with this program. If not, see #include #include #include +#include #include #include @@ -39,6 +40,8 @@ class RpcServer : public QObject QTcpSocket *clientSock; ::google::protobuf::Service *service; + ::google::protobuf::io::CopyingInputStreamAdaptor *inStream; + ::google::protobuf::io::CopyingOutputStreamAdaptor *outStream; bool isPending; int pendingMethodId; From 3aac690ed869e564f3be1106d2bf4e0152da22a1 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Mon, 25 Oct 2010 19:27:23 +0530 Subject: [PATCH 95/98] While appending streams, the streamId and ordinalId were getting overwritten. Port::newStreamAt() now takes an additional parameter - pointer to stream (default NULL) which is used when appending streams Fixes Issue 21 --- client/port.cpp | 8 +++++--- client/port.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/client/port.cpp b/client/port.cpp index 6b5e13e..289e44a 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -65,13 +65,16 @@ void Port::reorderStreamsByOrdinals() qSort(mStreams.begin(), mStreams.end(), StreamBase::StreamLessThan); } -bool Port::newStreamAt(int index) +bool Port::newStreamAt(int index, OstProto::Stream const *stream) { Stream *s = new Stream; if (index > mStreams.size()) return false; + if (stream) + s->protoDataCopyFrom(*stream); + s->setId(newStreamId()); mStreams.insert(index, s); updateStreamOrdinalsFromIndex(); @@ -235,8 +238,7 @@ bool Port::openStreams(QString fileName, bool append, QString &error) for (int i = 0; i < streams.stream_size(); i++) { - newStreamAt(mStreams.size()); - streamByIndex(mStreams.size()-1)->protoDataCopyFrom(streams.stream(i)); + newStreamAt(mStreams.size(), &streams.stream(i)); } emit streamListChanged(mPortGroupId, mPortId); diff --git a/client/port.h b/client/port.h index e4bb9c9..2fbb9a0 100644 --- a/client/port.h +++ b/client/port.h @@ -99,7 +99,7 @@ public: //! Used by StreamModel //@{ - bool newStreamAt(int index); + bool newStreamAt(int index, OstProto::Stream const *stream = NULL); bool deleteStreamAt(int index); //@} From fbde299478b1d704b0d1c5f1f3528b7d8d8af3d1 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 3 Nov 2010 19:39:36 +0530 Subject: [PATCH 96/98] Added HexDump Protocol --- client/ostinato.pro | 1 + client/streamconfigdialog.cpp | 1 + client/streamconfigdialog.ui | 154 +++++---- common/hexdump.cpp | 263 +++++++++++++++ common/hexdump.h | 89 +++++ common/hexdump.proto | 32 ++ common/hexdump.ui | 76 +++++ common/ostproto.pro | 5 + common/protocol.proto | 1 + common/protocolmanager.cpp | 3 + extra/qhexedit2/qhexedit2.pro | 8 + extra/qhexedit2/src/license.txt | 502 +++++++++++++++++++++++++++++ extra/qhexedit2/src/qhexedit.cpp | 106 ++++++ extra/qhexedit2/src/qhexedit.h | 145 +++++++++ extra/qhexedit2/src/qhexedit_p.cpp | 414 ++++++++++++++++++++++++ extra/qhexedit2/src/qhexedit_p.h | 82 +++++ server/drone.pro | 1 + 17 files changed, 1803 insertions(+), 80 deletions(-) create mode 100644 common/hexdump.cpp create mode 100644 common/hexdump.h create mode 100644 common/hexdump.proto create mode 100644 common/hexdump.ui create mode 100644 extra/qhexedit2/qhexedit2.pro create mode 100644 extra/qhexedit2/src/license.txt create mode 100644 extra/qhexedit2/src/qhexedit.cpp create mode 100644 extra/qhexedit2/src/qhexedit.h create mode 100644 extra/qhexedit2/src/qhexedit_p.cpp create mode 100644 extra/qhexedit2/src/qhexedit_p.h diff --git a/client/ostinato.pro b/client/ostinato.pro index e61730e..fa69080 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -25,6 +25,7 @@ win32 { POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a" } LIBS += -lprotobuf +LIBS += -L"../extra/qhexedit2/$(OBJECTS_DIR)/" -lqhexedit2 RESOURCES += ostinato.qrc HEADERS += \ dumpview.h \ diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 993cd1c..cc47dd7 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -243,6 +243,7 @@ void StreamConfigDialog::setupUiExtra() #else bgProto[ProtoPayload]->addButton(rbPayloadNone, ButtonIdNone); bgProto[ProtoPayload]->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); + bgProto[ProtoPayload]->addButton(rbPayloadHexDump, OstProto::Protocol::kHexDumpFieldNumber); bgProto[ProtoPayload]->addButton(rbPayloadOther, ButtonIdOther); #endif /* diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 43c56b6..1f0a838 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,7 +8,7 @@ 0 0 - 626 + 634 507 @@ -173,7 +173,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff 0 0 - 584 + 592 269 @@ -181,7 +181,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff Simple - + L1 @@ -220,7 +220,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + true @@ -403,17 +403,17 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - + + true - Payload + L5 - + None @@ -423,17 +423,17 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - - Pattern - - + + false + + Text + - + false @@ -445,7 +445,49 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + + + + true + + + VLAN + + + false + + + false + + + + + + Untagged + + + true + + + + + + + Tagged + + + + + + + Stacked + + + + + + + true @@ -517,59 +559,17 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - + + true - VLAN - - - false - - - false + Payload - - - Untagged - - - true - - - - - - - Tagged - - - - - - - Stacked - - - - - - - - - - true - - - L5 - - - - + None @@ -579,17 +579,24 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - - false - + - Text + Pattern + + + false - + + + Hex Dump + + + + + false @@ -601,19 +608,6 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/common/hexdump.cpp b/common/hexdump.cpp new file mode 100644 index 0000000..f579430 --- /dev/null +++ b/common/hexdump.cpp @@ -0,0 +1,263 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#include "hexdump.h" +#include "streambase.h" + +#include + +HexDumpConfigForm::HexDumpConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + hexEdit->setFont(QFont("Courier")); + hexEdit->setOverwriteMode(false); +} + +void HexDumpConfigForm::on_hexEdit_overwriteModeChanged(bool isOverwriteMode) +{ + if (isOverwriteMode) + mode->setText(tr("Ovr")); + else + mode->setText(tr("Ins")); +} + +HexDumpProtocol::HexDumpProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) +{ + /* The configWidget is created lazily */ + configForm = NULL; +} + +HexDumpProtocol::~HexDumpProtocol() +{ + delete configForm; +} + +AbstractProtocol* HexDumpProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) +{ + return new HexDumpProtocol(stream, parent); +} + +quint32 HexDumpProtocol::protocolNumber() const +{ + return OstProto::Protocol::kHexDumpFieldNumber; +} + +void HexDumpProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const +{ + protocol.MutableExtension(OstProto::hexDump)->CopyFrom(data); + protocol.mutable_protocol_id()->set_id(protocolNumber()); +} + +void HexDumpProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) +{ + if (protocol.protocol_id().id() == protocolNumber() && + protocol.HasExtension(OstProto::hexDump)) + data.MergeFrom(protocol.GetExtension(OstProto::hexDump)); +} + +QString HexDumpProtocol::name() const +{ + return QString("HexDump"); +} + +QString HexDumpProtocol::shortName() const +{ + return QString("HexDump"); +} + +int HexDumpProtocol::fieldCount() const +{ + return hexDump_fieldCount; +} + +AbstractProtocol::FieldFlags HexDumpProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case hexDump_content: + flags |= FrameField; + break; + + case hexDump_pad_until_end: + flags &= ~FrameField; + flags |= MetaField; + break; + + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return flags; +} + +QVariant HexDumpProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case hexDump_content: + { + QByteArray ba; + QByteArray pad; + + switch(attrib) + { + case FieldValue: + case FieldTextValue: + case FieldFrameValue: + ba.append(QString().fromStdString(data.content())); + if (data.pad_until_end()) + { + pad = QByteArray( + protocolFrameSize(streamIndex) - ba.size(), '\0'); + } + break; + + default: + break; + } + + switch(attrib) + { + case FieldName: + return QString("Content"); + case FieldValue: + return ba; + case FieldTextValue: + return ba.append(pad).toHex(); + case FieldFrameValue: + return ba.append(pad); + default: + break; + } + break; + + } + + // Meta fields + case hexDump_pad_until_end: + { + switch(attrib) + { + case FieldValue: + return data.pad_until_end(); + default: + break; + } + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool HexDumpProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + bool isOk = false; + + if (attrib != FieldValue) + goto _exit; + + switch (index) + { + case hexDump_content: + { + QByteArray ba = value.toByteArray(); + data.set_content(ba.constData(), ba.size()); + isOk = true; + break; + } + case hexDump_pad_until_end: + { + bool pad = value.toBool(); + data.set_pad_until_end(pad); + isOk = true; + break; + } + default: + qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, + index); + break; + } + +_exit: + return isOk; +} + +int HexDumpProtocol::protocolFrameSize(int streamIndex) const +{ + int len = data.content().size(); + + if (data.pad_until_end()) + { + int pad = mpStream->frameLen(streamIndex) + - (protocolFrameOffset(streamIndex) + len + kFcsSize); + if (pad < 0) + pad = 0; + len += pad; + } + + return len; +} + +QWidget* HexDumpProtocol::configWidget() +{ + /* Lazy creation of the configWidget */ + if (configForm == NULL) + { + configForm = new HexDumpConfigForm; + loadConfigWidget(); + } + + return configForm; +} + +void HexDumpProtocol::loadConfigWidget() +{ + configWidget(); + + configForm->hexEdit->setData( + fieldData(hexDump_content, FieldValue).toByteArray()); + configForm->padUntilEnd->setChecked( + fieldData(hexDump_pad_until_end, FieldValue).toBool()); +} + +void HexDumpProtocol::storeConfigWidget() +{ + configWidget(); + + setFieldData(hexDump_content, configForm->hexEdit->data()); + setFieldData(hexDump_pad_until_end, configForm->padUntilEnd->isChecked()); +} + diff --git a/common/hexdump.h b/common/hexdump.h new file mode 100644 index 0000000..f5b6932 --- /dev/null +++ b/common/hexdump.h @@ -0,0 +1,89 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _HEXDUMP_H +#define _HEXDUMP_H + +#include "hexdump.pb.h" +#include "ui_hexdump.h" + +#include "abstractprotocol.h" + +/* +HexDump Protocol Frame Format - + +---------+---------+ + | User | Zero | + | HexDump | Padding | + +---------+---------+ +*/ + +class HexDumpConfigForm : public QWidget, public Ui::HexDump +{ + Q_OBJECT +public: + HexDumpConfigForm(QWidget *parent = 0); +private slots: + void on_hexEdit_overwriteModeChanged(bool isOverwriteMode); +}; + +class HexDumpProtocol : public AbstractProtocol +{ +public: + HexDumpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); + virtual ~HexDumpProtocol(); + + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); + virtual quint32 protocolNumber() const; + + virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; + virtual void protoDataCopyFrom(const OstProto::Protocol &protocol); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual int protocolFrameSize(int streamIndex = 0) const; + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); + +private: + OstProto::HexDump data; + HexDumpConfigForm *configForm; + enum hexDumpfield + { + // Frame Fields + hexDump_content = 0, + + // Meta Fields + hexDump_pad_until_end, + + hexDump_fieldCount + }; +}; +#endif diff --git a/common/hexdump.proto b/common/hexdump.proto new file mode 100644 index 0000000..6cdc3d5 --- /dev/null +++ b/common/hexdump.proto @@ -0,0 +1,32 @@ +/* +Copyright (C) 2010 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +import "protocol.proto"; + +package OstProto; + +// HexDump Protocol +message HexDump { + optional bytes content = 1; + optional bool pad_until_end = 2 [default = true]; +} + +extend Protocol { + optional HexDump hexDump = 104; +} diff --git a/common/hexdump.ui b/common/hexdump.ui new file mode 100644 index 0000000..61f187a --- /dev/null +++ b/common/hexdump.ui @@ -0,0 +1,76 @@ + + HexDump + + + + 0 + 0 + 511 + 190 + + + + Form + + + + + + + + + Pad until end of packet + + + + + + + Qt::Horizontal + + + + 281 + 20 + + + + + + + + + 50 + 0 + + + + QFrame::Panel + + + QFrame::Sunken + + + 1 + + + + + + Qt::AlignCenter + + + + + + + + QHexEdit + QWidget +
qhexedit.h
+ 1 +
+
+ + +
diff --git a/common/ostproto.pro b/common/ostproto.pro index 68f1cc6..28d5dc7 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -1,6 +1,7 @@ TEMPLATE = lib CONFIG += qt staticlib QT += network script +INCLUDEPATH += "../extra/qhexedit2/src" LIBS += \ -lprotobuf FORMS += \ @@ -19,6 +20,7 @@ FORMS += \ udp.ui \ textproto.ui \ userscript.ui \ + hexdump.ui \ sample.ui PROTOS += \ protocol.proto \ @@ -46,6 +48,7 @@ PROTOS += \ udp.proto \ textproto.proto \ userscript.proto \ + hexdump.proto \ sample.proto HEADERS += \ abstractprotocol.h \ @@ -78,6 +81,7 @@ HEADERS += \ udp.h \ textproto.h \ userscript.h \ + hexdump.h \ sample.h SOURCES += \ abstractprotocol.cpp \ @@ -103,6 +107,7 @@ SOURCES += \ udp.cpp \ textproto.cpp \ userscript.cpp \ + hexdump.cpp \ sample.cpp QMAKE_DISTCLEAN += object_script.* diff --git a/common/protocol.proto b/common/protocol.proto index 3510e2b..25b0fbb 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -86,6 +86,7 @@ message Protocol { kPayloadFieldNumber = 101; kSampleFieldNumber = 102; kUserScriptFieldNumber = 103; + kHexDumpFieldNumber = 104; kEth2FieldNumber = 200; kDot3FieldNumber = 201; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 0910e1a..b256135 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -43,6 +43,7 @@ along with this program. If not, see #include "udp.h" #include "textproto.h" #include "userscript.h" +#include "hexdump.h" #include "sample.h" ProtocolManager *OstProtocolManager; @@ -99,6 +100,8 @@ ProtocolManager::ProtocolManager() registerProtocol(OstProto::Protocol::kTextProtocolFieldNumber, (void*) TextProtocol::createInstance); + registerProtocol(OstProto::Protocol::kHexDumpFieldNumber, + (void*) HexDumpProtocol::createInstance); registerProtocol(OstProto::Protocol::kPayloadFieldNumber, (void*) PayloadProtocol::createInstance); diff --git a/extra/qhexedit2/qhexedit2.pro b/extra/qhexedit2/qhexedit2.pro new file mode 100644 index 0000000..c7b9989 --- /dev/null +++ b/extra/qhexedit2/qhexedit2.pro @@ -0,0 +1,8 @@ +TEMPLATE = lib +CONFIG += qt staticlib warn_on + +HEADERS = src/qhexedit.h \ + src/qhexedit_p.h + +SOURCES = src/qhexedit.cpp \ + src/qhexedit_p.cpp diff --git a/extra/qhexedit2/src/license.txt b/extra/qhexedit2/src/license.txt new file mode 100644 index 0000000..f166cc5 --- /dev/null +++ b/extra/qhexedit2/src/license.txt @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! \ No newline at end of file diff --git a/extra/qhexedit2/src/qhexedit.cpp b/extra/qhexedit2/src/qhexedit.cpp new file mode 100644 index 0000000..a295110 --- /dev/null +++ b/extra/qhexedit2/src/qhexedit.cpp @@ -0,0 +1,106 @@ +#include + +#include "qhexedit.h" + + +QHexEdit::QHexEdit(QWidget *parent) : QScrollArea(parent) +{ + qHexEdit_p = new QHexEditPrivate(this); + setWidget(qHexEdit_p); + setWidgetResizable(true); + + connect(qHexEdit_p, SIGNAL(dataChanged()), this, SIGNAL(dataChanged())); + connect(qHexEdit_p, SIGNAL(currentAddress(int)), this, SIGNAL(currentAddress(int))); + connect(qHexEdit_p, SIGNAL(overwriteModeChanged(bool)), this, SIGNAL(overwriteModeChanged(bool))); +} + +void QHexEdit::insert(int i, const QByteArray & ba) +{ + qHexEdit_p->insert(i, ba); +} + +void QHexEdit::insert(int i, char ch) +{ + qHexEdit_p->insert(i, ch); +} + +void QHexEdit::remove(int pos, int len) +{ + qHexEdit_p->remove(pos, len); +} + +void QHexEdit::setAddressArea(bool addressArea) +{ + qHexEdit_p->setAddressArea(addressArea); +} + +void QHexEdit::setAddressWidth(int addressWidth) +{ + qHexEdit_p->setAddressWidth(addressWidth); +} + +void QHexEdit::setAsciiArea(bool asciiArea) +{ + qHexEdit_p->setAsciiArea(asciiArea); +} + +void QHexEdit::setHighlighting(bool mode) +{ + qHexEdit_p->setHighlighting(mode); +} + +void QHexEdit::setAddressOffset(int offset) +{ + qHexEdit_p->setAddressOffset(offset); +} + +int QHexEdit::addressOffset() +{ + return addressOffset(); +} + +void QHexEdit::setData(const QByteArray &data) +{ + qHexEdit_p->setData(data); +} + +QByteArray QHexEdit::data() +{ + return qHexEdit_p->data(); +} + +void QHexEdit::setAddressAreaColor(const QColor &color) +{ + qHexEdit_p->setAddressAreaColor(color); +} + +QColor QHexEdit::addressAreaColor() +{ + return qHexEdit_p->addressAreaColor(); +} + +void QHexEdit::setHighlightingColor(const QColor &color) +{ + qHexEdit_p->setHighlightingColor(color); +} + +QColor QHexEdit::highlightingColor() +{ + return qHexEdit_p->highlightingColor(); +} + +void QHexEdit::setOverwriteMode(bool overwriteMode) +{ + qHexEdit_p->setOverwriteMode(overwriteMode); +} + +bool QHexEdit::overwriteMode() +{ + return qHexEdit_p->overwriteMode(); +} + +void QHexEdit::setFont(const QFont &font) +{ + qHexEdit_p->setFont(font); +} + diff --git a/extra/qhexedit2/src/qhexedit.h b/extra/qhexedit2/src/qhexedit.h new file mode 100644 index 0000000..2b94581 --- /dev/null +++ b/extra/qhexedit2/src/qhexedit.h @@ -0,0 +1,145 @@ +#ifndef QHEXEDIT_H +#define QHEXEDIT_H + +#include +#include "qhexedit_p.h" + +/** \mainpage +QHexEdit is a binary editor widget for Qt. + +\version Version 0.4.3 +\image html hexedit.png +*/ + + +/*! QHexEdit is a hex editor widget written in C++ for the Qt (Qt4) framework. +It is a simple editor for binary data, just like QPlainTextEdit is for text data. +There are sip configuration files included, so it is easy to create bindings +for PyQt and you can use this widget also in python. + +QHexEdit takes the data of a QByteArray (setData()) and shows it. You can use the +mouse or the keyboard to navigate inside the widget. If you hit the keys (0..9, a..f) +you will change the data. Changed data is highlighted and can be accessed via data(). + +Normaly QHexEdit works in the overwrite Mode. You can set overwriteMode(false) and +insert data. In this case the size of data() increases. It is also possible to delete +bytes under the cursor, here the size of data decreases. + +There are some limitations: The size of data has in general to be below 10 megabytes, +otherwise the scroll sliders ard not shown and you can't scroll any more. Copy and +paste functionality is perhaps a subject of a later release. +*/ + class QHexEdit : public QScrollArea +{ + Q_OBJECT + /*! Property data holds the content of QHexEdit. Call setData() to set the + content of QHexEdit, data() returns the actual content. + */ + Q_PROPERTY(QByteArray data READ data WRITE setData) + + /*! Property addressOffset is added to the Numbers of the Address Area. + A offset in the address area (left side) is sometimes usefull, whe you show + only a segment of a complete memory picture. With setAddressOffset() you set + this property - with addressOffset() you get the actual value. + */ + Q_PROPERTY(int addressOffset READ addressOffset WRITE setAddressOffset) + + /*! Property address area color sets (setAddressAreaColor()) the backgorund + color of address areas. You can also read the color (addressaAreaColor()). + */ + Q_PROPERTY(QColor addressAreaColor READ addressAreaColor WRITE setAddressAreaColor) + + /*! Property highlighting color sets (setHighlightingColor()) the backgorund + color of highlighted text areas. You can also read the color + (highlightingColor()). + */ + Q_PROPERTY(QColor highlightingColor READ highlightingColor WRITE setHighlightingColor) + + /*! Porperty overwrite mode sets (setOverwriteMode()) or gets (overwriteMode()) the mode + in which the editor works. In overwritem mode the user will overwrite existing data. + */ + Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode) + +public: + /*! Creates an instance of QHexEdit. + \param parent Parent widget of QHexEdit. + */ + QHexEdit(QWidget *parent = 0); + + /*! Inserts a byte array. + \param i Index position, where to insert + \param ba byte array, which is to insert + */ + void insert(int i, const QByteArray & ba); + + /*! Inserts a char. + \param i Index position, where to insert + \param ch Char, which is to insert + */ + void insert(int i, char ch); + + /*! Removes len bytes from the content. + \param pos Index position, where to remove + \param len Amount of bytes to remove + */ + void remove(int pos, int len=1); + + /*! Set the font of the widget. Please use fixed width fonts like Mono or Courier.*/ + void setFont(const QFont &); + + /*! \cond docNever */ + void setAddressOffset(int offset); + int addressOffset(); + void setData(QByteArray const &data); + QByteArray data(); + void setAddressAreaColor(QColor const &color); + QColor addressAreaColor(); + void setHighlightingColor(QColor const &color); + QColor highlightingColor(); + void setOverwriteMode(bool); + bool overwriteMode(); + /*! \endcond docNever */ + +public slots: + + /*! Set the minimum width of the address area. + \param addressWidth Width in characters. + */ + void setAddressWidth(int addressWidth); + + /*! Switch the address area on or off. + \param addressArea true (show it), false (hide it). + */ + void setAddressArea(bool addressArea); + + /*! Switch the ascii area on or off. + \param asciiArea true (show it), false (hide it). + */ + void setAsciiArea(bool asciiArea); + + /*! Switch the highlighting feature on or of. + \param mode true (show it), false (hide it). + */ + void setHighlighting(bool mode); + +signals: + + /*! Contains the address, where the cursor is located. */ + void currentAddress(int address); + + /*! The signal is emited every time, the data is changed. */ + void dataChanged(); + + /*! The signal is emited every time, the overwrite mode is changed. */ + void overwriteModeChanged(bool state); + +private: + /*! \cond docNever */ + QHexEditPrivate *qHexEdit_p; + QHBoxLayout *layout; + QScrollArea *scrollArea; + /*! \endcond docNever */ +}; + +#endif + diff --git a/extra/qhexedit2/src/qhexedit_p.cpp b/extra/qhexedit2/src/qhexedit_p.cpp new file mode 100644 index 0000000..30f0660 --- /dev/null +++ b/extra/qhexedit2/src/qhexedit_p.cpp @@ -0,0 +1,414 @@ +#include + +#include "qhexedit_p.h" + +const int HEXCHARS_IN_LINE = 47; +const int GAP_ADR_HEX = 10; +const int GAP_HEX_ASCII = 16; +const int BYTES_PER_LINE = 16; + +QHexEditPrivate::QHexEditPrivate(QScrollArea *parent) : QWidget(parent) +{ + _scrollArea = parent; + setAddressWidth(4); + setAddressOffset(0); + setAddressArea(true); + setAsciiArea(true); + setHighlighting(true); + setOverwriteMode(true); + setAddressAreaColor(QColor(Qt::lightGray).lighter(110)); + setHighlightingColor(QColor(Qt::yellow).lighter(160)); + + setFont(QFont("Mono", 10)); + connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor())); + + _cursorTimer.setInterval(500); + _cursorTimer.start(); + + setFocusPolicy(Qt::StrongFocus); +} + +void QHexEditPrivate::setAddressOffset(int offset) +{ + _addressOffset = offset; + adjust(); +} + +int QHexEditPrivate::addressOffset() +{ + return _addressOffset; +} + +void QHexEditPrivate::setData(const QByteArray &data) +{ + _data = data; + _originalData = data; + adjust(); + setCursorPos(0); + setFocus(); +} + +QByteArray QHexEditPrivate::data() +{ + return _data; +} + +void QHexEditPrivate::setAddressAreaColor(const QColor &color) +{ + _addressAreaColor = color; + update(); +} + +QColor QHexEditPrivate::addressAreaColor() +{ + return _addressAreaColor; +} + +void QHexEditPrivate::setHighlightingColor(const QColor &color) +{ + _highlightingColor = color; + update(); +} + +QColor QHexEditPrivate::highlightingColor() +{ + return _highlightingColor; +} + +void QHexEditPrivate::setOverwriteMode(bool overwriteMode) +{ + if (overwriteMode != _overwriteMode) + { + emit overwriteModeChanged(overwriteMode); + _overwriteMode = overwriteMode; + adjust(); + } +} + +bool QHexEditPrivate::overwriteMode() +{ + return _overwriteMode; +} + +void QHexEditPrivate::insert(int i, const QByteArray & ba) +{ + _data.insert(i, ba); + _originalData.insert(i, ba); +} + +void QHexEditPrivate::insert(int i, char ch) +{ + _data.insert(i, ch); + _originalData.insert(i, ch); +} + +void QHexEditPrivate::remove(int index, int len) +{ + _data.remove(index, len); + _originalData.remove(index, len); +} + +void QHexEditPrivate::setAddressArea(bool addressArea) +{ + _addressArea = addressArea; + adjust(); + setCursorPos(_cursorPosition); +} + +void QHexEditPrivate::setAddressWidth(int addressWidth) +{ + if ((addressWidth >= 0) and (addressWidth<=6)) + { + _addressNumbers = addressWidth; + adjust(); + setCursorPos(_cursorPosition); + } +} + +void QHexEditPrivate::setAsciiArea(bool asciiArea) +{ + _asciiArea = asciiArea; + adjust(); +} + +void QHexEditPrivate::setFont(const QFont &font) +{ + QWidget::setFont(font); + adjust(); +} + +void QHexEditPrivate::setHighlighting(bool mode) +{ + _highlighting = mode; + update(); +} + +void QHexEditPrivate::keyPressEvent(QKeyEvent *event) +{ + bool down = false; + int charX = (_cursorX - _xPosHex) / _charWidth; + int posX = (charX / 3) * 2 + (charX % 3); + int posBa = (_cursorY / _charHeight) * BYTES_PER_LINE + posX / 2; + + int key = int(event->text()[0].toAscii()); + if ((key>='0' && key<='9') || (key>='a' && key <= 'f')) + { + // calc address + + + // insert char + if (_overwriteMode == false) + if ((charX % 3) == 0) + { + insert(posBa, char(0)); + adjust(); + } + QByteArray hexValue = _data.mid(posBa, 1).toHex(); + if ((charX % 3) == 0) + hexValue[0] = key; + else + hexValue[1] = key; + _data.replace(posBa, 1, QByteArray().fromHex(hexValue)); + emit dataChanged(); + + setCursorPos(_cursorPosition + 1); + down = true; + } + + // delete char + if (event->matches(QKeySequence::Delete)) + remove(posBa); + if (event->key() == Qt::Key_Backspace) + { + remove(posBa - 1); + setCursorPos(_cursorPosition - 2); + } + + // handle other function keys + if (event->key() == Qt::Key_Insert) + setOverwriteMode(!_overwriteMode); + + if (event->matches(QKeySequence::MoveToNextChar)) + { + setCursorPos(_cursorPosition + 1); + down = true; + } + if (event->matches(QKeySequence::MoveToPreviousChar)) + setCursorPos(_cursorPosition - 1); + if (event->matches(QKeySequence::MoveToStartOfLine)) + setCursorPos(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE))); + if (event->matches(QKeySequence::MoveToEndOfLine)) + setCursorPos(_cursorPosition | (2 * BYTES_PER_LINE -1)); + if (event->matches(QKeySequence::MoveToPreviousLine)) + setCursorPos(_cursorPosition - (2 * BYTES_PER_LINE)); + if (event->matches(QKeySequence::MoveToPreviousPage)) + setCursorPos(_cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); + if (event->matches(QKeySequence::MoveToStartOfDocument)) + setCursorPos(0); + if (event->matches(QKeySequence::MoveToNextLine)) + { + setCursorPos(_cursorPosition + (2 * BYTES_PER_LINE)); + down = true; + } + if (event->matches(QKeySequence::MoveToEndOfDocument)) + { + setCursorPos(_data.size() * 2); + down = true; + } + if (event->matches(QKeySequence::MoveToNextPage)) + { + setCursorPos(_cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); + down = true; + } + + // when we move downwards, we have to go a little further + if (down) + _scrollArea->ensureVisible(_cursorX, _cursorY, 3, 3 + _charHeight); + else + _scrollArea->ensureVisible(_cursorX, _cursorY, 3, 3); + update(); +} + +void QHexEditPrivate::mousePressEvent(QMouseEvent * event) +{ + setCursorPos(event->pos()); +} + +void QHexEditPrivate::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + // draw some patterns if needed + painter.fillRect(event->rect(), this->palette().color(QPalette::Base)); + if (_addressArea) + painter.fillRect(QRect(_xPosAdr, event->rect().top(), _xPosHex - GAP_ADR_HEX + 2, height()), _addressAreaColor); + if (_asciiArea) + { + int linePos = _xPosAscii - (GAP_HEX_ASCII / 2); + painter.setPen(Qt::gray); + painter.drawLine(linePos, event->rect().top(), linePos, height()); + } + + painter.setPen(this->palette().color(QPalette::WindowText)); + + // calc position + int firstLineIdx = ((event->rect().top()/ _charHeight) - _charHeight) * BYTES_PER_LINE; + if (firstLineIdx < 0) + firstLineIdx = 0; + int lastLineIdx = ((event->rect().bottom() / _charHeight) + _charHeight) * BYTES_PER_LINE; + if (lastLineIdx > _data.size()) + lastLineIdx = _data.size(); + int yPosStart = ((firstLineIdx) / BYTES_PER_LINE) * _charHeight + _charHeight; + + // paint address area + if (_addressArea) + { + for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) + { + QString address = QString("%1") + .arg(lineIdx + _addressOffset, _realAddressNumbers, 16, QChar('0')); + painter.drawText(_xPosAdr, yPos, address); + } + } + + // paint hex area + QByteArray hexBa(_data.mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex()); + QBrush highLighted = QBrush(_highlightingColor); + painter.setBackground(highLighted); + painter.setBackgroundMode(Qt::TransparentMode); + for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) + { + QByteArray hex; + int xPos = _xPosHex; + for (int colIdx = 0; ((lineIdx + colIdx) < _data.size() and (colIdx < BYTES_PER_LINE)); colIdx++) + { + // hilight diff bytes + if (_highlighting) + { + int posBa = lineIdx + colIdx; + if (posBa >= _originalData.size()) + painter.setBackgroundMode(Qt::TransparentMode); + else + if (_data[posBa] == _originalData[posBa]) + painter.setBackgroundMode(Qt::TransparentMode); + else + painter.setBackgroundMode(Qt::OpaqueMode); + } + + // render hex value + if (colIdx == 0) + { + hex = hexBa.mid((lineIdx - firstLineIdx) * 2, 2); + painter.drawText(xPos, yPos, hex); + xPos += 2 * _charWidth; + } else { + hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).prepend(" "); + painter.drawText(xPos, yPos, hex); + xPos += 3 * _charWidth; + } + } + } + painter.setBackgroundMode(Qt::TransparentMode); + + // paint ascii area + if (_asciiArea) + { + for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) + { + QByteArray ascii = _data.mid(lineIdx, BYTES_PER_LINE); + for (int idx=0; idx < ascii.size(); idx++) + if (((char)ascii[idx] < 0x20) or ((char)ascii[idx] > 0x7e)) + ascii[idx] = '.'; + painter.drawText(_xPosAscii, yPos, ascii); + } + } + + // paint cursor + if ((_data.size() > 0) and _blink) + painter.fillRect(_cursorX, _cursorY, _cursorWidth, _cursorHeight, this->palette().color(QPalette::WindowText)); +} + +void QHexEditPrivate::setCursorPos(int position) +{ + // delete cursor + _blink = false; + update(); + + // cursor in range? + if (_overwriteMode) + { + if (position > (_data.size() * 2 - 1)) + position = _data.size() * 2 - 1; + } else { + if (position > (_data.size() * 2)) + position = _data.size() * 2; + } + + if (position < 0) + position = 0; + + // calc position + _cursorPosition = position; + _cursorY = (position / (2 * BYTES_PER_LINE)) * _charHeight + 4; + int x = (position % (2 * BYTES_PER_LINE)); + _cursorX = (((x / 2) * 3) + (x % 2)) * _charWidth + _xPosHex; + + // immiadately draw cursor + _blink = true; + update(); + emit currentAddress(_cursorPosition/2); +} + +void QHexEditPrivate::setCursorPos(QPoint pos) +{ + // find char under cursor + if ((pos.x() >= _xPosHex) and (pos.x() < (_xPosHex + HEXCHARS_IN_LINE * _charWidth))) + { + int x = (pos.x() - _xPosHex) / _charWidth; + if ((x % 3) == 0) + x = (x / 3) * 2; + else + x = ((x / 3) * 2) + 1; + int y = (pos.y() / _charHeight) * 2 * BYTES_PER_LINE; + setCursorPos(x + y); + } +} + +void QHexEditPrivate::updateCursor() +{ + if (_blink) + _blink = false; + else + _blink = true; + update(_cursorX, _cursorY, _charWidth, _charHeight); +} + +void QHexEditPrivate::adjust() +{ + _charWidth = fontMetrics().width(QLatin1Char('9')); + _charHeight = fontMetrics().height(); + + // is addressNumbers wide enought? + QString test = QString("%1") + .arg(_data.size() + _addressOffset, _addressNumbers, 16, QChar('0')); + _realAddressNumbers = test.size(); + + _xPosAdr = 0; + if (_addressArea) + _xPosHex = _realAddressNumbers *_charWidth + GAP_ADR_HEX; + else + _xPosHex = 0; + _xPosAscii = _xPosHex + HEXCHARS_IN_LINE * _charWidth + GAP_HEX_ASCII; + + if (_overwriteMode) + _cursorWidth = _charWidth; + else + _cursorWidth = 2; + _cursorHeight = _charHeight - 3; + + // tell QAbstractScollbar, how big we are + setMinimumHeight(((_data.size()/16 + 1) * _charHeight) + 3); + setMinimumWidth(_xPosAscii + (BYTES_PER_LINE * _charWidth)); + + update(); +} diff --git a/extra/qhexedit2/src/qhexedit_p.h b/extra/qhexedit2/src/qhexedit_p.h new file mode 100644 index 0000000..c422c58 --- /dev/null +++ b/extra/qhexedit2/src/qhexedit_p.h @@ -0,0 +1,82 @@ +#ifndef QHEXEDIT_P_H +#define QHEXEDIT_P_H + +/** \cond docNever */ + + +#include + +class QHexEditPrivate : public QWidget +{ +Q_OBJECT + +public: + QHexEditPrivate(QScrollArea *parent); + + void setAddressOffset(int offset); + int addressOffset(); + + void setData(QByteArray const &data); + QByteArray data(); + + void setAddressAreaColor(QColor const &color); + QColor addressAreaColor(); + + void setHighlightingColor(QColor const &color); + QColor highlightingColor(); + + void setOverwriteMode(bool overwriteMode); + bool overwriteMode(); + + void insert(int i, const QByteArray & ba); + void insert(int i, char ch); + void remove(int index, int len=1); + + void setAddressArea(bool addressArea); + void setAddressWidth(int addressWidth); + void setAsciiArea(bool asciiArea); + void setHighlighting(bool mode); + virtual void setFont(const QFont &font); + +signals: + void currentAddress(int address); + void dataChanged(); + void overwriteModeChanged(bool state); + +protected: + void keyPressEvent(QKeyEvent * event); + void mousePressEvent(QMouseEvent * event); + void paintEvent(QPaintEvent *event); + void setCursorPos(QPoint pos); + void setCursorPos(int position); + +private slots: + void updateCursor(); + +private: + void adjust(); + + QColor _addressAreaColor; + QByteArray _data; + QByteArray _originalData; + QColor _highlightingColor; + QScrollArea *_scrollArea; + QTimer _cursorTimer; + + bool _blink; + bool _addressArea; + bool _asciiArea; + bool _highlighting; + bool _overwriteMode; + + int _addressNumbers, _realAddressNumbers; + int _addressOffset; + int _charWidth, _charHeight; + int _cursorX, _cursorY, _cursorWidth, _cursorHeight, _cursorPosition; + int _xPosAdr, _xPosHex, _xPosAscii; +}; + +/** \endcond docNever */ + +#endif + diff --git a/server/drone.pro b/server/drone.pro index b2b25d1..160973b 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -25,6 +25,7 @@ win32 { POST_TARGETDEPS += "../common/libostproto.a" "../rpc/libpbrpc.a" } LIBS += -lprotobuf +LIBS += -L"../extra/qhexedit2/$(OBJECTS_DIR)/" -lqhexedit2 RESOURCES += drone.qrc HEADERS += drone.h FORMS += drone.ui From a6c1166a788be90c253ac5a7630fdf6c906a05eb Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 3 Nov 2010 20:21:57 +0530 Subject: [PATCH 97/98] Added missing qmake project file for extra libraries --- extra/extra.pro | 3 +++ ost.pro | 1 + 2 files changed, 4 insertions(+) create mode 100644 extra/extra.pro diff --git a/extra/extra.pro b/extra/extra.pro new file mode 100644 index 0000000..48aa842 --- /dev/null +++ b/extra/extra.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qhexedit2 diff --git a/ost.pro b/ost.pro index bfe4e1a..0f9d987 100644 --- a/ost.pro +++ b/ost.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS = \ + extra \ rpc/pbrpc.pro \ common/ostproto.pro \ server/drone.pro \ From 599e5919072a2289c470d59d61d7e88513430457 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Thu, 4 Nov 2010 23:05:26 +0530 Subject: [PATCH 98/98] TextProtocol now allows specifying the end-of-line symbol Fixes Issue 18 --- common/fileformat.h | 2 +- common/textproto.cpp | 36 +++++++++++++++++++++++++++++++++++- common/textproto.h | 4 +++- common/textproto.proto | 7 +++++++ common/textproto.ui | 35 ++++++++++++++++++++++++++++++++--- 5 files changed, 78 insertions(+), 6 deletions(-) diff --git a/common/fileformat.h b/common/fileformat.h index d181567..acb8337 100644 --- a/common/fileformat.h +++ b/common/fileformat.h @@ -49,7 +49,7 @@ private: // Native file format version static const uint kFileFormatVersionMajor = 0; static const uint kFileFormatVersionMinor = 1; - static const uint kFileFormatVersionRevision = 0; + static const uint kFileFormatVersionRevision = 1; void initFileMetaData(OstProto::FileMetaData &metaData); }; diff --git a/common/textproto.cpp b/common/textproto.cpp index c86f7ff..9834530 100644 --- a/common/textproto.cpp +++ b/common/textproto.cpp @@ -107,6 +107,7 @@ AbstractProtocol::FieldFlags TextProtocol::fieldFlags(int index) const break; case textProto_portNum: + case textProto_eol: case textProto_encoding: flags &= ~FrameField; flags |= MetaField; @@ -136,8 +137,18 @@ QVariant TextProtocol::fieldData(int index, FieldAttrib attrib, case FieldTextValue: return QString().fromStdString(data.text()); case FieldFrameValue: + { + QString text; Q_ASSERT(data.encoding() == OstProto::TextProtocol::kUtf8); - return QString().fromStdString(data.text()).toUtf8(); + text = QString().fromStdString(data.text()); + + if (data.eol() == OstProto::TextProtocol::kCrLf) + text.replace('\n', "\r\n"); + else if (data.eol() == OstProto::TextProtocol::kCr) + text.replace('\n', '\r'); + + return text.toUtf8(); + } default: break; } @@ -157,6 +168,17 @@ QVariant TextProtocol::fieldData(int index, FieldAttrib attrib, } break; } + case textProto_eol: + { + switch(attrib) + { + case FieldValue: + return data.eol(); + default: + break; + } + break; + } case textProto_encoding: { switch(attrib) @@ -200,6 +222,15 @@ bool TextProtocol::setFieldData(int index, const QVariant &value, data.set_port_num(portNum); break; } + case textProto_eol: + { + uint eol = value.toUInt(&isOk); + if (isOk && data.EndOfLine_IsValid(eol)) + data.set_eol((OstProto::TextProtocol::EndOfLine) eol); + else + isOk = false; + break; + } case textProto_encoding: { uint enc = value.toUInt(&isOk); @@ -243,6 +274,8 @@ void TextProtocol::loadConfigWidget() configForm->portNumCombo->setValue( fieldData(textProto_portNum, FieldValue).toUInt()); + configForm->eolCombo->setCurrentIndex( + fieldData(textProto_eol, FieldValue).toUInt()); configForm->encodingCombo->setCurrentIndex( fieldData(textProto_encoding, FieldValue).toUInt()); configForm->protoText->setText( @@ -254,6 +287,7 @@ void TextProtocol::storeConfigWidget() configWidget(); setFieldData(textProto_portNum, configForm->portNumCombo->currentValue()); + setFieldData(textProto_eol, configForm->eolCombo->currentIndex()); setFieldData(textProto_encoding, configForm->encodingCombo->currentIndex()); setFieldData(textProto_text, configForm->protoText->toPlainText()); diff --git a/common/textproto.h b/common/textproto.h index 57b71cc..1ec5fc0 100644 --- a/common/textproto.h +++ b/common/textproto.h @@ -27,7 +27,8 @@ along with this program. If not, see /* TextProtocol Protocol Frame Format - - specified text encoded with the specified encoding + specified text with the specified line ending and encoded with the + specified encoding */ class TextProtocolConfigForm : public QWidget, public Ui::TextProtocol @@ -50,6 +51,7 @@ private: // Meta Fields textProto_portNum, + textProto_eol, textProto_encoding, textProto_fieldCount diff --git a/common/textproto.proto b/common/textproto.proto index 12e5b4e..e20e496 100644 --- a/common/textproto.proto +++ b/common/textproto.proto @@ -26,10 +26,17 @@ message TextProtocol { enum TextEncoding { kUtf8 = 0; } + + enum EndOfLine { + kCr = 0; + kLf = 1; + kCrLf = 2; + } optional uint32 port_num = 1 [default = 80]; optional TextEncoding encoding = 2 [default = kUtf8]; optional string text = 3; + optional EndOfLine eol = 4 [default = kLf]; } extend Protocol { diff --git a/common/textproto.ui b/common/textproto.ui index b3cf278..f6996aa 100644 --- a/common/textproto.ui +++ b/common/textproto.ui @@ -5,7 +5,7 @@ 0 0 - 493 + 535 300 @@ -33,7 +33,36 @@
+ + + + Line Ending + + + + + + 2 + + + + CR + + + + + LF + + + + + CRLF + + + + + Encode as @@ -43,7 +72,7 @@ - + @@ -58,7 +87,7 @@
- + false