From 6656ea4646d06c2a3639f14d570eb00f882f3eec Mon Sep 17 00:00:00 2001 From: Apress Date: Sun, 16 Oct 2016 02:40:48 +0100 Subject: [PATCH] First commit --- 9781430241584.jpg | Bin 0 -> 10655 bytes LICENSE.txt | 27 + README.md | 15 + contributing.md | 14 + .../Examples/ArpPing.ph | 163 ++++ .../Examples/ArpPingExample.pc | 138 +++ .../Examples/BackgroundTask.ph | 109 +++ .../Examples/BackgroundTaskExample.pc | 145 ++++ packetC Programming Source/Examples/Base64.ph | 285 +++++++ .../Examples/Base64Example.pc | 47 ++ .../Examples/BitArray.ph | 134 +++ .../Examples/BitArrayExample.pc | 53 ++ .../Examples/ByteArray.ph | 54 ++ .../Examples/ClassifyPacket.ph | 141 ++++ packetC Programming Source/Examples/Hash32.ph | 395 +++++++++ .../Examples/NewSamplePacketCProject-io.ph | 48 ++ .../Examples/NewSamplePacketCProject.pc | 153 ++++ .../Examples/NewSamplePacketCProject.ph | 42 + .../Examples/NibbleArray.ph | 64 ++ .../Examples/ShortArray.ph | 65 ++ .../Examples/ShortArrayExample.pc | 24 + packetC Programming Source/Examples/Stack.ph | 67 ++ .../Examples/StackSample.pc | 47 ++ .../Examples/StreamBufferExample.pc | 319 +++++++ .../Examples/UdpProcessor.ph | 119 +++ .../Examples/UserException.pc | 70 ++ packetC Programming Source/include/Ascii.ph | 327 +++++++ .../include/Cloudshield.ph | 334 ++++++++ packetC Programming Source/include/Limits.ph | 41 + .../include/MoreProtocols.ph | 177 ++++ .../include/NamedOperators.ph | 35 + .../include/Protocols.ph | 796 ++++++++++++++++++ .../include/SortedList.ph | 333 ++++++++ .../include/TrojanProtocols.ph | 119 +++ 34 files changed, 4900 insertions(+) create mode 100644 9781430241584.jpg create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 contributing.md create mode 100644 packetC Programming Source/Examples/ArpPing.ph create mode 100644 packetC Programming Source/Examples/ArpPingExample.pc create mode 100644 packetC Programming Source/Examples/BackgroundTask.ph create mode 100644 packetC Programming Source/Examples/BackgroundTaskExample.pc create mode 100644 packetC Programming Source/Examples/Base64.ph create mode 100644 packetC Programming Source/Examples/Base64Example.pc create mode 100644 packetC Programming Source/Examples/BitArray.ph create mode 100644 packetC Programming Source/Examples/BitArrayExample.pc create mode 100644 packetC Programming Source/Examples/ByteArray.ph create mode 100644 packetC Programming Source/Examples/ClassifyPacket.ph create mode 100644 packetC Programming Source/Examples/Hash32.ph create mode 100644 packetC Programming Source/Examples/NewSamplePacketCProject-io.ph create mode 100644 packetC Programming Source/Examples/NewSamplePacketCProject.pc create mode 100644 packetC Programming Source/Examples/NewSamplePacketCProject.ph create mode 100644 packetC Programming Source/Examples/NibbleArray.ph create mode 100644 packetC Programming Source/Examples/ShortArray.ph create mode 100644 packetC Programming Source/Examples/ShortArrayExample.pc create mode 100644 packetC Programming Source/Examples/Stack.ph create mode 100644 packetC Programming Source/Examples/StackSample.pc create mode 100644 packetC Programming Source/Examples/StreamBufferExample.pc create mode 100644 packetC Programming Source/Examples/UdpProcessor.ph create mode 100644 packetC Programming Source/Examples/UserException.pc create mode 100644 packetC Programming Source/include/Ascii.ph create mode 100644 packetC Programming Source/include/Cloudshield.ph create mode 100644 packetC Programming Source/include/Limits.ph create mode 100644 packetC Programming Source/include/MoreProtocols.ph create mode 100644 packetC Programming Source/include/NamedOperators.ph create mode 100644 packetC Programming Source/include/Protocols.ph create mode 100644 packetC Programming Source/include/SortedList.ph create mode 100644 packetC Programming Source/include/TrojanProtocols.ph diff --git a/9781430241584.jpg b/9781430241584.jpg new file mode 100644 index 0000000000000000000000000000000000000000..58f5de2abf48fa2087c690e348e77b201f62dfa8 GIT binary patch literal 10655 zcmbVyc|26@`~Mk)O0=kmOoc3!Y>%bEBu^CC+bM-CWfvOTBuS4jc48PMR1#8#EJI?* zGG$~N3=JmxGNv(R`=06Pc|Luv~`B3vYlo25dDqJ#7j= zAQ0dh_y&06z{1Hpo^AkOX$hzT03Zr%1-O6^ID&u&|Ia_;Ht?QbV~8k301yOE^S^gP z1b>bpzy|Po;a_6`aJ=oG>j6>7&R@TScR+Ui^E)`t?q6ew6dkgMKf}-G_CaL+9gjj} zf87f%2BQ4i{D!}c?fx?c=itln_Zt!dei8f*{QBgP024q|SXe}OgQ$pz$i|JLo5Uoy zh;801CcS-!gyh~mP`SN(WM%g$s449`a9CbeR#{i&u)2n}wl-8r-%wA}Kut?qlRpV$ z zP-ug&i0H;mo52g-Z3P4%f`S4nF!&rES?RAj@{*sze$xlS( zPgFGRwEME8pyeEJZ{wz2yQQS}C>~T&R#DadLq}In|Cq_2Cr!;xoi?{Wd+z*&i!FW3Kb%f&hYli}kN$|4XiI zpj-k%LV`jfe7PV3A>bjnO=!b@4dLy^wj$U4cO1}+5|uoW{G_63qr8^g(oW}qFPnBL zXpbu{^F{k9+5eqj_x`^m`&Y34$Tb9r2|_^Q32p=6z>`m^-HXVNm&j2TEpbdhVKj^#L;)NjyL&kYEn9w$ru2^^Y|4 zA4nT9lgg!JTqGSlBXZ8>nVc5E5bvXUe)+g~*Uq{Z_2--z1yh0{PMKdS)@(%Jd)g02 z?NCG+XZu*cC}oD9svJJC(xh=JN7Y~)eJ$SI_smxKrZV9-6(&M*jt}%I-fE*&M)AQK z{afN$k&=+))ESR<`X6BzYc0Btx9_NZ+M4_zFokqhjH}@G+(uwxJzF!vQc)79F)9KL zb^0WrX8qzRXe0^ylOivk-c@A5#-N!=qSAC8K#y~(JY5TvMe+da<(=y12dW=eR7B`W zL#a!}UJ*QCc0dek5Y)&6;4zksuZ|2eu8we!9Ou-wh$jtKP5raqykti*V^yN?SSDL# zQv-osnp>KTFVl7ujqGGqO@>ky!`xEa!gs7JX(D)l(Suj>NG(nvhg%m!q8H73$1=JS zqW9`g@BmEfqbLa0ZzJrELeMI>u02kb)%$KB@W`^YJ>?zyj(B1Xp!mwyur)c*9tL(-pSwrufrFmrl;wJeupA* zmn1scgv8c)zC=KLIU}aIl}ULw6|<-vB4n?-sxfl9kfOcJ%jT&UJ^CIY!Ln+`7hPR=ndFB8oTg zO^1QC9t-v7Mm(?H+0eZvl6ZWddp{58Q%Q`GebH)GczM(4MGh^ZDGx1%qOF}nH0`Lm zSV6GwyWf}?r~DEyw3L)9iUTURsJHIW+wQLelQFYaT~%{v7o~h7GAGmzp>uTMFXjcP z?o~4;`=*E5jeBnX5V!q}8=_>Rm^{F-7jiKoC!Vqv2KC|rmrZ^|WJz@syCoc#FW-8p zi%wBYx>5_Vq1+k+YTxKnpc6ehB^n9ljUB8i`%EDnD})r=C~dAb3X|i_q{!4uoIxh& z>aeWO%u~u7G2C~TGCW-|A?XK0{NEq<$Dg6Fzr8AYq1rr|qkUuBQ})MT0vt0LP0tsb zV(ISp|61-BvCM&AhJSgZ5g%TUYCslxzJ9q}0J2#E)jSxFph;e3(5Ntv2$ z{{NCTjt<|22at45g6J3R-A;MVc6N1E5U!gFNVcd!3kbO3tT$)`TP*M zW%2mOt}6C&!f0#}94|>;jVLY(UhaQw4Jy5ed^AfUWsuBSp5`J|eV97B3#j3Vh3R(w zeio35>}r#m8PGG-$FCM}WaNvNei$*i>GCl4V9ecNCbK>fNq8qS(blQ7ra_AU$G}N0 zs{LP87&a`;g}Q)FK~{pl*B=^W*1DnPEXgwti}7sAYdC>=d@Bzqn3tY?>t5y<53VNe zO5QC5GUVMQaqeaAM3SUSULELoU&HRT1|P1qexhIW!0e>tIRNxJFi-)Go7GyHQSYmn z#{ytnM`D#F4$@x|SUG^CH)K7pYA%mlLZ!J+F{ta@v-3#{Q`VVB*hp(Gu79V1>D%B-@!&Yaj`vj zW$hewJB?-oE6WUs_bh7{kCLV2oUl-09Lnn=ypFO3l{1>@3IjK6U|k@tN*QvZqr$H_ zU5XhR0AC;eU;4P$QXWZzDigXE33T=g(*BW7jGDt5Czb~|&Bg%%ubxRfKF)+kPlL0q ze@lARaMeQM{jk?G0Zx6Veb~{>dI1Tgaw5}WTn4$7Q=ln1|Ei>Yg@XcTiSro@*6q}& z#H5xffgVh#KiC$+170yhkVw+>Ix)EAEk5Jvrjfq>m|5motqt4DP0|UDQ`y5V%1`6+1$)03&v@i-cF1&|+BI&r zB#wY`klnfUAvD1t9~}u_E{>=zsP?rH1-l@Nrb9V5{j_|?PNMUuBq(vGfYhscgA9YB zNaJ~K1ntx%103Blp*T0X4_)LaCc2!q5P@4Ce0I?Ku&h}^v7nOSNx|I#%xH!Lqgw9b zYSF@#1XczsIyXAe8kBnF#X0wspg%7T4lV&oL}pOF*=_kzc}K)`+T6vvNKKE=e|min z5ISt+&V}TG1}$A}F+6zRCFqH7widCx+l+EvYDUiGhJDCmojZ%zDUOQdjI`r{plDen zd8e*`p!U^EP*?o{ir#{?$dar*n}vkIufxJW2UDtsU1(EiOGaA23v5TG5-Fr>y*J_D z6WN$y)7l$CDSBHfQ9YaYLU<(ZMd3OJM{g0|6b&=zjCFZ!*7;GB>lS_ z?2+joirM9OD5FI?XHj|5-ZxXtx@s|po-eBVB$Z>q8OLWBs?=tBemwFC>E{oItl7wO z{;f|GV)ke&7TTDx9Q2^+7gk=Maj1LO6tAH_cQKyp`Z*gC-xeaF*f`9dll4Qclh4@J z1i%Bx&8Q?Wm1Dx~|4PsCIiP^gq-f%nx%@G{(5-pV*Mmr-kT*sYkm_-8gLa`iN zFODqD8Ca#R_w34an=@$*AZb9`j_ zHR%(ps7c%5A8^7XN44(b!*}@l3nH-y1ExI9?+Qtm!0p_T7IjhJ% z_*WGY=0^ppxm0Z)*2PNkqKR;5SoTeWL8em>gLzYn+qZx;zx?oV{*^hS5lo&fn%+3O zMidJ(|2CO(Kx-v0b}w9vo7TSNNytjmrb|@|B2nG&!h_y#)P;?%;>qxyynMCR6>!Bm z!8)d<$B3V>kGb_+aKkpgHmdimeN~66W>vvCbWG-I@dB}qTyv11jwHhn91j7*;_ICt zEEF_Ez^Ti{nmX2t!&OdevBmujB2>#ROgh5}nIViE8X-*o`QURc^X54Vosq@~aet07 zBzSA{j+#mRVZ&v9q$9GEC*9{UD_z~g>v9;>z>oQOv0r&d za4$;pfLkF-D}~P`QZ!%BU=Oc_0MY%?gz5DjFMX-pavkJWMvKa=E!2$%M^>(dxlD3y z9wsd}a^?8i$&wgCaA+>KLS$)Hq9j~@LkQ}d^fdi>rEh!V_kpqXWs4l|fkswy#dIRF z6j1x%0>$}OYqd2_AW_pc)*lyXyQnV=dLLtlH1#)WHO(gTU88Vt3Y*CYvp13cJ&pdv z8gNz06hn%_rWYep7J0zg(;Y}C5sW4DE^UR{-Qq?wl!@uKMP}f<)u0Z0BQRMrI0pwe z&w1xm9(9Ay|8TQ+crU2VwWURCZPW{Yt zu@)bbD&7nIWp=22q_S+X<=jS{QCYtNX(yypb6HPH`Sw?-4-~zzuI=&Y#8`L|{8PGH z^`~!Ntko%r)zeI3T~49%(@Efb`W*v5obHs~6X)7b-zLq}DR~p&xb!_h^B?#O<9CjT z05Qtf8hEUE(y-&kkQ{BPG#$}K5nsWTsV6ReTg&oJ4N;<6wFug;d@i5ZN9KtpT0 z31v)1myBW)6F=e;97f}Y*+atHEvTRLB{)35m)0fx&FK)-{fyK-Dk(Vd_-QO>`JdF- zqU+UgIf=3WK3#t=4^WGE;jtn54?;G6?xw_Jl~!2#M5I8$QP>8!yQ)B|o*t!w?Qi$? zLf$RG+ch*rA!@Z#7FRy*dg5$Hd$nDybK7k1-U7Ma^t<=p=9n|hARvsG9(66GP0GeX z@%#`pyIM4ti9z4~wMss8K{cow;I1da)l~2LFu`1CHg#O9mJH$q;`BKxA#dV!kCi`~ z`|jFLU;B>lASRPns6!>g!aK@cQfK2Mb6=FU{*L`Fk%XIQJV5j(o+%^=FF3_xmm>@t zaF?%iR0MAJD`Cs$AvwrgwPjqEEE+2#f@S{bIxggS6WM3pK{Jb&9YgM(G`4^rPS#o& zn2-o(7pzQW=(||gdpS+TqhB8jf+nbB!w;h>Xcevg!&s+Af77SidiuK#=v%0bKXAj} zbS|uTn348iKpjHRm*!~M)jjMvsrZ=58{#Jdn#6vmhhO%Yh&)TRP{+G=BJYg3qcY>6)YH_H6O_3+rnxS% z@r^a5Cy&@NrNP=|gb@FGF$FgJ&&Af#Nv(@T$kP26gI$m?hqd}?)`JTSHKPS1<3(=7 z^69#3+{wy!xcmNH8V?3^Ib2;n=(8k=6G0nE`~!rSI%>hBy^Ki;y$u4KM_CRr&=2|( zNU+#F2HZ&`tW9|>r0P-Q!*P!bw+)8ZdhhS*+Io{Y3_q)KoTE|%iQh5HtY&zwUgeG>I~)Hsz}hX8R^ZnNMu zK5JkvU|8-2hc7MZhGDo^s?8@!^Kq*SN+S9tG7p*`Iw->5>+!jU4<(((kK2T{;O}X~ zdHfd|jP4q$UZK77?>97??LiyNvk{lt=|AwRE$T{b8Zeie)F~-Jc{W#a9;2&OE$tJ6 zG6s`(lz5!OeZdZmsP{UH?R()EZHgjwus0=2PFHYv7nS}z-CFuFUImpEhCDib$_6Yu z90x&+9b0;6p8`TD!*0R(uwy6^=mHcZqY(v0}-|I;RX6L z!0cKN!hH9Er4*rX!QNz!$|2y3!t@Srjk|4)iEH0VdBDex`Mo=kXdI)j8*cvWLNsft zwU4`>@P~rGaMqzKnr>DXu~x@8p0!{cUtO$B-0hx%V{~)jm&4wz*X~x9$Wd0}JOzBG zG;Boe+l5AWK!+kMklUxR7W8ZobdR!Yn!^in(QHg1uul^Uf6tWzX&^)9v(8#AR)a|> zwN%-@)yn@yJ5*3H^Gu1w92q^CSOW}g?XyrrQ17i~)14M$5TL|BOSt&eB4z8fvl zrk=X)1Ggy_zKk*fSr*B7fAMO4~nzGNjcZrB>I85O`Px?ki_BbRE-QdOpV}a6)WBA8%e!sf^<%YMPk1 z*%~)ph_VCQ>5%tqg6I(cJE>CneoIL@cU#^u8i8Io;#;d2hLy3#@+&1P3AGjwk-j!U z`jfzH?VE|*HZh4q{Vd$3^8dW~S-d3g0$k+>fnJm<-06~AoLk%jrxc$4rZ!*dnm%F;qAz0Z}?G|sgZpX0o-1NwFnTKrdg|MsmFxkM!hKe zsOubmJB5CI8E>2MC$i#{yYM|uePbpK9q#MJBNaTrfQ?Hk^1+gG3uNAV8(}V&yVk5c z)agK}8KZ-b(4ftQr>R$%OxB(STG~8**?TO~@e6Wh%x*-OxI)7w!uZwqi__Q%$Vkml zggCr-(te|lkl?NkY`bkOv>8|S?ani|Y+dg!TR(LrITb@WzWD5GC*Kbz$27_y@3Z(f z>l)t+rf)%IlH-yLN}?ti))an}h?ISw!q7sGQSsG`Et}zcdS0Ls;Xt?7DPHA`{NJ`QS>!tvObW9%ZMi zL5{{Grx)7t9l1VY^zLf#5v>d<{U&L`tfkoRu2#MM%A>!Iy#xcb@z122JK2Sk^U(*B zw*(hU+_`Jtkdg1W^u#)iy=rOx3tII-Z=IG^@l=%{}=Qsk;N=+&4| zpCb&;I5vcVDqibx-cme8^}s9rWT@^cy5>xEK89fu^6>Ef>1-P{$-9-hXAO=<`XLF9 zy(hhykk)_!eWNvQnlo8mOk;&%!~-}tfmDvXr(B@-0HxSA@8rc5H8wk*0USvj3fKqhMAw- zl|=Xtf3(%x5eqX#7!|<#GIy~mt6h|8KtgDi2$?)M3`b!81JXED8He0l#8iQ;NU-eu zLPRCUb5m2L%mcqL%!jB{p&aCTb1ns1yO^j~bU)Mio7Ho8Y(7Z!%?8e&egtl!J1##} zLG%|U(vT9ec{QMEg)H89uhBF*eof}x5*gYP?=TVG zEa)4!hynQ$m7|#{JmABy7lX?FQS6n|iO-5$qIUd%b0Sp_8@G=PRqcZw4__gdS76MSb#sOr|_eUutRQv0mc?HYtvELYp2i4oQp zR%|y{_{;Q}krng_vL8~E0R>up>*ag{uY8f*eldX(|i8*{~b&?n1Ljff zF@6KmBIq$Oe_|BV_S(Mlt1$!>Oj;Nc)0$Kcmd#&vMoOdKhJNiQ9zD?LD=%Xr=6X*g zGWVD}`{u^^;(Jmf*}|80#_d!}M!SPHv})7}Su|UK!q#NW3bjJo{5MB5vE>u3!JZ7c zo~FTiwXkXwyZXDb&|E`L(eu}7ptgqD^K!8uqyf?6I1h-1D)Y&=m_rD%hS7OlT`B&4 z3x!AIh1ap`Q8;inYXdp&|Hgy2yOe!%I3^(IOAAF}x>Ff-s1fRxJc&|eS|ATNTu~RS z_Z@BpMoMz62_!nqzUuXYyVng|e5eG-_DXhro^yOMZW?*D4h+lF zr2LUja;2?=;-9SJ-JNIs9}fg%G4a?H>U5l^Z6znr{gyjb?yXAfd-pU#`znFH-s1*6 z3Z@Ghw#>jrDCYulozco|;Dbp6qD}(XpJE6LFV7&m4W~m)rXmR6rYlLamYp!`_I6v4 za)fhV3K^!|sDSP20FjR|7>mh{U)}|PNO6*@0T$YQ>u%X+WbfV&7=T5B4DcD-_hP72 z*)o|(9LKj5fJvPf2pKwuLzTg~1$N9gnNvT!7AcI;f>PrwzesB^+^$mNvWG167IdvQ zrl?z;RnuBo{V^4loN~qZR;Ipru)mYhPuX-?Gv3d=4AA-g`Gpx&7muLm=|M6-Vec z1Widc_f!uMaLJ&$gE(R~@~ls+`~-J#i34i*@^Q7VO(1!)1%(FrEKI4MGMQTs;<657 zewV}TI(1@h*qiY!OJ$-ZiRI6T^ih{_qZ zPgkTc?t{)L0=9F0CRjpNHp@}DbZ|rE zex<`gMbmhz&;u*=q|D-+{+;?+Rv(e zN73Fs!E|c&ozoytE!7{@SP`$L#9jMCtW*A6{Pq(uOinAjn0kKC5FJP_ZM3g0kv5f( z9;4>%1_MaK1!K+oH`4CyJjFDVGdx*U0Z14KCQKcwQSQ%+XJB*HcJrh-IF2m~8tb z#{Q*A)zg-pkI5QtVjLTHm_Iu$GOa6RB61Z|)BR-;MI&p!-8!;DTM-+tq_K#g9v|Y# z&=n%sx_Yt6BAP`^DC-`rqgid#0XJbWtW~(_y9S;)ZE;*m?#iPT!Ik*%QHpG&W7t@u&IRRblZxjKKxq#jV6ZXdU#-BU#U%bi1mWD5FtO5fx)d2L7;3L=oQ_avF zeA1?f^F-&a{nIEC8cJgl8+vlE2-lSe7=;bLoO}G_F1Bl8$uOTfcHWXDPt8dPD_^w3C+vm0egIo{Kzv6UT&WSkwjl{M4|4& zK;)0GP?w&ZANPk$n^W?G>2T^&fz8egQqn7}jHY%5ewE|VQe`TN@94#ZgKYGkZ(7Oa zcP->bXk2(9)bmVqdA#>@;vf%z_GIKAJhEhEW{Owpj|(Pw4}9V*+7l(oZx2ee1(=AB zbiw8|7Fe+|l_ZdB*4`XZpakNUyc%il+c^iH39#4t6UbV!PIv>wCk3&3VA-y{__k<% z^pXL_Y7GR$pe)Cau#(w^ges8x*y=TwFkmo2pEpM{Xu&daR;YeW-+Fr7L0?ZlDq zy&}#eMGKo~&2L4+=2dXP&5TMCQ7#Q!T#t@yI^IYBr`WRRNl8*c zUb2{Qr1=>K_viSIVHS1WF6Uvl=?BQ+un+`7+=fuo`@&;G!6TKu>_068;$ ze7;*0Ob!Vr5B;U+CJ20fE%;m4OCU};|KH=;z0t5t6<@KGa=R86yN{4|gW#QeL-L^S zdBFVxWb0nFT{AG!^q(>EcXeiOC`fgmYNe$n-Z@8qb?EDD%0dbDjoP-U&^dqg%Z?+5 z6MTKOKPZmuPuT1wSG;$_Y5$^|yOK{H=}PF-==kWXaOMg3e&Vg(+X({Ro4@VK*RI%C zS>LmuRB?my;LOV~%{+C)*m>dX{wj)WM#@A_kh0x{OzYY|?+Yhq?}9+STg$q?)A82ijt)3l-UyTxkxKq{ zt!|aNcedw`j`mmV3**|oQ`M+bI_D4FPV7A3TvzV@d2B2xLbVF3Q&M!(NZIX6;S3YgCPMwoZ|H0I!96p}{L zm_<9M->x?~t9EF(T_|Sr{w8Ho?AT3J<+77khtT6ECGCNyamxQ35Nq(CfFuFi-wwM; zl%2=ZySfHiWi9zvMjS0X72ETMEFzwIN14QHu!@!T9@^t+(0(Z@qJ|k#b!u +#include "ClassifyPacket.ph" +#include "UdpProcessor.ph" + +// *************************************************************************** +// Define constants used to define this box +// *************************************************************************** + +// IP that this application responses to +#define ARPPING_IPADDR 10.101.1.241 + +// 00:0B:A9:Fn:nn:nn – Is allocated to packetC developer private internal +// cabinet addressing. This is documented as a CloudShield private +// address similar to RFC1918 IP addresses. +// +// Define this uniquely in the form 00:0B:A9:Fn:nn:nn +// +// MAC id of this box that you want this to be identified as +#define ARPPING_MACID 0x00, 0x0B, 0xA9, 0xF1, 0x23, 0x45 + +// :NOTE: ArpPing.ph will error out if either of the above are not defined!!! +#include "ArpPing.ph" + +// UDP port that this will respond to. +int CMD_UDP_PORT = 31337; + + +// *************************************************************************** +// Define the global variables that track the type of packets processed +// *************************************************************************** + +// Global variables that track number of packets processed in types +int totalPktsProcessed_ = 0; +%pragma control totalPktsProcessed_ (export); +int cmdPktsProcessed_ = 0; +%pragma control cmdPktsProcessed_ (export); +int arpPktsProcessed_ = 0; +%pragma control arpPktsProcessed_ (export); +int pingPktsProcessed_ = 0; +%pragma control pingPktsProcessed_ (export); + +// *************************************************************************** +// Helper function to determine if this packet is directed at "me". Note +// this "borrows" the use of the ARPPING defines. Reuse at its best. +// *************************************************************************** +const byte MyMacId_[6] = { ARPPING_MACID }; +bool ThisIsForMe() { + bool thisIsForMe = false; + + if (ethernet.destinationAddress == (MacAddress)MyMacId_ ) + if ( ipv4.destinationAddress == (IpAddress)ARPPING_IPADDR ) { + thisIsForMe = true; + } + return thisIsForMe; +} + + +// *************************************************************************** +// Main code block +// *************************************************************************** +void main($PACKET pkt, $PIB pib, $SYS sys) +{ + // We will only respond to traffic we are interested in, send the rest on. + pib.action = FORWARD_PACKET; + + ++totalPktsProcessed_; + + // Determine the packet type + PktType pktType; + pktType = classifyPacket(); + + switch ( pktType ) { + + // ******************** + // PING request + // ******************** + case (PKTTYPE_PING_REQUEST): + // Process the PING request with a reply + if ( HandlePingRequest() == true ) { + // Increment the number of these packets processed + ++pingPktsProcessed_; + } + break; + + // ******************** + // ARP request + // ******************** + case (PKTTYPE_ARP_REQUEST): + if ( HandleArpRequest() == true ) { + // Increment the number of these packets processed + ++arpPktsProcessed_; + } + break; + + // ******************** + // UDP packet + // ******************** + case (PKTTYPE_UDP): + // We only accept UDP packets on a special port addressed to our + // ip adress, macId and UDP port. + if ( ThisIsForMe() == true ) + if ( udp.destinationPort == (short)CMD_UDP_PORT ) + if ( udp.sourcePort == (short)CMD_UDP_PORT ) { + // Increment the number of these packets processed + ++cmdPktsProcessed_; + + // The read_counter command is the only one we send back a reply + if ( HandleUdp() != CMDTYPE_READ_COUNTER ) { + // We want to drop these control packets + pib.action = DROP_PACKET; + } + } + break; + + default: + // We don't do anything with this type of packet. + // Drop through. + } + +} diff --git a/packetC Programming Source/Examples/BackgroundTask.ph b/packetC Programming Source/Examples/BackgroundTask.ph new file mode 100644 index 0000000..4a64c90 --- /dev/null +++ b/packetC Programming Source/Examples/BackgroundTask.ph @@ -0,0 +1,109 @@ +// ************************************************************************** +// backgroundTask.ph - +// ------------ +// Author(s) : dW!GhT +// Date Created: 08/04/2011 +// Version : 1.00 +// ************************************************************************** +// Description: This provides a way to have a function be a background +// task that takes care of the machinery to execute the +// function. It also provides the ability to have the +// function executed for a specified time (in seconds) calling +// it multiple times till it excedes the allocated time. +// +// BGTASK_INIT +// Function to call before the first time the background task is called. +// +// BGTASK_FUNCTION_CALLBACK +// Function to call that is the background task. +// +// BGTASK_RUN_FOR_X_SECONDS +// [Optional] Length of time in seconds to run the task. +// +// :NOTE: There are other ways to make a background task but this one +// has the advantage of self adjusting to the the throughput +// of the box since the driver of calling the callback function +// is a replica packet that gets put at the end of the input queue +// it naturally provides this. +// +// *************************************************************************** +#ifndef BACKGROUNDTASK_PH_ +#define BACKGROUNDTASK_PH_ + +// *************************************************************************** +// :NOTE: This is prototyped here but you will have to supply a hardward +// specific function call to return a timer value. +// *************************************************************************** +int getTimer(); + +// Make sure that we have the required define set up +#ifndef BGTASK_FUNCTION_CALLBACK +#error "You have to #define BGTASK_FUNCTION_CALLBACK." +#endif + +// Global variables to keep +bool BgTaskStarted_ = false; +int BgTaskLock_; + +bool runBackgroundTask() { + bool backgroundTaskExecuted = false; + + try { + // Test if we have to kick start this process by floating a replica. + // This is done only once when the first packet hits this code. + if ( BgTaskStarted_ == false ) { +#ifdef BGTASK_INIT + // Call the init function + BGTASK_INIT; +#endif + // Lock so that only one context is changing the + // control variable. + lock(BgTaskLock_); + BgTaskStarted_ = true; + unlock(BgTaskLock_); + pkt.replicate(); + } + + // Only if this is a replica do we call the callback function + if ( pib.flags.replica == true ) { + backgroundTaskExecuted = true; + + // To minimize the impact on the system of floating a replica + // we try to adjust the size down to the smallest we can. + // :NOTE: We could test and set but just setting it every time + // reduces the number of instructions involved. + pib.length = 4; + +#ifdef BGTASK_RUN_FOR_X_SECONDS + // Init the time we are going to run this task + short stopTime; + stopTime = (short)getTimer() + BGTASK_RUN_FOR_X_SECONDS; + + // Run till the stop time is + while ( (short)getTimer() <= stopTime ) { +#else + // We just run the callback function once + { +#endif + BGTASK_FUNCTION_CALLBACK; + } + + // We drop this replica packet and replicate another one to + // continue this process. + pib.action = DROP_PACKET; + pkt.replicate(); + } + + } + catch ( ERR_PKT_NOREPLICATE ) { + // We had an error occur when trying to create a replica, here + // we try to restart this process by trying the next packet. + BgTaskStarted_ = false; + } + + return backgroundTaskExecuted; +} + +#else +#error "Multiple inclusion of backgroundTask.ph." +#endif /*BACKGROUNDTASK_PH_*/ diff --git a/packetC Programming Source/Examples/BackgroundTaskExample.pc b/packetC Programming Source/Examples/BackgroundTaskExample.pc new file mode 100644 index 0000000..a184a4b --- /dev/null +++ b/packetC Programming Source/Examples/BackgroundTaskExample.pc @@ -0,0 +1,145 @@ +// ************************************************************************** +// CleanDbTask.pc - +// ------------ +// Author(s) : dW!GhT +// Date Created: 08/05/2011 +// Version : 1.00 +// ************************************************************************** +// Description: Used to show how to create an background task. +// +// *************************************************************************** +packet module Sample_StreamBuffer; + +// *************************************************************************** +// Include supporting header files +// *************************************************************************** +#include +#include + +// *************************************************************************** +// :NOTE: This is prototyped here but you will have to supply a hardward +// specific function call to return a timer value. +// *************************************************************************** +int getTimer(); + +// Structure of database record used to store flow info +struct FlowRec { + int srcIP; + int dstIP; + int expireTime; +}; + +// Database that stores the FlowRec info for quick lookups. +#define FLOWMGMT_FLOWSIZE 10*1024 +database FlowRec flows[FLOWMGMT_FLOWSIZE]; +record FlowRec flowRec; + +// User Created Exceptions +const Exception CLEANING_DATABASE = ERR_LAST_DEFINED + 1; + +// *************************************************************************** +// Background task that will prune the database of flows that have "aged" out. +// *************************************************************************** +int LastRowCleaned_ = 0; + +void cleanDatabase() { + try { + // Increament and check to see if we have to loop around to the start + ++LastRowCleaned_; + if ( LastRowCleaned_ >= FLOWMGMT_FLOWSIZE ) { + LastRowCleaned_ = 0; + } + + // See if this row needs to be deleted + if ( flows[LastRowCleaned_].data.expireTime < getTimer() ) { + flows[LastRowCleaned_].delete(); // Throws ERR_DB_READ + } + } + catch (ERR_DB_READ) { + // Record not found when trying to delete, just move to the next record + } + + return; +} + +// Make the cleanDatabase() routine a background task +#define BGTASK_FUNCTION_CALLBACK cleanDatabase() +#include "backgroundTask.ph" + +// *************************************************************************** +// Main code block +// *************************************************************************** +void main($PACKET pkt, $PIB pib, $SYS sys) +{ + try { + // Test to see if we are cleaning the database, + if ( runBackgroundTask() == true ) { + throw CLEANING_DATABASE; + } + + // Assume we are forwarding all packets + pib.action = FORWARD_PACKET; + + // Masks that are used for database searches/insertions + const FlowRec searchMask = { ~0, ~0, 0 }; + const FlowRec insertMask = { ~0, ~0, ~0 }; + + // We only deal with IPV4 flows + if ( ethernet.type == ETHERNET_TYPE_IP ) { + flowRec.srcIP = ipv4.sourceAddress; + flowRec.dstIP = ipv4.destinationAddress; + + // Get the record (flowNum) that this flow is stored in the + // database. If we don't find one then we insert it and init + // the associated sequence array. + int flowNum; + try { + // See if we have this flow in the database already + flowRec.mask = searchMask; + flowNum = flows.match(flowRec); // Throws ERR_DB_NOMATCH + + // Match... update the flow with new expire time + flowRec.mask = insertMask; + flowRec.expireTime = getTimer() + 5; + flows[flowNum] = flowRec; + } + catch (ERR_DB_NOMATCH) { + // No Match... insert flow into db + // Update the expire time + flowRec.mask = insertMask; + flowRec.expireTime = getTimer() + 5; + flowNum = flows.insert( flowRec ); // Throws ERR_DB_FULL + } + + // + // Check the TCP Flags for FIN. If so then we search the + // assembled packet for the regex we have loaded. + // + if ( tcp.flags.fin ) { + // Remove this from the database + flows[flowNum].delete(); + } // if ( flowRec.tcpFlags | 0x1 ) { + } // if ( ethernet.type == ETHERNET_TYPE_IP ) { + + } + + // ========================================================================= + // + // Exception handling routines. + // + // These mostly just handle increamenting stats on the failures of + // critical sections of the code. + // + // ========================================================================= + catch (ERR_DB_FULL) { + // Nothing to do + } + catch (CLEANING_DATABASE) { + // If we are cleaning a database then this was a replica + // so we just drop it. + pib.action = DROP_PACKET; + } + + // FIN. +} + diff --git a/packetC Programming Source/Examples/Base64.ph b/packetC Programming Source/Examples/Base64.ph new file mode 100644 index 0000000..c8236d8 --- /dev/null +++ b/packetC Programming Source/Examples/Base64.ph @@ -0,0 +1,285 @@ +// ************************************************************************** +// base64.ph - Include file for Base64. +// ------------ +// Author(s) : dW!GhT +// Date Created: 07/06/2011 +// Version : 1.01 +// ************************************************************************** +// Description: This provides an application with the ability to encode +// and decode base64 data +// ************************************************************************** +// Usage: Several #defines are required for the buffers used in the +// encode/decode process. +// +// These are used in both: +// BASE64_ENCODED_STRING Base64 encoded string +// BASE64_DECODED_STRING String result of encode/decode +// +// Optional for both, defaults to '0' +// BASE64_ENCODED_STRING_OFFSET Offset within encoded str to start +// BASE64_DECODED_STRING_OFFSET Offset within decoded str to start +// +// Optional for encoding: +// BASE64_MIME Encoded string will conform to +// MIME specs of cr/lf every 76 chars +// +// Example Usage: +// The #defines allow you to define static or dynamic byte arrays as +// your encode/decode targets. An offset is also allowed, which defaults +// to 0, so that you can specify a point to encode/decode to. +// +// If you wanted to decode something from the packet payload, it could +// look something like the following. +// ... +// byte decodedB64[100]; +// #define BASE64_ENCODED_STRING pkt +// #define BASE64_ENCODED_STRING_OFFSET pib.payloadOffset +// #define BASE64_DECODED_STRING decodedB64 +// #include "base64.ph" +// ... +// +// If you wanted to encode something from a string into a pkt payload, it +// could look something like the following. +// ... +// byte myString[] = "A towel … is about the most massively useful " \ +// "thing an interstellar hitch hiker can have."; +// #define BASE64_DECODED_STRING myString +// #define BASE64_ENCODED_STRING pkt +// #define BASE64_ENCODED_STRING_OFFSET pib.payloadOffset +// #include "base64.ph" +// ... +// +// If you wanted to encode a string into another string, it could +// look something like the following. +// ... +// byte myString[] = "Computer, compute to the last digit the value" \ +// " of pi -- Spock"; +// byte myB64String[ ((sizeof(encodeThis)/3)*4)+ +// 4*((sizeof(encodeThis)%3)>0) ] = {0}; +// #define BASE64_DECODED_STRING myString +// #define BASE64_ENCODED_STRING myB64String +// #include "base64.ph" +// ... +// +// *************************************************************************** +#ifndef BASE64_PH_ +#define BASE64_PH_ + +// Error check for required #defines +#ifndef BASE64_DECODED_STRING +#error BASE64_DECODED_STRING needs to be defined for base64.ph to compile. +#endif +#ifndef BASE64_ENCODED_STRING +#error BASE64_ENCODED_STRING needs to be defined for base64.ph to compile. +#endif + +// Macro used to calculate the size of an base64 encoded string +#ifdef BASE64_MIME +#define BASE64_CALC_ENCODED_SIZE(X) ((((X)/3)*4)+4*(((X)%3)>0)+((((X)/3)*4)/76) +#else +#define BASE64_CALC_ENCODED_SIZE(X) ((((X)/3)*4)+4*(((X)%3)>0)) +#endif + +// Offsets within the encode/decode strings +#ifndef BASE64_ENCODED_STRING_OFFSET +#define BASE64_ENCODED_STRING_OFFSET 0 +#endif +#ifndef BASE64_DECODED_STRING_OFFSET +#define BASE64_DECODED_STRING_OFFSET 0 +#endif + +// Return sizes of encode/decode +int b64_decodedSize_; +int b64_encodedSize_; + +// Macros to retrieve the decode/encode sizes +#define BASE64_DECODED_SIZE() b64_decodedSize_ +#define BASE64_ENCODED_SIZE() b64_encodedSize_ + +// Convenience typedef to indicate these are +// characters we are dealing with. +#ifndef char +typedef byte char; +#endif + +// Constants for CR/LF that gets added for MINE every 76 chars +const char ACSII_LF = 10; +const char ACSII_CR = 13; + +// Our base string that we use to encode with +const char b64_encodeChar_[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +// =========================================================================== +// Encodes character data to base-64 data +// Returns the size of the decoded string. +// +// :NOTE: There is some loop unrolling for the end condition that makes +// this code pretty fast. +// =========================================================================== +int base64Encode( int stringLength ) +{ + b64_decodedSize_ = stringLength; + + // The result/encoded string + b64_encodedSize_ = 0; + + // Increment over the length of the string, three characters at a time + int c; + for (c = BASE64_DECODED_STRING_OFFSET; + c+2 < stringLength + BASE64_DECODED_STRING_OFFSET; c += 3) { + +#ifdef MIME_BASE64 + // We add newlines after every 76 output characters, + // according to the MIME specs + if ( (c-BASE64_DECODED_STRING_OFFSET) > 0 && + (((c-BASE64_DECODED_STRING_OFFSET) / 3) * 4) % 76 == 0) { + BASE64_ENCODED_STRING[b64_encodedSize_++] = ACSII_CR; + BASE64_ENCODED_STRING[b64_encodedSize_++] = ACSII_LF; + } +#endif + + // These three 8-bit (ASCII) characters become one 24-bit number. + int n; + n = (int)BASE64_DECODED_STRING[c] << 16; + n += (int)BASE64_DECODED_STRING[c+1] << 8; + n += (int)BASE64_DECODED_STRING[c+2]; + + // that gets separated into four 6-bit numbers. + char n0, n1, n2, n3; + n0 = (char)(n >> 18) & 0x3f; + n1 = (char)(n >> 12) & 0x3f; + n2 = (char)(n >> 6) & 0x3f; + n3 = (char)n & 0x3f; + + // These four 6-bit numbers are used as indices + // into the base64 character list + BASE64_ENCODED_STRING[b64_encodedSize_++] = b64_encodeChar_[n0]; + BASE64_ENCODED_STRING[b64_encodedSize_++] = b64_encodeChar_[n1]; + BASE64_ENCODED_STRING[b64_encodedSize_++] = b64_encodeChar_[n2]; + BASE64_ENCODED_STRING[b64_encodedSize_++] = b64_encodeChar_[n3]; + } + + // Encode the last 1-2 characters. + // :NOTE: We do this outside of the loop to reduce the amount of tests + // that get performed in the loop. This removes 2 tests per + // character by handling this end condition outside of the loop. + if ( c != stringLength + BASE64_DECODED_STRING_OFFSET ) { + // These three 8-bit (ASCII) characters become one 24-bit number. + // If we run over the end we just add a zero pad. + int n; + n = (int)BASE64_DECODED_STRING[c] << 16; + if( (c+1) < stringLength + BASE64_DECODED_STRING_OFFSET ) + n += (int)BASE64_DECODED_STRING[c+1] << 8; + if( (c+2) < stringLength + BASE64_DECODED_STRING_OFFSET ) + n += (int)BASE64_DECODED_STRING[c+2]; + + // that gets separated into four 6-bit numbers. + char n0, n1, n2, n3; + n0 = (char)(n >> 18) & 0x3f; + n1 = (char)(n >> 12) & 0x3f; + n2 = (char)(n >> 6) & 0x3f; + n3 = (char)n & 0x3f; + + // These four 6-bit numbers are used as indices + // into the base64 character list + BASE64_ENCODED_STRING[b64_encodedSize_++] = b64_encodeChar_[n0]; + BASE64_ENCODED_STRING[b64_encodedSize_++] = b64_encodeChar_[n1]; + BASE64_ENCODED_STRING[b64_encodedSize_++] = b64_encodeChar_[n2]; + BASE64_ENCODED_STRING[b64_encodedSize_++] = b64_encodeChar_[n3]; + } + + // Add the padding to make this string a multiple of 3 characters. + // The pad character is '='. + c = stringLength % 3; + if ( c > 0 ) { + for (; c < 3; c++) { + BASE64_ENCODED_STRING[b64_encodedSize_-(3-c)] = '='; + } + } + return b64_encodedSize_; +} + + +// +// Decode character indices quickly! This table provides a lookup +// that will give the index to the decode character. 255 indicates +// an error/unused. +// +const char b64_decodeChar_[256] = +{ + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,255,255, + 255,255,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21, + 22,23,24,25,255,255,255,255,255,255,26,27,28,29,30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49,50,51,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255 +}; + + +// =========================================================================== +// +// Decodes character data to base-64 data. +// Returns the size of the decoded string. +// +// :NOTE: There is some loop unrolling for the end condition that makes +// this code pretty fast. +// +// =========================================================================== +int base64Decode( int stringLength ) +{ + b64_encodedSize_ = stringLength; + + // The result/decoded string size + b64_decodedSize_ = 0; + + // Decode 3 characters at a time + int c; + for (c = BASE64_ENCODED_STRING_OFFSET; + c+4 < stringLength + BASE64_ENCODED_STRING_OFFSET; c += 4) { + // Decode the four 6 bit indices + char n0, n1, n2, n3; + n0 = b64_decodeChar_[BASE64_ENCODED_STRING[c]]; + n1 = b64_decodeChar_[BASE64_ENCODED_STRING[c+1]]; + n2 = b64_decodeChar_[BASE64_ENCODED_STRING[c+2]]; + n3 = b64_decodeChar_[BASE64_ENCODED_STRING[c+3]]; + + BASE64_DECODED_STRING[b64_decodedSize_++] = (char)((n0 << 2) + ((n1 & 0x30) >> 4)); + BASE64_DECODED_STRING[b64_decodedSize_++] = (char)(((n1 & 0xf) << 4) + + ((n2 & 0x3c) >> 2)); + BASE64_DECODED_STRING[b64_decodedSize_++] = (char)(((n2 & 0x3) << 6) + n3); + } + + // Decode the last 1-3 characters. + // :NOTE: We do this outside of the loop to reduce the amount of tests + // that get performed in the loop. This removes 2 tests per + // character by handling this end condition outside of the loop. + if ( c < stringLength + BASE64_ENCODED_STRING_OFFSET ) { + // Decode the four 6 bit indices + char n0, n1, n2, n3; + n0 = b64_decodeChar_[BASE64_ENCODED_STRING[c]]; + n1 = b64_decodeChar_[BASE64_ENCODED_STRING[c+1]]; + n2 = b64_decodeChar_[BASE64_ENCODED_STRING[c+2]]; + n3 = b64_decodeChar_[BASE64_ENCODED_STRING[c+3]]; + + BASE64_DECODED_STRING[b64_decodedSize_++] = (char)((n0 << 2) + ((n1 & 0x30) >> 4)); + if ( BASE64_ENCODED_STRING[b64_encodedSize_-2] != '=' ) { + BASE64_DECODED_STRING[b64_decodedSize_++] = (char)(((n1 & 0xf) << 4) + + ((n2 & 0x3c) >> 2)); + if ( BASE64_ENCODED_STRING[b64_encodedSize_-1] != '=' ) { + BASE64_DECODED_STRING[b64_decodedSize_++] = (char)(((n2 & 0x3) << 6) + n3); + } + } + } + + return b64_decodedSize_; +} + +#endif /*BASE64_PH_*/ diff --git a/packetC Programming Source/Examples/Base64Example.pc b/packetC Programming Source/Examples/Base64Example.pc new file mode 100644 index 0000000..b43ddd6 --- /dev/null +++ b/packetC Programming Source/Examples/Base64Example.pc @@ -0,0 +1,47 @@ +// ************************************************************************** +// Base64Sample.pc +// ------------ +// Author(s) : dW!GhT +// Date Created: 03/01/2011 +// Version : 1.00 +// ************************************************************************** +// Description: This project provides a simple example of how to use FAST UDP. +// +// *************************************************************************** +packet module Sample_Base64; + +// *************************************************************************** +// Include supporting header files +// *************************************************************************** +#include + +// *************************************************************************** +// Set up string to encode +// *************************************************************************** +byte encodeThis[] = + "A towel … is about the most massively useful thing an interstellar hitch hiker can have."; +byte b64String[((sizeof(encodeThis)/3)*4)+4*((sizeof(encodeThis)%3)>0)] = {0}; +#define BASE64_ENCODED_STRING b64String +#define BASE64_STRING encodeThis +#include "base64.ph" + +// *************************************************************************** +// Main code block +// *************************************************************************** +void main($PACKET pkt, $PIB pib, $SYS sys) +{ + // Assume we are forwarding all packets + pib.action = FORWARD_PACKET; + + // Encode the string encodeThis into the b64String + int encodedSize; + encodedSize = base64Encode( sizeof(encodeThis) ); + + // Clear out the string that we encoded + encodeThis #= 0; + + // Decode the b64String to the encodeThis string + int decodedSize; + decodedSize = base64Decode( BASE64_ENCODED_SIZE() ); +} + diff --git a/packetC Programming Source/Examples/BitArray.ph b/packetC Programming Source/Examples/BitArray.ph new file mode 100644 index 0000000..c803146 --- /dev/null +++ b/packetC Programming Source/Examples/BitArray.ph @@ -0,0 +1,134 @@ +// *************************************************************************** +// bitArray.ph +// ------------ +// Author(s) : dW!GhT +// Date Created: 04/01/2011 +// Version : 1.00 +// ************************************************************************** +// Description: This provides macros and routines that will deal with bit +// arrays, or also known as bitmaps, in a memory and processor +// efficient way. +// +// The user views the bitmap as one long bit string. +// +// 0100111100110011110101....0011101 +// +// :NOTE: For speed no bounds checking is preformed. +// *************************************************************************** +#ifndef BITARRAY_PH_ +#define BITARRAY_PH_ + +// =========================================================================== +// The bits will be held in an int array (32 bits). +// :NOTE: We have to +2 since packetC does not allow arrays of size 1. The +// last chunk is used as a gating word so that some of the macros +// that scan the chunks do not run off the end of the array. +// =========================================================================== +#define BIT_ARRAY(BA,SZ) int BA[((SZ)>>5)+2] = { (((SZ)>>5))#0, 2#0x7ffffffe } + +#define ALL_SET_BITS 0xffffffff +#define ALL_CLEAR_BITS 0x00000000 + +// *************************************************************************** +// *************************************************************************** +// Bit Twiddlers that act on the storage array +// *************************************************************************** +// *************************************************************************** + +// =========================================================================== +// Sets the bit at the specified position. +// =========================================================================== +#define SET_BIT(BA,POS) ((BA)[(POS)>>5] |= (1<<((POS)&31))) + +// =========================================================================== +// Clears (set to 0) the bit at the specified position. +// =========================================================================== +#define CLEAR_BIT(BA,POS) ((BA)[(POS)>>5] &= ~(1<<((POS)&31))) + +// =========================================================================== +// Toggles the bit at the specified position. If it was 1, it will be set +// to 0. If it was 0, it will be set to 1. +// =========================================================================== +#define TOGGLE_BIT(BA,POS) ((BA)[(POS)>>5] ^= (1<<((POS)&31))) + +// =========================================================================== +// Returns the bit at the specified position. It will be 0 or 1. +// =========================================================================== +#define GET_BIT(BA,POS) ((((BA)[(POS)>>5]) >> ((POS)&31)) & 0x1) + + +// *************************************************************************** +// *************************************************************************** +// Scanners used to locate set bits within the storage array chunks. +// *************************************************************************** +// *************************************************************************** + +// =========================================================================== +// Updates POS variable with the next bit set. It will first move to the +// first set chunk to move quickly to the set bit. +// This will run till it finds a set bit. The array is gated with a ALLSET +// entry so as to not have to test if we reached the end of the array. The +// caller should test for the end of array condition on their own. +// =========================================================================== +#define NEXT_SET_BIT(BA,POS) while ( (BA)[POS>>5] == ALL_CLEAR_BITS ) \ + { POS += 32; }; \ + ++(POS); \ + while ( !(((BA)[(POS)>>5] & (1<<((POS)&31))) >> \ + ((POS)&31)) ) \ + { POS += 1; } + +// =========================================================================== +// Updates POS variable with the next cleared bit. It will first move to the +// first set chunk to move quickly to the cleared bit. +// This will run till it finds a set bit. The array is gated with a ALLSET +// entry so as to not have to test if we reached the end of the array. The +// caller should test for the end of array condition on their own. +// =========================================================================== +#define NEXT_CLEARED_BIT(BA,POS) while ( (BA)[POS>>5] == ALL_SET_BITS ) \ + { POS += 32; }; \ + ++(POS); \ + while ( (((BA)[(POS)>>5] & (1<<((POS)&31))) >> \ + ((POS)&31)) ) \ + { POS += 1; } + +// =========================================================================== +// Updates the POS variable to the next chunk that has bits set in it. This +// moves a chunk (32bits) at a time and tests the chunk in that position so +// POS does not have to align on a 32bit boundary. POS is returned aligned +// on a 32bit boundary. +// +// :NOTE: POS is updated to the chunk (32 bits) that contain a set bit. For +// the benifit of execution speed the routine to determine the next +// set bit has been moved to NEXT_SET_BIT macro. +// =========================================================================== +#define NEXT_SET_CHUNK(BA,POS) { while ( (BA)[POS>>5] == ALL_CLEAR_BITS ) \ + { POS += 32; } \ + POS &= ~0x1f; } + +// =========================================================================== +// Updates the POS variable to the next chunk that has all bits cleared. This +// moves a chunk (32bits) at a time and tests the chunk in that position so +// POS does not have to align on a 32bit boundary. POS is returned aligned +// on a 32bit boundary. +// +// :NOTE: POS is updated to the chunk (32 bits) that contains all cleared +// bits. For the benifit of execution speed the routine to determine +// the next set bit has been moved to NEXT_SET_BIT macro. +// =========================================================================== +#define NEXT_CLEARED_CHUNK(BA,POS) { while ((BA)[POS>>5] != ALL_CLEARED_BITS)\ + { POS += 32; } \ + POS &= ~0x1f; } + +// =========================================================================== +// Returns a count of the number of bits set with a chunk. This is also +// called the popCount or Hamming Weight. +// :NOTE: The "BX_()" macro is a helper for the CHUNK_BIT_COUNT macro and +// provides no useful function to the end user. +// =========================================================================== +#define CHUNK_BIT_COUNT(BA,POS) (((BX_((BA)[(POS)>>5])+(BX_((BA)[(POS)>>5])>>4)) \ + & 0x0F0F0F0F) % 255) +#define BX_(x) ((x) - (((x)>>1)&0x77777777) \ + - (((x)>>2)&0x33333333) \ + - (((x)>>3)&0x11111111)) + +#endif /*BITARRAY_PH_*/ diff --git a/packetC Programming Source/Examples/BitArrayExample.pc b/packetC Programming Source/Examples/BitArrayExample.pc new file mode 100644 index 0000000..0da1e09 --- /dev/null +++ b/packetC Programming Source/Examples/BitArrayExample.pc @@ -0,0 +1,53 @@ +// *************************************************************************** +// BitArraySample.ph +// ------------ +// Author(s) : dW!GhT +// Date Created: 05/01/2011 +// Version : 1.00 +// ************************************************************************** +// Description: This provides a sample of how to use the BitArray.ph +// ************************************************************************** +packet module Sample_bitArray; + +#include "BitArray.ph" +#define BIGBITARRAY_SIZE 256 +BIT_ARRAY( bigBitArray, BIGBITARRAY_SIZE ); + +void main( $PACKET pkt, $SYS sys, $PIB pib ) { + int myBit; + + // Set a couple of bits + SET_BIT(bigBitArray, 48); + SET_BIT(bigBitArray, 49); + SET_BIT(bigBitArray, 132); + + // Get the value of a couple of bits + myBit = GET_BIT(bigBitArray, 40); // == 0 + myBit = GET_BIT(bigBitArray, 48); // == 1 + myBit = GET_BIT(bigBitArray, 49); // == 1 + myBit = GET_BIT(bigBitArray, 50); // == 0 + myBit = GET_BIT(bigBitArray, 132); // == 1 + + // Flip a bit + TOGGLE_BIT(bigBitArray,40); + myBit = GET_BIT(bigBitArray, 40); // == 1 + + // Clear a bit + CLEAR_BIT(bigBitArray, 32); + myBit = GET_BIT(bigBitArray, 32); // == 0 + + // Find the position of set bits + int iterPosition = 0; + NEXT_SET_BIT( bigBitArray, iterPosition ); // == 40 + NEXT_SET_BIT( bigBitArray, iterPosition ); // == 48 + NEXT_CLEARED_BIT( bigBitArray, iterPosition ); // == 50 + NEXT_SET_BIT( bigBitArray, iterPosition ); // == 132 + + // The next two test for out of bounds conditions + NEXT_SET_BIT( bigBitArray, iterPosition ); // == 257 (OUT OF BOUNDS) + NEXT_CLEARED_BIT( bigBitArray, iterPosition ); // == 287 (OUT OF BOUNDS) + + // We are just forwarding packets + pib.action = FORWARD_PACKET; +} + diff --git a/packetC Programming Source/Examples/ByteArray.ph b/packetC Programming Source/Examples/ByteArray.ph new file mode 100644 index 0000000..1039f6a --- /dev/null +++ b/packetC Programming Source/Examples/ByteArray.ph @@ -0,0 +1,54 @@ +// *************************************************************************** +// byteArray.ph +// ------------ +// Author : dW!GhT +// Date Created: 04/28/2011 +// Version : 1.00 +// *************************************************************************** +// This provides macros and routines that will deal with allocating and +// accessing in global arrays. +// +// :NOTE: For speed no bounds checking is preformed. +// *************************************************************************** +#ifndef BYTEARRAY_PH_ +#define BYTEARRAY_PH_ + +// =========================================================================== +// The bytes will be held in an int array (32 bits). +// :NOTE: We have to +2 since packetC does not allow arrays of size 1. +// =========================================================================== +#define BYTE_ARRAY(BA,SZ) int BA[((SZ)>>2)+2] = { (((SZ)>>2)+2)#0 } + + +// *************************************************************************** +// *************************************************************************** +// Access/Modifiers that act on the storage array +// *************************************************************************** +// *************************************************************************** + +// =========================================================================== +// Sets the byte at the specified position. +// =========================================================================== + +// This works best on a POS that is a constant. +#define SET_BYTE_C(BA,POS,VAL) { \ + ((BA)[(POS)>>2] &= ~(0xff<<(((POS)&3)<<3))); \ + ((BA)[(POS)>>2] |= ((VAL&0xff)<<(((POS)&3)<<3))); \ +} + +// This works best on a POS that is a variable. +#define SET_BYTE_V(BA,POS,VAL) { \ + int sPos; \ + sPos = (((POS)&3)<<3); \ + int cPos; \ + cPos = (POS)>>2; \ + (BA)[cPos] &= ~(0xff<>2]) >> ((((POS)&3))<<3)) + +#endif /*BYTEARRAY_PH_*/ diff --git a/packetC Programming Source/Examples/ClassifyPacket.ph b/packetC Programming Source/Examples/ClassifyPacket.ph new file mode 100644 index 0000000..c44679b --- /dev/null +++ b/packetC Programming Source/Examples/ClassifyPacket.ph @@ -0,0 +1,141 @@ +// ************************************************************************** +// ClassifyPacket.ph - Include file for the Example Arp/Ping program. +// ------------ +// Author(s) : dW!GhT +// Date Created: 03/01/2011 +// Version : 1.00 +// ************************************************************************** +// Description: This provides a simple example of how to classify packets +// using the protocols.ph descriptors. It is suggested that +// the user use this as a start to expand on for use in their +// own projects. +// +// Returns: Enumeration PktType (see declaration below) +// +// *************************************************************************** +#ifndef CLASSIFYPACKET_PH_ +#define CLASSIFYPACKET_PH_ + +#include + +// *************************************************************************** +// Msg types that get processed +// *************************************************************************** +enum int PktType { + PKTTYPE_NONE = 0, // None if not significate to us + PKTTYPE_ICMP = 1, // Internet Control Message Protocol + PKTTYPE_PING_REQUEST = 2, // ICMP echo request, PING + PKTTYPE_PING_RESPONSE = 3, // ICMP echo response, PING + PKTTYPE_ARP = 4, // Address Resolution Protocol + PKTTYPE_ARP_REQUEST = 5, // ARP request + PKTTYPE_ARP_REPLY = 6, // ARP reply + PKTTYPE_TCP = 7, // Transmission Control Protocol + PKTTYPE_IP4 = 8, // IPv4 + PKTTYPE_IP6 = 9, // IPv6 + PKTTYPE_8021Q = 10, // VLAN tagging + PKTTYPE_UDP = 11 // User Defined Packet +}; + +// *************************************************************************** +// +// Processes the current packet type. +// +// NOTE: Only these are processed in detail +// - Ping (icmp echo request) +// - ARP request/reply +// +// any other packet type will be returned as its ethernet type. +// +// *************************************************************************** +PktType classifyPacket() +{ + // Set the intial msg type to nothing we are interested in + PktType pktType = PKTTYPE_NONE; + + // *********************************** + // Classify packet based on ethertype + // *********************************** + switch (ethernet.type) + { + // *********************** + // IPv4 + // *********************** + case ETHERNET_TYPE_IP: + pktType = PKTTYPE_IP4; + //classify packet based on protocol + switch (ipv4.protocol) + { + // **************** + // Internet Control Message Protocol + // **************** + case IP_PROTOCOL_ICMP: + pktType = PKTTYPE_ICMP; + + // Ck if this is a ping request + if ( icmpEcho.type == ICMP_TYPE_ECHO_REQUEST ) { + // *PING* request + pktType = PKTTYPE_PING_REQUEST; + } else if ( icmpEcho.type == ICMP_TYPE_ECHO_RESPONSE ) { + // *PING* response + pktType = PKTTYPE_PING_RESPONSE; + } + break; + + // **************** + // User defined + // **************** + case IP_PROTOCOL_UDP: + pktType = PKTTYPE_UDP; + break; + + // **************** + // Transmission Control Protocol + // **************** + case IP_PROTOCOL_TCP: + pktType = PKTTYPE_TCP; + break; + + + default: + // do nothing here + } + break; + + // *************************** + // Address Resolution Protocol + // *************************** + case ETHERNET_TYPE_ARP: + pktType = PKTTYPE_ARP; + + // See if this is a ARP request or reply packet + if ( arp.opcode == ARP_OPCODE_REQUEST ) { + pktType = PKTTYPE_ARP_REQUEST; + } else if ( arp.opcode == ARP_OPCODE_REPLY ) { + pktType = PKTTYPE_ARP_REPLY; + } + break; + + // *************************** + // IPv6 + // *************************** + case ETHERNET_TYPE_IP6: + pktType = PKTTYPE_IP6; + break; + + // *************************** + // VLAN Tagging + // *************************** + case ETHERNET_TYPE_8021Q: + pktType = PKTTYPE_8021Q; + break; + + + default: + // do nothing here + } + + return pktType; +} + + +#endif /*CLASSIFYPACKET_PH_*/ diff --git a/packetC Programming Source/Examples/Hash32.ph b/packetC Programming Source/Examples/Hash32.ph new file mode 100644 index 0000000..19950eb --- /dev/null +++ b/packetC Programming Source/Examples/Hash32.ph @@ -0,0 +1,395 @@ +// *************************************************************************** +// hash32.ph - Include file for hash32() method +// ------------ +// Author : dW!GhT +// Date Created: 09/28/2011 +// Version : 1.00 +// *************************************************************************** +// Several hash functions that operate on a 32 bit value are presented +// here. See referenced urls for discussions on each of theses hashes +// strengths and weaknesses. +// All of the functions also have an "inline" version in the form of a +// function macro that reduces the overhead of calling the functions in +// packetC. All the INLINE_ macros will modify/return the calculated hash +// in the passed key. +// =========================================================================== +// Number of RAVE instructions generated for each hash method: +// +// Function #Instructions Comments +// --------------- ------------- ------------- +// hash32Murmur2 16 Noted flaw with repeative 4 bytes +// hash32FNV1a 22 +// hash32Shift 30 +// hash32Murmur3 33 Updated version that fixes flaw +// hash32SuperFast 33 +// hash32Int 37 +// hash32CRC 40 +// hash32BJ 120 Lots of overhead for mix/final +// +// *************************************************************************** +#ifndef HASH_PH_ +#define HASH_PH_ + +// Macro used by several of the hash functions +#define GET_BYTE(X,POS) (X)>>(POS<<3) & 0xff + +// *************************************************************************** +// +// RAVE has a CRC32 function that will return an int of the buffer length. +// This will return the CRC32 of the passed key. This does a lookup into +// a precomputed global array which may cause preformance issues in some +// apps. +// +// *************************************************************************** +const int CrcTable_[256] = { // Using polynomial 0xedb88320 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +// 40 RAVE instructions +int hash32CRC( int key ) { + int hash; + hash = (hash >> 8) ^ CrcTable_[(hash & 0xff) ^ GET_BYTE(key,0)]; + hash = (hash >> 8) ^ CrcTable_[(hash & 0xff) ^ GET_BYTE(key,1)]; + hash = (hash >> 8) ^ CrcTable_[(hash & 0xff) ^ GET_BYTE(key,2)]; + hash = (hash >> 8) ^ CrcTable_[(hash & 0xff) ^ GET_BYTE(key,3)]; + return hash; +} + +#define INLINE_HASH32CRC(KEY) \ +{ \ + int hash; \ + hash = (hash >> 8) ^ CrcTable_[(hash & 0xff) ^ GET_BYTE(KEY,0)]; \ + hash = (hash >> 8) ^ CrcTable_[(hash & 0xff) ^ GET_BYTE(KEY,1)]; \ + hash = (hash >> 8) ^ CrcTable_[(hash & 0xff) ^ GET_BYTE(KEY,2)]; \ + hash = (hash >> 8) ^ CrcTable_[(hash & 0xff) ^ GET_BYTE(KEY,3)]; \ + KEY = hash; \ +} + + +// *************************************************************************** +// +// Adapted from this article on fast hashing, basically a modified version +// of Bob Jenkins' hash (lookup3). +// http://www.azillionmonkeys.com/qed/hash.html +// +// *************************************************************************** + +// 33 RAVE instructions +int hash32SuperFast( int data ) { + int hash; + hash += data >> 16; + hash = (hash << 16) ^ ((data & 0xffff) << 11) ^ hash; + hash += hash >> 11; + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +} + +#define INLINE_HASH32SUPERFAST(KEY) \ +{ \ + int hash; \ + hash += KEY >> 16; \ + hash = (hash << 16) ^ ((KEY & 0xffff) << 11) ^ hash; \ + hash += hash >> 11; \ + hash ^= hash << 3; \ + hash += hash >> 5; \ + hash ^= hash << 4; \ + hash += hash >> 17; \ + hash ^= hash << 25; \ + hash += hash >> 6; \ + KEY = hash; \ +} + + +// *************************************************************************** +// +// Adapted from Bob Jenkins lookup3.c hashword() routine. +// http://burtleburtle.net/bob/hash/doobs.html +// +// *************************************************************************** + +// Helper macros for hash32BJ() +#define ROT(X,K) (((X)<<(K)) | ((X)>>(32-(K)))) +#define HASH32_MIX(A,B,C) \ +{ \ + A -= C; A ^= ROT(C, 4); C += B; \ + B -= A; B ^= ROT(A, 6); A += C; \ + C -= B; C ^= ROT(B, 8); B += A; \ + A -= C; A ^= ROT(C,16); C += B; \ + B -= A; B ^= ROT(A,19); A += C; \ + C -= B; C ^= ROT(B, 4); B += A; \ +} +#define HASH32_FINAL(A,B,C) \ +{ \ + C ^= B; C -= ROT(B,14); \ + A ^= C; A -= ROT(C,11); \ + B ^= A; B -= ROT(A,25); \ + C ^= B; C -= ROT(B,16); \ + A ^= C; A -= ROT(C,4); \ + B ^= A; B -= ROT(A,14); \ + C ^= B; C -= ROT(B,24); \ +} + +// Arbitrary starting hash value +int prevHash32BJ_ = 0xcafebabe; + +// 120 RAVE instructions +int hash32BJ( int key ) +{ + int a,b,c; + a = b = c = 0xdeadbeef + (4<<2) + prevHash32BJ_; + + a += GET_BYTE( key, 0 ); + b += GET_BYTE( key, 1 ); + c += GET_BYTE( key, 2 ); + HASH32_MIX(a,b,c); + + a += GET_BYTE( key, 3 ); + HASH32_FINAL(a,b,c); + + return (prevHash32BJ_ = c); +} + +// Inline version +#define INLINE_HASH32BJ(KEY) \ +{ \ + int a,b,c; \ + a = b = c = 0xdeadbeef + (4<<2) + prevHash32BJ_; \ + a += GET_BYTE( KEY, 0 ); \ + b += GET_BYTE( KEY, 1 ); \ + c += GET_BYTE( KEY, 2 ); \ + HASH32_MIX(a,b,c); \ + a += GET_BYTE( KEY, 3 ); \ + HASH32_FINAL(a,b,c); \ + KEY = prevHash32BJ_ = c; \ +} + + +// *************************************************************************** +// +// This version of integer hash function uses operations with integer +// constants to help producing a hash value. It is suspected that the actual +// values of the magic constants are not very important. Even using 16 bit +// constants may still work pretty well. +// +// Adapted from a article on Integer Hashes: +// http://www.concentric.net/~ttwang/tech/inthash.htm +// +// *************************************************************************** + +// 37 RAVE instructions +int hash32Int( int a ) +{ + a = (a+0x7ed55d16) + (a<<12); + a = (a^0xc761c23c) ^ (a>>19); + a = (a+0x165667b1) + (a<<5); + a = (a+0xd3a2646c) ^ (a<<9); + a = (a+0xfd7046c5) + (a<<3); + a = (a^0xb55a4f09) ^ (a>>16); + return a; +} + +// Inline version +#define INLINE_HASH32INT(KEY) \ +{ \ + KEY = (KEY+0x7ed55d16) + (KEY<<12); \ + KEY = (KEY^0xc761c23c) ^ (KEY>>19); \ + KEY = (KEY+0x165667b1) + (KEY<<5); \ + KEY = (KEY+0xd3a2646c) ^ (KEY<<9); \ + KEY = (KEY+0xfd7046c5) + (KEY<<3); \ + KEY = (KEY^0xb55a4f09) ^ (KEY>>16); \ +} + + +// +// Based on an original suggestion on Robert Jenkin's part in 1997. +// +// 30 RAVE instructions +int hash32Shift( int key ) +{ + key = ~key + (key << 15); // key = (key << 15) - key - 1; + key = key ^ (key >> 12); + key = key + (key << 2); + key = key ^ (key >> 4); + key = key * 2057; // key = (key + (key << 3)) + (key << 11); + key = key ^ (key >> 16); + return key; +} + +// Inline version +#define INLINE_HASH32SHIFT(KEY) \ +{ \ + KEY = ~KEY + (KEY << 15); \ + KEY = KEY ^ (KEY >> 12); \ + KEY = KEY + (KEY << 2); \ + KEY = KEY ^ (KEY >> 4); \ + KEY = KEY * 2057; \ + KEY = KEY ^ (KEY >> 16); \ +} + + +// *************************************************************************** +// +// Adapted from an article on FNV (Fowler/Noll/Vo) hash. +// http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash +// +// There also is more discussion on several forms and variations here: +// http://isthe.com/chongo/tech/comp/fnv/ +// +// *************************************************************************** + +// 32 bit FNV-1 and FNV-1a non-zero initial basis +#define FNV1_32_INIT 0x811c9dc5 + +// 32 bit magic FNV-0 and FNV-1 prime +#define FNV_32_PRIME 0x01000193 + +int prevHashFNV_ = FNV1_32_INIT; + +// fnvHash32 - perform a 32 bit Fowler/Noll/Vo hash (32 bit FNV-1 hash) +// 22 RAVE instructions +int hash32FNV1a( int val ) +{ + int hval; + hval = prevHashFNV_; + + // Multiply by the 32 bit FNV magic prime mod 2^32 then XOR + // the bottom byte with each octet. + hval *= FNV_32_PRIME; + hval ^= GET_BYTE( val, 0 ); + hval *= FNV_32_PRIME; + hval ^= GET_BYTE( val, 1 ); + hval *= FNV_32_PRIME; + hval ^= GET_BYTE( val, 2 ); + hval *= FNV_32_PRIME; + hval ^= GET_BYTE( val, 3 ); + + // Return the new hash value + return (prevHashFNV_ = hval); +} + +// Inline version +#define INLINE_HASH32FNV1A(KEY) \ +{ \ + int hval; \ + hval = prevHashFNV_; \ + hval *= FNV_32_PRIME; \ + hval ^= GET_BYTE( KEY, 0 ); \ + hval *= FNV_32_PRIME; \ + hval ^= GET_BYTE( KEY, 1 ); \ + hval *= FNV_32_PRIME; \ + hval ^= GET_BYTE( KEY, 2 ); \ + hval *= FNV_32_PRIME; \ + hval ^= GET_BYTE( KEY, 3 ); \ + KEY = prevHashFNV_ = hval; \ +} + + +// *************************************************************************** +// +// Adapted from source code made available here +// http://sites.google.com/site/murmurhash/ +// +// :NOTE: There is a flaw in MurmurHash2, repetitions of 4-byte patterns +// have a much higher chance of collision than expected. +// Murmur3 solves this flaw +// +// *************************************************************************** +// 16 RAVE instructions +int hash32Murmur2( int k ) +{ + // Initialize the hash to a 'random' value + + int h = FNV1_32_INIT ^ 4; + + // Mix 4 bytes into the hash + k *= 0x5bd1e995; + k ^= k >> 24; + k *= 0x5bd1e995; + + h *= 0x5bd1e995; + h ^= k; + + // Do a few final mixes of the hash to ensure the last few + // bytes are well-incorporated. + h ^= h >> 13; + h *= 0x5bd1e995; + h ^= h >> 15; + + return h; +} + +// 33 RAVE instructions +int hash32Murmur3( int key ) +{ + int h1 = FNV1_32_INIT; + + key *= 0xcc9e2d51; + key = (key << 15) | (key >> 17); + key *= 0x1b873593; + + h1 ^= key; + h1 = (h1 << 15) | (h1 >> 19); + h1 = h1 * 5 + 0xe6546b64; + h1 ^= 4; + + h1 ^= h1 >> 16; + h1 *= 0x85ebca6b; + h1 ^= h1 >> 13; + h1 *= 0xc2b2ae35; + h1 ^= h1 >> 16; + + return h1; +} + +#endif /*HASH_PH_*/ + diff --git a/packetC Programming Source/Examples/NewSamplePacketCProject-io.ph b/packetC Programming Source/Examples/NewSamplePacketCProject-io.ph new file mode 100644 index 0000000..d7cb251 --- /dev/null +++ b/packetC Programming Source/Examples/NewSamplePacketCProject-io.ph @@ -0,0 +1,48 @@ +// ***************************************************************************** +// NewSamplePacketCProject-io.ph - Header file for Input/Output (io) project +// ------------ +// Author(s) : Cloudshield Technologies +// Date Created: Sat 06 Sep 2008 04:51:00 PM EDT +// Checked in : $Date: 2011/03/18 13:52:28 $ +// Version : $Revision: 1.5 $ +// **************************************************************************** +#ifndef SAMPLE_PROJECT_IO_PH_ +#define SAMPLE_PROJECT_IO_PH_ + +// Declare constants +const int PORTCOUNT = 16; +const int DISABLED = 255; + +// Declare portmap list +int Portmap_[ PORTCOUNT ] = { + 1, 0, 3, 2, + DISABLED, DISABLED, DISABLED, DISABLED, + DISABLED, DISABLED, DISABLED, DISABLED, + DISABLED, DISABLED, DISABLED, DISABLED +}; + +// Declare global event counters +int IoForward_; +%pragma control IoForward_ (export); +int IoDrop_; +%pragma control IoDrop_ (export); + +// forward io macro +#define FORWARD_IO( pib, sys )\ + if ( Portmap_[sys.inPort] < PORTCOUNT ) {\ + sys.outPort = Portmap_[sys.inPort];\ + pib.action = FORWARD_PACKET;\ + IoForward_++;\ + } else {\ + pib.action = DROP_PACKET;\ + IoDrop_++;\ + } + +// dropIo macro +#define DROP_IO( pib, sys )\ + pib.action = DROP_PACKET;\ + IoDrop_++; + + +#endif /*SAMPLE_PROJECT_IO_PH_*/ + diff --git a/packetC Programming Source/Examples/NewSamplePacketCProject.pc b/packetC Programming Source/Examples/NewSamplePacketCProject.pc new file mode 100644 index 0000000..bbe9781 --- /dev/null +++ b/packetC Programming Source/Examples/NewSamplePacketCProject.pc @@ -0,0 +1,153 @@ +// ************************************************************************** +// NewSamplePacketCProject.pc - Main file for the Classifier (cl) project. +// ------------ +// Author(s) : Cloudshield Technologies +// Date Created: Sat 09 Sep 2008 04:00:00 PM EDT +// Checked in : $Date: 2011/03/18 13:52:28 $ +// Version : $Revision: 1.13 $ +// ************************************************************************** +// Description: This project provides a simple classifier. +// +// Received packets are classified based on the following +// packet field values: +// +// - Ethertype +// - ARP Opcode +// - IP4 Protocol +// - IP6 Next Header +// - ICMP4 Type +// - ICMP6 Type +// - TCP Port +// - UDP Port +// +// Global classification counters are maintained as follows +// +// - clEthertype_: Number of packets by Ethertype +// - clArpOpcode_: Number of packets by ARP opcode +// - clIp4Protocol_: Number of IP4 packets by protocol +// - clIp6NextHeader_: Number of IP6 packets by next header +// - clIcmp4Type_: Number of ICMP4 packets by type +// - clIcmp6Type_: Number of ICMP6 packets by type +// - clTcpWKPort_: Number of TCP packets by well known port number, +// index 0 incremented for ports greater than 1024 +// - clUdpWKPort_: Number of UDP packets by well known port number, +// index 0 incremented for ports greater than 1024 +// +// Received packets are evaluated against an array that lists +// output ports by input port. If an assigned output port is +// within the valid range of port numbers, the packet is +// forwarded out that port. If an assigned output port is +// outside the valid range of ports, the packet is dropped. +// +// Global IO counters are maintained as follows: +// +// - IoFoward_: Number of packets forwarded +// - IoDrop_: Number of packets dropped +// +// **************************************************************************** + +// **************************************************************************** +// Scope declaration +// **************************************************************************** +packet module sampleProject; + +// **************************************************************************** +// Include supporting header files +// **************************************************************************** +#include +#include "NewSamplePacketCProject-io.ph" +#include "NewSamplePacketCProject.ph" + +// **************************************************************************** +// +// Main code block +// +// **************************************************************************** +void main($PACKET pkt, $PIB pib, $SYS sys) +{ + // Get ethertype and increment ethertype counter array + EthernetType ethertype; + ethertype = ethernet.type; + ++clEthertype_[ RAW_SHORT(ethertype) ]; + + // Classify packet based on ethertype + switch (ethertype) + { + case ETHERNET_TYPE_IP: + // Get ip4 protocol value and increment protocol array + IpProtocol protocol; + protocol = ipv4.protocol; + ++clIp4Protocol_[ RAW_BYTE(protocol) ]; + + // Classify packet based on protocol + switch (protocol) + { + case IP_PROTOCOL_TCP: + // Increment tcp well know port array, + // Increment element zero if above 1024 + INCREMENT_PORT_STATS( tcp, clTcpWKPort_ ); + break; + + case IP_PROTOCOL_UDP: + // Increment udp well know port array, + // Increment element zero if above 1024 + INCREMENT_PORT_STATS( udp, clUdpWKPort_ ); + break; + + case IP_PROTOCOL_ICMP: + // Increment icmp4 type array, + ++clIcmp4Type_[ icmp.type ]; + break; + + default: + // fall through + } + break; + + case ETHERNET_TYPE_IP6: + // Get ip6 next header value and increment next header array + IpProtocol nextHeader; + nextHeader = ipv6.protocol; + ++clIp6NextHeader_[ RAW_BYTE(nextHeader) ]; + + // Classify packet based on next header + switch (nextHeader) + { + case IP_PROTOCOL_TCP: + // Increment tcp well know port array, + // Increment element zero if above 1024 + INCREMENT_PORT_STATS( tcp, clTcpWKPort_ ); + break; + + case IP_PROTOCOL_UDP: + // Increment udp well know port array, + // Increment element zero if above 1024 + INCREMENT_PORT_STATS( udp, clUdpWKPort_ ); + break; + + case IP_PROTOCOL_IPV6: + // Increment icmp6 type array, + ++clIcmp6Type_[ icmpv6.type ]; + break; + + default: + // fall through + } + break; + + case ETHERNET_TYPE_ARP: + // Get arp opcode value and increment opcode array + ArpOpcode opcode; + opcode = arp.opcode; + ++clArpOpcode_[ RAW_SHORT(opcode) ]; + break; + + default: + // fall through + } + + // Set outport port, + // Set action to FORWARD_PACKET + // Increment IoForward counter + FORWARD_IO( pib, sys ); +} diff --git a/packetC Programming Source/Examples/NewSamplePacketCProject.ph b/packetC Programming Source/Examples/NewSamplePacketCProject.ph new file mode 100644 index 0000000..f731992 --- /dev/null +++ b/packetC Programming Source/Examples/NewSamplePacketCProject.ph @@ -0,0 +1,42 @@ +// **************************************************************************** +// NewSamplePacketCProject.ph - Header file for the Classifier (cl) project. +// ------------ +// Author(s) : Cloudshield Technologies +// Date Created: Sat 09 Sep 2008 04:00:00 PM EDT +// Checked in : $Date: 2011/03/18 13:52:28 $ +// Version : $Revision: 1.5 $ +// **************************************************************************** +#ifndef SAMPLE_PROJECT_CL_PH_ +#define SAMPLE_PROJECT_CL_PH_ + +//declare global event counters +int clEthertype_[ 65536 ] = {0}; +%pragma control clEthertype_ (export); +int clArpOpcode_[ 24 ] = {0}; +%pragma control clArpOpcode_ (export); +int clIp4Protocol_[ 256 ] = {0}; +%pragma control clIp4Protocol_ (export); +int clIp6NextHeader_[ 256 ] = {0}; +%pragma control clIp6NextHeader_ (export); +int clIcmp4Type_[ 256 ] = {0}; +%pragma control clIcmp4Type_ (export); +int clIcmp6Type_[ 256 ] = {0}; +%pragma control clIcmp6Type_ (export); +int clTcpWKPort_[ 1024 ] = {0}; +%pragma control clTcpWKPort_(export); +int clUdpWKPort_[ 1024 ] = {0}; +%pragma control clUdpWKPort_(export); + +// Declare macro +// Increment well known port array, +// Increment element zero if above 1024 +#define INCREMENT_PORT_STATS(data, array)\ + if ( data.sourcePort < 1024 ) {\ + array[ data.sourcePort ]++;\ + }\ + else if ( data.destinationPort < 1024 ) {\ + array[ data.destinationPort ]++;\ + }else array[ 0 ]++; + +#endif /*SAMPLE_PROJECT_CL_PH_*/ + diff --git a/packetC Programming Source/Examples/NibbleArray.ph b/packetC Programming Source/Examples/NibbleArray.ph new file mode 100644 index 0000000..6c2d60d --- /dev/null +++ b/packetC Programming Source/Examples/NibbleArray.ph @@ -0,0 +1,64 @@ +// *************************************************************************** +// nibbleArray.ph +// ------------ +// Author : dW!GhT +// Date Created: 04/28/2011 +// Version : 1.00 +// *************************************************************************** +// This provides macros and routines that will deal with allocating and +// accessing byte global arrays. +// +// :NOTE: For speed no bounds checking is preformed. +// *************************************************************************** +#ifndef NIBBLEARRAY_PH_ +#define NIBBLEARRAY_PH_ + +// =========================================================================== +// The bytes will be held in an int array (32 bits). +// :NOTE: We have to +2 since packetC does not allow arrays of size 1. +// =========================================================================== +#define NIBBLE_ARRAY(BA,SZ) int BA[((SZ)>>2)+2] = { (((SZ)>>2)+2)#0 } + + +// *************************************************************************** +// *************************************************************************** +// Access/Modifiers that act on the storage array +// *************************************************************************** +// *************************************************************************** + +// =========================================================================== +// Sets the byte at the specified position. +// =========================================================================== + +// This works best on a POS that is a constant. +#define SET_NIBBLE_C(BA,POS,VAL) { \ + ((BA)[(POS)>>3] &= ~(0xf<<(((POS)&7)<<2))); \ + ((BA)[(POS)>>3] |= ((VAL&0xf)<<(((POS)&7)<<2))); \ +} + +// This works best on a POS that is a variable. +#define SET_NIBBLE_V(BA,POS,VAL) { \ + int sPos; \ + sPos = (((POS)&7)<<2); \ + int cPos; \ + cPos = (POS)>>2; \ + (BA)[cPos] &= ~(0xf<>3]) >> ((((POS)&7))<<2)) &0xf) + +// =========================================================================== +// Increments the byte at the specified position. +// =========================================================================== +#define INC_NIBBLE(BA,POS) ( ((BA)[(POS)>>3]) += (1<<((((POS)&7))<<2)) ) + +// =========================================================================== +// Decrements the byte at the specified position. +// =========================================================================== +#define DEC_NIBBLE(BA,POS) ( ((BA)[(POS)>>3]) -= (1<<((((POS)&7))<<2)) ) + +#endif /*NIBBLEARRAY_PH_*/ diff --git a/packetC Programming Source/Examples/ShortArray.ph b/packetC Programming Source/Examples/ShortArray.ph new file mode 100644 index 0000000..4769ac0 --- /dev/null +++ b/packetC Programming Source/Examples/ShortArray.ph @@ -0,0 +1,65 @@ +// *************************************************************************** +// shortArray.ph +// ------------ +// Author : dW!GhT +// Date Created: 04/28/2011 +// Version : 1.00 +// *************************************************************************** +// This provides macros and routines that will deal with allocating and +// accessing short global arrays. +// +// :NOTE: For speed no bounds checking is preformed. +// *************************************************************************** +#ifndef SHORTARRAY_PH_ +#define SHORTARRAY_PH_ + +// =========================================================================== +// The bits will be held in an int array (32 bits). +// :NOTE: We have to +2 since packetC does not allow arrays of size 1. +// =========================================================================== +#define SHORT_ARRAY(BA,SZ) int BA[((SZ)>>1)+2] = { (((SZ)>>1)+2)#0 } + + +// *************************************************************************** +// *************************************************************************** +// Access/Modifiers that act on the storage array +// *************************************************************************** +// *************************************************************************** + +// =========================================================================== +// Sets the short at the specified position. +// =========================================================================== + +// This works best on POS that is a constant +// C:C = 2 RAVE instructions +// C:V = 4 RAVE instructions +// V:C = 17 RAVE instructions +// V:V = 18 RAVE instructions +#define SET_SHORT_C(BA,POS,VAL) { \ + ((BA)[(POS)>>1] &= ~(0xffff<<(((POS)&1)<<4))); \ + ((BA)[(POS)>>1] |= (((VAL)&0xffff)<<(((POS)&1)<<4))); \ +} + +// This works best on POS that is a variable. +// C:C = 11 RAVE instructions +// C:V = 10 RAVE instructions +// V:C = 14 RAVE instructions +// V:V = 15 RAVE instructions +#define SET_SHORT_V(BA,POS,VAL) { \ + int sPos; \ + sPos = (((POS)&1)<<4); \ + int cPos; \ + cPos = (POS)>>1; \ + (BA)[cPos] &= ~(0xffff<>1]) >> (((POS)&1)<<4)) ) + +#endif /*SHORTARRAY_PH_*/ diff --git a/packetC Programming Source/Examples/ShortArrayExample.pc b/packetC Programming Source/Examples/ShortArrayExample.pc new file mode 100644 index 0000000..15ac613 --- /dev/null +++ b/packetC Programming Source/Examples/ShortArrayExample.pc @@ -0,0 +1,24 @@ +// *************************************************************************** +// ShortArraySample.pc +// Short sample showing how to use ShortArray.ph +// *************************************************************************** +packet module shortArrayTest; + +// Allocate the short global array +#include "shortArray.ph" +#define SHORTARRAY_SIZE 1024 +SHORT_ARRAY( shortArray, SHORTARRAY_SIZE ); + +void main( $PACKET pkt, $SYS sys, $PIB pib ) { + short shorty; + + // Set a couple of values + SET_SHORT(shortArray, 12, 0xbabe ); + SET_SHORT(shortArray, 13, 0xcafe ); + + // Retrieve a couple of values + shorty = GET_SHORT(shortArray,12); + shorty = GET_SHORT(shortArray,13); + + pib.action = FORWARD_PACKET; +} \ No newline at end of file diff --git a/packetC Programming Source/Examples/Stack.ph b/packetC Programming Source/Examples/Stack.ph new file mode 100644 index 0000000..e843dd0 --- /dev/null +++ b/packetC Programming Source/Examples/Stack.ph @@ -0,0 +1,67 @@ +// ************************************************************************** +// stack.ph +// ------------ +// Author(s) : dW!GhT +// Date Created: 08/04/2011 +// Version : 1.00 +// ************************************************************************** +// Description: packetC implementation of the STL container type stack. +// All methods are define macros so as to make these as fast +// possible. +// +// *************************************************************************** +#ifndef STACK_PH_ +#define STACK_PH_ + +// If STACK_SIZE is not defined we default to 100 elements +#ifndef STACK_MAX_SIZE +#define STACK_MAX_SIZE 100 +#endif + +// Define the stack we are going to use for this. The [0] contains the +// sizing information. +int stack_[STACK_MAX_SIZE] = {0}; + + +// *************************************************************************** +// Test whether container is empty +// Returns whether the stack is empty, i.e. whether its size is 0. +// *************************************************************************** +#define STACK_EMPTY() (stack_[0] == 0) + +// *************************************************************************** +// Remove element +// Removes the element on top of the stack, effectively reducing its size +// by one. The value of this element can be retrieved before being popped +// by calling member stack::top. +// *************************************************************************** +#define STACK_POP() \ + if ( stack_[0] > 0) { \ + --stack_[0]; \ + } + +// *************************************************************************** +// Add element +// Adds a new element at the top of the stack, above its current top element. +// The content of this new element is initialized to a copy of x. +// *************************************************************************** +#define STACK_PUSH(X) \ + if ( stack_[0] < STACK_MAX_SIZE ) { \ + stack_[++stack_[0]] = X; \ + } + +// *************************************************************************** +// Return size +// Returns the number of elements in the stack. +// *************************************************************************** +#define STACK_SIZE() stack_[0] + +// *************************************************************************** +// Access next element +// Returns the next element in the stack. Since stacks are last-in first-out +// containers this is also the last element pushed into the stack. +// *************************************************************************** +#define STACK_TOP() stack_[stack_[0]] + + +#endif /*STACK_PH_*/ diff --git a/packetC Programming Source/Examples/StackSample.pc b/packetC Programming Source/Examples/StackSample.pc new file mode 100644 index 0000000..9e9a5e6 --- /dev/null +++ b/packetC Programming Source/Examples/StackSample.pc @@ -0,0 +1,47 @@ +// ************************************************************************** +// StackSample.pc - Main file for using Stack.ph. +// ------------ +// Author(s) : dW!GhT +// Date Created: 01/11/2012 +// Version : 1.00 +// ************************************************************************** +// Description: This project provides a simple example of how to use Stack.ph. +// +// *************************************************************************** +packet module Sample_Stack; + +// *************************************************************************** +// Include supporting header files +// *************************************************************************** +#include +#include "stack.ph" + +// *************************************************************************** +// Main code block +// *************************************************************************** +void main($PACKET pkt, $PIB pib, $SYS sys) +{ + // Assume we are forwarding all packets + pib.action = FORWARD_PACKET; + + //===== stack Stuff + STACK_PUSH(10); + STACK_PUSH(101); + STACK_PUSH(1011); + + int szStack; + szStack = STACK_SIZE(); + + int x; + x = STACK_TOP(); + STACK_POP(); + STACK_POP(); + STACK_POP(); + STACK_POP(); + + if ( !STACK_EMPTY() ) { + pib.action = DROP_PACKET; + } + +} + diff --git a/packetC Programming Source/Examples/StreamBufferExample.pc b/packetC Programming Source/Examples/StreamBufferExample.pc new file mode 100644 index 0000000..c250edb --- /dev/null +++ b/packetC Programming Source/Examples/StreamBufferExample.pc @@ -0,0 +1,319 @@ +// ************************************************************************** +// StreamBufferSample.pc - +// ------------ +// Author(s) : dW!GhT +// Date Created: 08/01/2011 +// Version : 1.00 +// ************************************************************************** +// Description: This project provides a simple example of how to use the +// streambuffer to assemble a flow and search it. +// +// Based in Streambuffer.csm example included with RAVE. +// +// *************************************************************************** +packet module Sample_StreamBuffer; + +// *************************************************************************** +// Include supporting header files +// *************************************************************************** +#include +#include + +// *************************************************************************** +// :NOTE: This is prototyped here but you will have to supply a hardward +// specific function call to return a timer value. +// *************************************************************************** +int getTimer(); + +// Number of flows to watch over +#define FLOWMGMT_FLOWSIZE 10000 + +// Max size of flows we can assemble +#define SB_STREAMSIZE 65536 + +// Define the maxium size of the streambuffer +#define MAX_STREAMBUFFER_SIZE 1000*1000*390 + +// Global debug exports +int DbgUpdateFailures_ = 0; +%pragma control DbgUpdateFailures_ (export); +int DbgSearchMatches_ = 0; +%pragma control DbgSearchMatches_ (export); +int DbgSearches_ = 0; +%pragma control DbgSearches_ (export); +int DbgSearchOffsets_[100]= { 100 #0 }; +%pragma control DbgSearchOffsets_ (export); +int DbgBufferOverflows_ = 0; +%pragma control DbgBufferOverflows_ (export); +int DbgBadStreamOffsets_ = 0; +%pragma control DbgBadStreamOffsets_ (export); + + +// Array of indices into the streambuffer +int SequenceBase_[ FLOWMGMT_FLOWSIZE ]; +// Array of locks used to access streambuffer +int BufferLock_[ FLOWMGMT_FLOWSIZE ] = {FLOWMGMT_FLOWSIZE #0}; + +// Number of possible ports packets can come in on +// If the output port is set to this, the packet should be dropped. +#define ROUTING_NUM_PORTS 20 +#define ROUTING_IGNORE 255 +int Routing_OutputPorts_[ROUTING_NUM_PORTS] = { 1, 0, 3, 2, 255 }; + +// SearchSet used to search the streambuffer, defined as regex +regex searchset SbSearch[2][11] = { ".*?reserved" }; +%pragma datatype SbSearch (regex1); + +// Structure of database record used to store flow info +struct FlowRec { + int srcIP; + int dstIP; + union Shared { + int full; + struct TcpUdp { + short srcPort; + short dstPort; + } tcpUdp; + struct Icmp { + IcmpType type; + byte code; + } icmp; + } info; + IpProtocol protocol; + byte tcpFlags; + short expireTime; +}; + +// Database that stores the FlowRec info for quick lookups. +database FlowRec flows[FLOWMGMT_FLOWSIZE]; +record FlowRec flowRec; + +// User Created Exceptions +const Exception ERR_BAD_STREAM_OFFSET = ERR_LAST_DEFINED + 1; +const Exception ERR_BUFFER_OVERFLOW = ERR_LAST_DEFINED + 2; +const Exception CLEANING_DATABASE = ERR_LAST_DEFINED + 3; + +// *************************************************************************** +// Background task that will prune the database of flows that have "aged" out. +// +// :NOTE: A replica is floated that is used to drive this process. By +// floating one replica we are effectively doing some load based +// processing in that the replica goes to the end of the packet +// list coming in the box, light load and this gets executed often +// heavy load and it gets executed when it can without effecting +// packet thoughput. +// *************************************************************************** +int LastRowCleaned_ = 0; + +void cleanDatabase() { + // Increament and check to see if we have to loop around to the start + ++LastRowCleaned_; + if ( LastRowCleaned_ >= FLOWMGMT_FLOWSIZE ) { + LastRowCleaned_ = 0; + } + + try { + // See if this row needs to be deleted + if ( flows[LastRowCleaned_].data.expireTime < (short)getTimer() ) { + flows[LastRowCleaned_].delete(); + } + } + catch (ERR_DB_READ) { + // Record not found when trying to delete + } + return; +} + +// This enables background tasking +#define BGTASK_FUNCTION_CALLBACK cleanDatabase() +#include "backgroundTask.ph" + +// *************************************************************************** +// Main code block +// *************************************************************************** +void main($PACKET pkt, $PIB pib, $SYS sys) +{ + try { + // Test to see if we are cleaning the database, + if ( runBackgroundTask() == true ) { + throw CLEANING_DATABASE; + } + + // Assume we are forwarding all packets + pib.action = FORWARD_PACKET; + + // Masks that are used for database searches/insertions + const FlowRec searchMask = { ~0, ~0, {~0}, IP_PROTOCOL_MASK, 0b, 0s }; + const FlowRec insertMask = { ~0, ~0, {~0}, IP_PROTOCOL_MASK, ~0b, ~0s }; + + // Determine the port this is being directed out of + int routing_OutputPort; + routing_OutputPort = Routing_OutputPorts_[sys.inPort]; + + // We only deal with IPV4 flows + if ( ethernet.type == ETHERNET_TYPE_IP ) { + flowRec.srcIP = ipv4.sourceAddress; + flowRec.dstIP = ipv4.destinationAddress; + flowRec.protocol = ipv4.protocol; + + // Zero out these fields + flowRec.info.full = 0; + flowRec.tcpFlags = 0; + flowRec.expireTime = 0; + + // Capture some of the special info on the specific protocols + switch ( ipv4.protocol ) { + case IP_PROTOCOL_ICMP: + flowRec.info.icmp.type = icmp.type; + flowRec.info.icmp.code = icmp.code; + break; + + case IP_PROTOCOL_TCP: + // Capture the tcp flags but mask off the reserved bits + flowRec.tcpFlags = tcp.flags | 0x3f; + break; + + case IP_PROTOCOL_UDP: + flowRec.info.tcpUdp.srcPort = tcp.sourcePort; + break; + + default: + // No special info we need to capture, drop though + } + + // Get the record (flowNum) that this flow is stored in the + // database. If we don't find one then we insert it and init + // the associated sequence array. + int flowNum; + try { + // See if we have this flow in the database already + flowRec.mask = searchMask; + flowNum = flows.match(flowRec); // Throws ERR_DB_NOMATCH + + // Match... update the flow with new expire time + flowRec.mask = insertMask; + flowRec.expireTime = (short)(getTimer() + 5); + flows[flowNum] = flowRec; + } + catch (ERR_DB_NOMATCH) { + // No Match... insert flow into db + // Update the expire time + flowRec.mask = insertMask; + flowRec.expireTime = (short)(getTimer() + 5); + flowNum = flows.insert( flowRec ); // Throws ERR_DB_FULL + + // Init the assigned streambuffer space to all zeros + int sbOffset; + sbOffset = SB_STREAMSIZE * flowNum; + streambuffer[ sbOffset:sbOffset+SB_STREAMSIZE ] #= 0; + SequenceBase_[flowNum] = tcp.sequenceNumber; + } + + // calculate the length of the payload + int payloadLen; + payloadLen = (int)ipv4.totalLength - pib.l3Offset - pib.payloadOffset; + + // If there is no payload data then we do nothing + if ( payloadLen > 0 ) { + // calculate the offset + int flowOffset; + flowOffset = tcp.sequenceNumber - SequenceBase_[flowNum]; + int bufferStart; + bufferStart = flowNum * SB_STREAMSIZE + flowOffset; + + // Ck for overflow on the base + if ( flowOffset > SB_STREAMSIZE ) { + // check for overflow on the copy + if ( flowOffset + payloadLen > SB_STREAMSIZE ) { + payloadLen = SB_STREAMSIZE - flowOffset; + } + + // Ck that we are not overflowing the buffer + if ( bufferStart + payloadLen >= MAX_STREAMBUFFER_SIZE ) { + throw ERR_BAD_STREAM_OFFSET; + } + // Spin-lock till we can reserve the buffer for this flow + while ( !lock( BufferLock_[flowNum] ) ); + + // Copy the payload into its buffer section + streambuffer[bufferStart:bufferStart+payloadLen] = + pkt[pib.payloadOffset:pib.payloadOffset+payloadLen]; + + // Unlock the buffer + unlock( BufferLock_[flowNum] ); + } else { + // ERROR Over flow condition!!! + throw ERR_BUFFER_OVERFLOW; + } + } // if ( payloadLen > 0 ) { + + // + // Check the TCP Flags for FIN. If so then we search the + // assembled packet for the regex we have loaded. + // + if ( flowRec.tcpFlags | 0x1 ) { + // Remove this from the database + flows[flowNum].delete(); + + // Calculate the start/end and check for overflow + int searchAtEnd = false; + int searchStart; + searchStart = flowNum * SB_STREAMSIZE; + int searchEnd; + searchEnd = tcp.sequenceNumber - SequenceBase_[flowNum]; + if ( searchEnd > SB_STREAMSIZE ) { + searchEnd = SB_STREAMSIZE; + } + + // Search till we don't find anything anymore + do { + ++DbgSearches_; + + // Search the buffer. SbSearch.find() throws a ERR_SET_NOTFOUND + // exception when nothing is found, thereby exiting the infinite + // do/while loop. + SearchResult searchResult; + searchResult = SbSearch.find( streambuffer[searchStart:searchEnd] ); + + // Found something, increment the number of matches counter + // and set the starting position to the match + searchStart = searchResult.position; + DbgSearchOffsets_[DbgSearchMatches_++] = searchStart; + } while (true); // forever and ever loop + + } // if ( flowRec.tcpFlags | 0x1 ) { + + } // if ( ethernet.type == ETHERNET_TYPE_IP ) { + + } + + // ========================================================================= + // + // Exception handling routines. + // + // These mostly just handle increamenting stats on the failures of + // critical sections of the code. + // + // ========================================================================= + catch (ERR_DB_FULL) { + ++DbgUpdateFailures_; + } + catch (ERR_BAD_STREAM_OFFSET) { + ++DbgBadStreamOffsets_; + pib.action = DROP_PACKET; + } + catch (ERR_BUFFER_OVERFLOW) { + ++DbgBufferOverflows_; + } + catch (ERR_SET_NOTFOUND) { + // Nothing to do + } + catch (CLEANING_DATABASE) { + // If we are cleaning a database then this was a replica + // so we just drop it. + pib.action = DROP_PACKET; + } + + // FIN. +} + diff --git a/packetC Programming Source/Examples/UdpProcessor.ph b/packetC Programming Source/Examples/UdpProcessor.ph new file mode 100644 index 0000000..d6ad25c --- /dev/null +++ b/packetC Programming Source/Examples/UdpProcessor.ph @@ -0,0 +1,119 @@ +// *************************************************************************** +// UdpProcessor.ph - Include file for the UDP packet processor. +// ------------ +// Author(s) : dW!GhT +// Date Created: 04/01/2011 +// Version : 1.00 +// ************************************************************************** +// Description: Handle responding to a User Command passed in a UDP packet. +// +// This is a simple example that will do the following: +// - increment the udpCounter_ variable by 1. +// - increment the udpCounter_ variable by amount passed. +// - reset the counter to 0. +// - a classic NOP. "; ) +// - "READ_COUNTER" that will send back the UDP with the counter value +// +// :NOTE: Use this as a starting point for your custom command processor. +// +// *************************************************************************** +#ifndef UDPPROCESSOR_PH_ +#define UDPPROCESSOR_PH_ + +// *************************************************************************** +// Commands that this will handle +// *************************************************************************** +enum byte CmdType { + CMDTYPE_NONE = 0, // Nothing/void/null/the loneliness of not + CMDTYPE_RESET_COUNTER = 1, // Resets the global counter to 0 + CMDTYPE_INCREMENT_BY_1 = 2, // Incr the counter by 1 + CMDTYPE_INCREMENT_BY_DATA = 3, // Incr the counter by amount passed + CMDTYPE_READ_COUNTER = 4, // Reads counter and passes back + + CMDTYPE_RESPONSE = 0xfe, // Used to indicate to the reciever + CMDTYPE_NOP = 0xff +}; + +// *************************************************************************** +// The payload of the UDP packet contains the passed data +// *************************************************************************** +descriptor udpDataStruct { + int amountToInc; + CmdType cmdType; // Cmd is here to avoid alignment issues +} udpData at pib.payloadOffset; + + +// *************************************************************************** +// This is the global variable that the commands will act upon +// *************************************************************************** +int udpCounter_ = 0; +%pragma control udpCounter_ (export); + + +// *************************************************************************** +// Helper function to turn the packet around sending a response to the +// caller process. +// *************************************************************************** +void SendResponseBack() { + // Swap source/desc mac addrs + MacAddress tempMacId; + tempMacId = ethernet.destinationAddress; + ethernet.destinationAddress = ethernet.sourceAddress; + ethernet.sourceAddress = tempMacId; + + // Swap source/desc IP addrs + IpAddress tempIpAddr; + tempIpAddr = ipv4.destinationAddress; + ipv4.destinationAddress = ipv4.sourceAddress; + ipv4.sourceAddress = tempIpAddr; + + // We have to recalculate L3/L4 checksums before sending it on its way + pib.flags.l3CheckSumRecalc = true; + pib.flags.l4CheckSumRecalc = true; + + return; +} + +// *************************************************************************** +// HandleUdp will return the CmdType that was processed. +// *************************************************************************** +CmdType HandleUdp() { + // Execute the command passed + switch ( udpData.cmdType ) { + case CMDTYPE_RESET_COUNTER: // Reset the counter to zero + udpCounter_ = 0; + break; + + case CMDTYPE_INCREMENT_BY_1: // Increment the counter by one + ++udpCounter_; + break; + + case CMDTYPE_INCREMENT_BY_DATA: // Used the data passed to inc counter + udpCounter_ += udpData.amountToInc; + break; + + case CMDTYPE_READ_COUNTER: // Pass the counter back to the caller + // Put the counter into the payload + udpData.amountToInc = udpCounter_; + udpData.cmdType = CMDTYPE_RESPONSE; + + // Here we turn the UDP packet around sending it back + SendResponseBack(); + break; + + case CMDTYPE_NOP: // Nothing to do here... "; ) + // NOP means "no operation"... so don't do anything!!! + break; + + default: + // We don't know this command, do nothing + } + + // Return the command type that was processed so the caller can act + // accordingly as to drop or forward the packet. + return udpData.cmdType; +} + + + +#endif /*UDPPROCESSOR_PH_*/ diff --git a/packetC Programming Source/Examples/UserException.pc b/packetC Programming Source/Examples/UserException.pc new file mode 100644 index 0000000..661b029 --- /dev/null +++ b/packetC Programming Source/Examples/UserException.pc @@ -0,0 +1,70 @@ +// ************************************************************************** +// UserException.pc - Main file for demoing UserException throws. +// ------------ +// Author(s) : dWiGhT +// Date Created: 01/18/2012 +// Version : 1.00 +// ************************************************************************** +// Description: This project provides a simple example of how to use User +// Exceptions throw across function scopes. +// *************************************************************************** +packet module User_Exception; + +// *************************************************************************** +// Include supporting header files +// *************************************************************************** +#include + +// *************************************************************************** +// Create a user exception +// *************************************************************************** +const Exception ERR_USER_EXCEPTION = ERR_LAST_DEFINED + 1; + +// *************************************************************************** +// Macros that help throw exceptions over scopes. +// *************************************************************************** +#define CATCH_THROWS(X,Y) \ + if ( X == true ) throw Y + +#define FUNC_THROWS(X,Y,Z) \ +bool X { \ + bool exceptionThrown = false; \ + try Z \ + catch ( Y ) { \ + exceptionThrown = true; \ + } \ + return exceptionThrown; \ +} + +// *************************************************************************** +// This defines a function that just throws an user created exception that +// can be catched by the calling scope. +// *************************************************************************** +FUNC_THROWS( myFunc_ThrowsUserException(), ERR_USER_EXCEPTION, + { + throw ERR_USER_EXCEPTION; + } +) + +// *************************************************************************** +// Main code block +// *************************************************************************** +void main($PACKET pkt, $PIB pib, $SYS sys) +{ + // Wrap this scope with error catching + try { + + // Assume we are forwarding all packets + pib.action = FORWARD_PACKET; + + CATCH_THROWS( myFunc_ThrowsUserException(), ERR_USER_EXCEPTION ); + + // Error handling for main scope + } + catch (ERR_USER_EXCEPTION) { + // do something interesting + pib.action = DROP_PACKET; + } + +} + diff --git a/packetC Programming Source/include/Ascii.ph b/packetC Programming Source/include/Ascii.ph new file mode 100644 index 0000000..3f9c1da --- /dev/null +++ b/packetC Programming Source/include/Ascii.ph @@ -0,0 +1,327 @@ +//============================================================================ +// +// ascii.ph - ASCII character constants for use in packetC. +// +// Provides pre-defined constants for ASCII Character Sets 0-127. +// Enables the rapid access to directly comparing text characters +// in packet to a named character value. +// +// assumptions +// +// All values defined are of type const byte using all UPPERCASE. +// These are simply new definitions for constants. Note that +// many characters are not legal packetC names so all names +// use spelled out descriptions (e.g. SEMICOLON versus ; is +// used.) One exception to style guide is that a lowercase of +// ASCII a-z is provided in two variants (one all UPPERCASE with +// _LC appended and one simply with the letter in lowercase). +// As packetC is case sensitive, ASCII_A and ASCII_a are distinct. +// +// author +// cloudshield.com +// +// version +// $Revision: 1.0 $ +// +// copyright notice +// © 2009-2011 CloudShield Technologies, Inc. +// +//============================================================================ +#ifndef ASCII_PH +#define ASCII_PH +#define _ASCII_PH_VERSION 1.01 + +#define _ASCII_MACROS ENABLED + +//==================- START of ASCII ========================================= + + +const byte ASCII_NUL = 0; +const byte ASCII_SOH = 1; +const byte ASCII_STX = 2; +const byte ASCII_ETX = 3; +const byte ASCII_EOT = 4; +const byte ASCII_ENQ = 5; +const byte ASCII_ACK = 6; +const byte ACSII_BEL = 7; +const byte ACSII_BS = 8; +const byte ACSII_HT = 9; +const byte ACSII_NL = 10; +const byte ACSII_VT = 11; +const byte ACSII_NP = 12; +const byte ACSII_CR = 13; +const byte ACSII_SO = 14; +const byte ACSII_SI = 15; +const byte ACSII_DLE = 16; +const byte ACSII_DC1 = 17; +const byte ACSII_DC2 = 18; +const byte ACSII_DC3 = 19; +const byte ACSII_DC4 = 20; +const byte ACSII_NAK = 21; +const byte ACSII_SYN = 22; +const byte ACSII_ETB = 23; +const byte ASCII_CAN = 24; +const byte ASCII_EM = 25; +const byte ASCII_SUB = 26; +const byte ASCII_ESC = 27; +const byte ASCII_FS = 28; +const byte ASCII_GS = 29; +const byte ASCII_RS = 30; +const byte ASCII_US = 31; +const byte ASCII_SP = 32; +const byte ASCII_SPACE = ' '; +const byte ASCII_EXCLAMATIONPOINT = '!'; +const byte ASCII_BANG = '!'; +const byte ASCII_DBLQUOTE = 34; +const byte ASCII_DOUBLEQUOTE = 34; +const byte ASCII_POUND = '#'; +const byte ASCII_DOLLARSIGN = '$'; +const byte ASCII_PERCENT = '%'; +const byte ASCII_AMPERSAND = '&'; +const byte ASCII_AND = '&'; +const byte ASCII_QUOTE = 39; +const byte ASCII_SINGLEQUOTE = 39; +const byte ASCII_LEFTPARENTHESES = '('; +const byte ASCII_LEFTPAREN = '('; +const byte ASCII_RIGHTPARENTHESES = ')'; +const byte ASCII_RIGHTPAREN = ')'; +const byte ASCII_STAR = '*'; +const byte ASCII_ASTERISK = '*'; +const byte ASCII_PLUS = '+'; +const byte ASCII_PLUSSIGN = '+'; +const byte ASCII_COMMA = ','; +const byte ASCII_MINUS = '-'; +const byte ASCII_DASH = '-'; +const byte ASCII_DOT = '.'; +const byte ASCII_DECIMALPOINT = '.'; +const byte ASCII_SLASH = '/'; +const byte ASCII_FORWARDSLASH = '/'; +const byte ASCII_0 = '0'; +const byte ASCII_1 = '1'; +const byte ASCII_2 = '2'; +const byte ASCII_3 = '3'; +const byte ASCII_4 = '4'; +const byte ASCII_5 = '5'; +const byte ASCII_6 = '6'; +const byte ASCII_7 = '7'; +const byte ASCII_8 = '8'; +const byte ASCII_9 = '9'; +const byte ASCII_COLON = ':'; +const byte ASCII_SEMICOLON = ';'; +const byte ASCII_LESSTHAN = '<'; +const byte ASCII_EQUALS = '='; +const byte ASCII_GREATERTHAN = '>'; +const byte ASCII_QUESTIONMARK = '?'; +const byte ASCII_ATSIGN = '@'; +const byte ASCII_A = 'A'; +const byte ASCII_B = 'B'; +const byte ASCII_C = 'C'; +const byte ASCII_D = 'D'; +const byte ASCII_E = 'E'; +const byte ASCII_F = 'F'; +const byte ASCII_G = 'G'; +const byte ASCII_H = 'H'; +const byte ASCII_I = 'I'; +const byte ASCII_J = 'J'; +const byte ASCII_K = 'K'; +const byte ASCII_L = 'L'; +const byte ASCII_M = 'M'; +const byte ASCII_N = 'N'; +const byte ASCII_O = 'O'; +const byte ASCII_P = 'P'; +const byte ASCII_Q = 'Q'; +const byte ASCII_R = 'R'; +const byte ASCII_S = 'S'; +const byte ASCII_T = 'T'; +const byte ASCII_U = 'U'; +const byte ASCII_V = 'V'; +const byte ASCII_W = 'W'; +const byte ASCII_X = 'X'; +const byte ASCII_Y = 'Y'; +const byte ASCII_Z = 'Z'; +const byte ASCII_LEFTBRACKET = '['; +const byte ASCII_BACKSLASH = '\'; +const byte ASCII_RIGHTBRACKET = ']'; +const byte ASCII_CARAT = '^'; +const byte ASCII_CARROT = '^'; +const byte ASCII_UNDERSCORE = '_'; +const byte ASCII_BACKAPOSTROPHE = '`'; +const byte ASCII_a = 'a'; +const byte ASCII_b = 'b'; +const byte ASCII_c = 'c'; +const byte ASCII_d = 'd'; +const byte ASCII_e = 'e'; +const byte ASCII_f = 'f'; +const byte ASCII_g = 'g'; +const byte ASCII_h = 'h'; +const byte ASCII_i = 'i'; +const byte ASCII_j = 'j'; +const byte ASCII_k = 'k'; +const byte ASCII_l = 'l'; +const byte ASCII_m = 'm'; +const byte ASCII_n = 'n'; +const byte ASCII_o = 'o'; +const byte ASCII_p = 'p'; +const byte ASCII_q = 'q'; +const byte ASCII_r = 'r'; +const byte ASCII_s = 's'; +const byte ASCII_t = 't'; +const byte ASCII_u = 'u'; +const byte ASCII_v = 'v'; +const byte ASCII_w = 'w'; +const byte ASCII_x = 'x'; +const byte ASCII_y = 'y'; +const byte ASCII_z = 'z'; +const byte ASCII_LEFTBRACE = '{'; +const byte ASCII_VERTICALBAR = '|'; +const byte ASCII_OR = '|'; +const byte ASCII_RIGHTBRACE = '}'; +const byte ASCII_TILDE = '~'; +const byte ASCII_DEL = 127; + + +/*==========================================================================*/ +/* */ +/* ASCII Validation Functions and Macros */ +/* */ +/* The following implementation of isascii style macros are based upon the */ +/* lookup table model introduced by J.E. Hendrix in the Small C Compiler */ +/* book. The macros, table and implementations have all been changed, */ +/* however, the methodology bases itself on simplified early C programming */ +/* habits of optimizations in the representation of even the most basic */ +/* algorithms and functions. */ +/* */ +/*==========================================================================*/ + +/* REMOVE #define for _ASCII_MACROS at top for turning these off! */ +#ifdef _ASCII_MACROS + + +#define ASCII_ALNUM 1 +#define ASCII_ALPHA 2 +#define ASCII_CNTRL 4 +#define ASCII_DIGIT 8 +#define ASCII_GRAPH 16 +#define ASCII_LOWER 32 +#define ASCII_PRINT 64 +#define ASCII_PUNCT 128 +#define ASCII_BLANK 256 +#define ASCII_UPPER 512 +#define ASCII_XDIGIT 1024 + +/*==========================================================================*/ +/* */ +/* Each bit position within the table represents a different ASCII type for */ +/* lookup. The input character is used as an index and the #define from */ +/* above is used as a mask to determine if the character matches the type */ +/* of character being checked. The approach is designed to be optimized in */ +/* that everything is a macro not introducing function calls, however, the */ +/* trade-off of the bitwise and, &, operation was used to avoid a unique */ +/* table for each character type, although that would have been one opcode */ +/* faster. While there are only 256 character entries, a int is used to */ +/* represent the bits since there are more than 8 character types. */ +/* */ +/*==========================================================================*/ + +const int ASCII_TABLE[256] = +{ +0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, +0x0004, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0004, 0x0004, +0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, +0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, +0x0140, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, +0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, +0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, +0x0459, 0x0459, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, +0x00D0, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0253, +0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, +0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, +0x0253, 0x0253, 0x0253, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, +0x00D0, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0073, +0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, +0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, +0x0073, 0x0073, 0x0073, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x0004, + +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +#define ISALNUM(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_ALNUM)) /* 'a'-'z', 'A'-'Z', '0'-'9' */ +#define ISALPHA(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_ALPHA)) /* 'a'-'z', 'A'-'Z' */ +#define ISACNTRL(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_CNTRL)) /* 0-31, 127 */ +#define ISDIGIT(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_DIGIT)) /* '0'-'9' */ +#define ISGRAPH(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_GRAPH)) /* '!'-'~' */ +#define ISLOWER(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_LOWER)) /* 'a'-'z' */ +#define ISPRINT(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_PRINT)) /* ' '-'~' */ +#define ISPUNCT(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_PUNCT)) /* !alnum && !cntrl && !space */ +#define ISSPACE(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_BLANK)) /* HT, LF, VT, FF, CR, ' ' */ +#define ISUPPER(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_UPPER)) /* 'A'-'Z' */ +#define ISDIGIT(c) ((bool) (ASCII_TABLE[(byte) c] & ASCII_XDIGIT)) /* '0'-'9', 'a'-'f', 'A'-'F' */ + +/*==========================================================================*/ +/* */ +/* isAscii - Returns Boolean true or false as per cloudshield.ph */ +/* Follows macro function naming for sync with above. */ +/* */ +/*==========================================================================*/ +bool isAscii(byte c) +{ +if (c < 128) + { + return true; + } +else + { + return false; + }; +} + +/*==========================================================================*/ +/* */ +/* atoi - The atoi function takes in a single parameter that is the offset */ +/* into the packet pointing to the *FIRST* digit in the integer */ +/* value. The function will output a single 32-bit local variable */ +/* containing the converted value. */ +/* */ +/* The function will process up to 10 characters and expects that */ +/* the format is well formed and the first non-digit character */ +/* is a termination marker. Commas and other separators will */ +/* terminate processing. The packet will not be modified. */ +/* */ +/*==========================================================================*/ +int atoi( int pktIdx ) +{ + int iRetVal = 0; + int numDigits = 0; + + while ( ++numDigits < 10 && + pkt[pktIdx] <= '9' && pkt[pktIdx] >= '0' ) + { + iRetVal = (iRetVal * 10) + (int)(pkt[pktIdx] - '0'); + ++pktIdx; + } + + return iRetVal; +} + + +#endif /* _ASCII_MACROS */ + + +//===================== END of ASCII ========================================= + +#endif /* ASCII_PH_ */ \ No newline at end of file diff --git a/packetC Programming Source/include/Cloudshield.ph b/packetC Programming Source/include/Cloudshield.ph new file mode 100644 index 0000000..184a5b3 --- /dev/null +++ b/packetC Programming Source/include/Cloudshield.ph @@ -0,0 +1,334 @@ +//============================================================================== +// cloudshield.ph - packetC standard include for CloudShield platforms. +// +// This packetC standard include file defines platform specific structures +// related to intrinsic functionality within the language. In addition, +// structures and data types that are built into the compiler are provided +// in this document as comments to enable programmers to understand and +// validate types. +// +// author +// cloudshield.com +// +// version +// $Revision: 1.10 $ +// +// copyright notice +// © 2009-2011 CloudShield Technologies, Inc. +// +//============================================================================== +#ifndef CLOUDSHIELD_PH +#define CLOUDSHIELD_PH +#define _CLOUDSHIELD_PH_VERSION 1.02 +#define __PACKETC__ TRUE + + +//============================================================================== +// PacketAction Enumerated Type +// +// Used with action in $PIB to define what to do with packet at end of main(). +// +//============================================================================== +// enum int PacketAction +// { +// DROP_PACKET = 0, +// FORWARD_PACKET = 1, +// REQUEUE_PACKET = 2 +// }; + + +//============================================================================== +// Layer Type Enumerations +// +// L2Type, L3Type and L4Type are used by the $PIB to describe current packet. +// +//============================================================================== +// enum int L2Type +// { +// L2TYPE_OTHER = 0, +// L2TYPE_SONET_PPP = 1, +// L2TYPE_SONET_HDLC = 2, +// L2TYPE_SONET_HDLC_PPP_MPLS = 17, +// L2TYPE_SONET_HDLC_MPLS = 18, +// L2TYPE_ETHII = 3, +// L2TYPE_ETHII_MPLS = 19, +// L2TYPE_ETHII_8021Q = 35, +// L2TYPE_ETHII_8021Q_MPLS = 51, +// L2TYPE_802_3_SNAP_MPLS = 21, +// L2TYPE_802_3_SNAP_802_1Q = 37, +// L2TYPE_802_3_SNAP_802_1Q_MPLS = 53, +// L2TYPE_802_3 = 4, +// L2TYPE_802_3_MPLS = 20, +// L2TYPE_802_3_SNAP = 5, +// L2TYPE_802_3_802_1Q = 36 +// }; +// +// enum int L3Type +// { +// L3TYPE_OTHER = 0, +// L3TYPE_IPV4 = 1, +// L3TYPE_IPV6 = 2, +// L3TYPE_ARP = 3, +// L3TYPE_RARP = 4, +// L3TYPE_IPX = 5 +// }; +// +// enum int L4Type +// { +// L4TYPE_OTHER = 0, +// L4TYPE_TCP = 1, +// L4TYPE_UDP = 2, +// L4TYPE_ICMP = 3, +// L4TYPE_ICMPV6 = 4, +// L4TYPE_ESP = 5, +// L4TYPE_AH = 6, +// L4TYPE_GRE = 7, +// L4TYPE_SCTP = 8 +// }; + + +//============================================================================== +// Packet Information Block +// +// The typedef for structure $PIB is instantiated as pib and delivered as a +// parameter to main() containing information about the current packet. +// The pib acts as both an input structure as well as the end state of the pib +// determines actions to be taken against the packet at the end of main(). +// +//============================================================================== +// struct $PIB +// { +// PacketAction action; +// int logAccelTarget; +// int length; +// bits int +// { +// replica : 1; +// l3CheckSumValid : 1; +// l3CheckSumRecalc : 1; +// l4CheckSumValid : 1; +// l4CheckSumRecalc : 1; +// ipv6Fragment : 1; +// ipv4 : 1; +// ipv6 : 1; +// logAccelReplicate : 1; +// logAccelModify : 1; +// logAccelMethod : 1; +// logAccelDatasize : 1; +// mpls : 1; +// vlan : 1; +// FASTDidMatch : 1; +// pad : 17; +// } flags; +// L2Type l2Type; +// L3Type l3Type; +// L4Type l4Type; +// int l2Offset; +// int mplsOffset; +// int l3Offset; +// int l4Offset; +// int payloadOffset; +// int FASTAssocData; +// int FASTModRule; +// int FASTFlowID; +// }; + + +//============================================================================== +// Message Group Levels +// +// The MessageGroup enumerated type is used to set a severity level for a log() +// message. This field can be set once in a context and all future events that +// are generated during the processing of the packet will utilize this value. +// The $SYS structure utilized MessageGroup with field messageGroup. +// +//============================================================================== +// enum int MessageGroup +// { +// MSG_CRITICAL = 1, +// MSG_MAJOR = 2, +// MSG_MINOR = 3, +// MSG_WARNING = 4, +// MSG_INFO = 5 +// }; + + +//============================================================================== +// Message Constants +// +// The following constants provide a maximum message number and length for a +// log() message generated by the packetC system. Use in conjunction with the +// messageId field in $SYS. +// +//============================================================================== +// const int MAX_PACKETC_MSGS = 255; +// const int MAX_PACKETC_MSG_LEN = 80; + +//============================================================================== +// Time Construct Structure +// +// This structure is used to represent the 64-bit fields used in time elements +// of the $SYS structure. For ticks this is the upper and lower 32-bits of a +// 64-bit counter. For UTC Time values, this relates to the seconds (high) and +// microseconds (low) since UTC (1/1/1970) in a single 64-bit structure. +// +// This structure replaced XTime structure from cloudshield.ph version 1.00 +// +//============================================================================== +// struct Time64 { +// int highOrder; +// int lowOrder; +// }; + +//============================================================================== +// System Information +// +// The typedef for structure $SYS is instantiated as sys and delivered as a +// parameter to main() containing information about the current system. +// The system information structure, sys, acts as both a source of information +// about the system the packetC is operating on as well as system level +// that may affect choices in processing. In particular this structure +// data about the physical interface packets were received on an whether this +// is an Ethernet or SONET system. Some attributes may affect the system's +// processing of operations as well as provide real-time information about the +// system that may change during the processing of a packet. +// +// This release (v1.01) of cloudshield.ph introduces UTC time support. Note +// the change of the old xtime(now ticksL in struct time) and time(now ticks). +// +//============================================================================== +// struct $SYS +// { +// int messageId; +// MessageGroup messageGroup; +// int inPort; +// int outPort; +// int context; +// int ticks; +// struct Time64Values { +// Time64 ticksL; +// Time64 utcTime; +// Time64 utcTimeUncorrected; +// Time64 utcTimeDrift; +// } time; +// int bufferCount; +// int queueDepth; +// int logFailures; +// bits int +// { +// sonet : 1; +// pad : 31; +// } flags; +// int requeueCount; +// int tcsFlow; +// int tcsRule; +// int outBlade; +// int inBlade; +// int replicatePort; +// int replicateBlade; +// }; + + +//============================================================================== +// Search Results Structure +// +// When a match or find operator is used on a search set, a structure is then +// returned with the result. This structure is the typedef for that result. +// +//============================================================================== +// struct SearchResult +// { +// int index; +// int position; +// }; + + +//============================================================================== +// Exception Constants +// +// Try catch based exception handlers are core to packetC. There are a set of +// pre-defined exceptions for intrinsic operators to packetC. The section +// of exception constants below are what is implemented in the associated +// packetC compiler. +// +//============================================================================== +// typedef int Exception; +// const Exception ERR_ANY_EXCEPTION = 0; +// const Exception ERR_DB_FULL = 1; +// const Exception ERR_DB_READ = 2; +// const Exception ERR_DB_NOMATCH = 3; +// const Exception ERR_PKT_INSERT = 4; +// const Exception ERR_PKT_DELETE = 5; +// const Exception ERR_PKT_NOREPLICATE = 6; +// const Exception ERR_SET_NOMATCH = 7; +// const Exception ERR_SET_NOPERFORM = 8; +// const Exception ERR_SET_NOTFOUND = 9; +// const Exception ERR_PKT_NOTREQUEUED = 10; + +//============================================================================== +// User Defined Exception Constants +// +// packetC users can create their own exceptions constants to throw by using +// the ERR_LAST_DEFINED constant. +// +// const Exception ERR_MY_EXCEPTION = ERR_LAST_DEFINED + 1 +// +//============================================================================== +// const Exception ERR_LAST_DEFINED = 64; + +//============================================================================== +// Packet Type +// +// Each system may have a slightly different constraint on the buffer for each +// packet. The typedef below defines the $PACKET for the system. +// +//============================================================================== +// typedef byte $PACKET[9 * 1024 - 1]; + + +//============================================================================== +// Truth Constants +// +// In packetC no boolean types exist, however, true and false are pre-defined. +// To enforce consistency and strict type matching, bool is defined. +// +//============================================================================== +// const int true = 1; +// const int false = 0; +typedef int bool; + +//============================================================================== +// Search Set Constants +// +// Null is a valid value in strings and regular expressions. Constants are +// pre-defined for these values. +// +//============================================================================== +// const byte NULL_STOP[1] = "\x00"; +// const byte NULL_REGEX[4] = ".*?\x00"; + +//============================================================================== +// Stream Buffer +// +// Our packetC implementation currently supports the 'buffer' qualifier for a +// single declaration; a predefined byte array, streambuffer[390*1000*1000], +// that provides a large special memory store that is fast, shared across +// application copies and, possibly, volatile. +// +// The stream buffer can be accessed by multiple packet application copies. +// Access is not atomic so the user will have to provide locks to orchestrate +// access to this storage. Stream Buffer contents may be volatile if the user +// does not orchestrate access by multiple application copies. +// +// Variables stored in buffer memory are particularly well suited for network +// processing tasks that require large amounts of contiguous memory to be used +// by cooperating copies of a packet application. For example, buffer storage +// is advantageous for stream reassembly, in which multiple application copies +// assemble the contents of related packets in proper sequence, e.g., so that +// the collective payload can be scanned for items of interest. +// +//============================================================================== +// buffer byte streambuffer[390*1000*1000]; + +#endif + diff --git a/packetC Programming Source/include/Limits.ph b/packetC Programming Source/include/Limits.ph new file mode 100644 index 0000000..0bfc5af --- /dev/null +++ b/packetC Programming Source/include/Limits.ph @@ -0,0 +1,41 @@ +//============================================================================ +// +// limits.ph - packetC limits.h standard library replacement +// +// Provide similar representations to those found in limits.h on different +// platforms. +// +// author +// cloudshield.com +// +// version +// $Revision: 1.1 $ +// +// copyright notice +// © 2009-2011 CloudShield Technologies, Inc. +// +//============================================================================ +#ifndef LIMITS_PH +#define LIMITS_PH +#define _LIMITS_PH_VERSION 1.02 + +//============================================= +//============== BASIC TYPE SIZES ============= +//============================================= + +const int BYTE_BIT = 8 /* Number of bits for a byte */ +const int SHORT_BIT = 16 /* Number of bits for a short */ +const int INT_BIT = 32 /* Number of bits for an int */ +// const int LONG_BIT = 64 /* Number of bits for a long */ + +const int BYTE_MIN = 0 /* Minimum value of a byte */ +const int BYTE_MAX = 255 /* Maximum value of a byte */ +const int SHORT_MIN = 0 /* Minimum value of a short */ +const int SHORT_MAX = 65535 /* Maximum value of a short */ +const int INT_MIN = 0 /* Minimum value of a int */ +const int INT_MAX = 4294967295 /* Maximum value of a int */ +//const int LONG_MIN = 0 /* Minimum value of a int */ +//const int LONG_MAX = 18446744073709551615 /* Maximum value of a long */ + + +#endif /* LIMITS_PH_ */ \ No newline at end of file diff --git a/packetC Programming Source/include/MoreProtocols.ph b/packetC Programming Source/include/MoreProtocols.ph new file mode 100644 index 0000000..548a8f0 --- /dev/null +++ b/packetC Programming Source/include/MoreProtocols.ph @@ -0,0 +1,177 @@ +//============================================================================== +// moreprotocols.ph – Network protocol constants for use with descriptors. +// +// Provide Pre-Defined constants and other definitions for the purpose of +// simplifying of access to bit fields and other interesting combinations. +// +// Definitions will start with PROTO and be followed by the layer information +// such as TCP then a name for the field. +// +// Note that many elements are specified as define statements such that they +// can be used as a constant parameter for 8, 16 and 32 bit functions without +// type checking issues. +// +// author +// cloudshield.com +// +// version +// $Revision: 1.0 $ +// +// copyright notice +// © 2009-2011 CloudShield Technologies, Inc. +// +//============================================================================== +#ifndef MORE_PROTOCOLS_PH +#define MORE_PROTOCOLS_PH +#define _MORE_PROTOCOLS_PH 1.01 + +//====================================== +//======== IP TOS / PRECEDENCE ========= +//====================================== + +// Mask off the Top 3 Bits to Get Precedence +const byte PROTO_IP_PRECEDENCE_MASK = 0xE0; + +// Use the Following as Comparisons against Byte for Top 3 Bits +// Note that Precedence is a Field, Not Bit Settings +const byte PROTO_IP_PRECEDENCE_ROUTINE = 0x00; +const byte PROTO_IP_PRECEDENCE_NORMAL = 0x00; +const byte PROTO_IP_PRECEDENCE_PRIORITY = 0x20; +const byte PROTO_IP_PRECEDENCE_IMMEDIATE = 0x40; +const byte PROTO_IP_PRECEDENCE_FLASH = 0x60; +const byte PROTO_IP_PRECEDENCE_FLASHOVERRIDE = 0x80; +const byte PROTO_IP_PRECEDENCE_CRITICAL = 0xA0; +const byte PROTO_IP_PRECEDENCE_INTERNETWORK = 0xC0; +const byte PROTO_IP_PRECEDENCE_NETWORKCONTROL = 0xE0; +const byte PROTO_IP_PRECEDENCE_NETWORK_CONTROL = 0xE0; + + +// Mask off the Lower 5 Bits to Get TOS Bits Only +const byte PROTO_IP_TOS_MASK = 0x1F; + +// Type of Service Bit Fields +// DELAY - when set to '1' the packet requests low delay. +const byte PROTO_IP_TOS_DELAY = 0x10; + +// Throughout - when set to '1' the packet requests high throughput. +const byte PROTO_IP_TOS_THROUGHPUT = 0x08; + +// Reliability - when set to '1' the packet requests high reliability. +const byte PROTO_IP_TOS_RELIABILITY = 0x04; + +// Cost - when set to '1' the packet has a low cost. +const byte PROTO_IP_TOS_COST = 0x02; + +// MBZ - Checking Bit +const byte PROTO_IP_TOS_MBZ = 0x01; + +//====================================== +//====== IP OPTION FIELD DECODING ====== +//====================================== + +// Copied Flag Bit Specifies Options Relationship to Fragmented Datagrams +// 0 - Option IS NOT copied to each fragmented datagram. +// 1 - Option IS copied to fragmented datagrams. +const byte PROTO_IP_OPTION_FLAG = 0x80; + +// If IP Option Class Field is 2, it is a TimeStamp Packet +const byte PROTO_IP_OPTION_TIMESTAMP = 0x40; +const byte PROTO_IP_OPTION_CLASS_TIMESTAMP = 0x40; + +// Mask off the Class Field +const byte PROTO_IP_OPTION_CLASS_MASK = 0x60; + +// Mask off the Option Number Field +const byte PROTO_IP_OPTION_NUMBER_MASK = 0x1F; + +// The IP Option Number Specifies Format and Usage of IP Options +// Refer to RFCs for Details. Common Numbers are Listed: +// 0 - Indicates End of Option List. If present, No Length or Data Present +// 1 - No Operation, If present, No Length or Data Present +// 2 - Security the length is 11 octets and the various security codes +// can be found in RFC 791. +// 3 - Loose Source Routing +// 4 - Internet Timestamp +// 7 - Record Route +// 8 - Stream ID - Length of 4 Bytes. +// 9 - Strict Source Routing +const byte PROTO_IP_OPTION_NUMBER_END = 0x00; +const byte PROTO_IP_OPTION_END = 0x00; +const byte PROTO_IP_OPTION_NUMBER_NOP = 0x01; +const byte PROTO_IP_OPTION_NOP = 0x01; +const byte PROTO_IP_OPTION_NUMBER_TIMESTAMP = 0x04; + +const byte PROTO_IP_OPTION_NUMBER_RECORDROUTE = 0x07; +const byte PROTO_IP_OPTION_RECORDROUTE = 0x07; + + +//====================================== +//=========== TCP FLAGS ================ +//====================================== + +// Mask Off TCP Flag Bits +const byte PROTO_TCP_FLAGS_MASK = 0x1F; + +// URG - Urgent Pointer Field Significant +const byte PROTO_TCP_FLAGS_URG = 0x20; +const byte PROTO_TCP_URG = 0x20; + +// ACK - Acknowledgment Field Significant +const byte PROTO_TCP_FLAGS_ACK = 0x10; +const byte PROTO_TCP_ACK = 0x10; + +// PSH - Push Function Requested, pass data to application as soon as possible +const byte PROTO_TCP_FLAGS_PSH = 0x08; +const byte PROTO_TCP_PSH = 0x08; +const byte PROTO_TCP_FLAGS_PUSH = 0x08; +const byte PROTO_TCP_PUSH = 0x08; + +// RST - Reset the Connection +const byte PROTO_TCP_FLAGS_RST = 0x04; +const byte PROTO_TCP_RST = 0x04; +const byte PROTO_TCP_FLAGS_RESET = 0x04; +const byte PROTO_TCP_RESET = 0x04; + +// SYN - Syncronize Sequence Numbers +const byte PROTO_TCP_FLAGS_SYN = 0x02; +const byte PROTO_TCP_SYN = 0x02; + +// FIN - No More Data From Sender - Finish Session +const byte PROTO_TCP_FLAGS_FIN = 0x01; +const byte PROTO_TCP_FIN = 0x01; + +//====================================== +//=========== WELL KNOWN PORTS ========= +//====================================== + +const short PROTO_PORT_FTP_DATA = 20; +const short PROTO_PORT_FTP = 21; +const short PROTO_PORT_FTP_CONTROL = 21; +const short PROTO_PORT_SSH = 22; +const short PROTO_PORT_TELNET = 23; +const short PROTO_PORT_SMTP = 25; +const short PROTO_PORT_DNS = 53; +const short PROTO_PORT_BIND = 53; +const short PROTO_PORT_TFTP = 69; +const short PROTO_PORT_WWW = 80; +const short PROTO_PORT_HTTP = 80; +const short PROTO_PORT_POP = 110; +const short PROTO_PORT_POP3 = 110; +const short PROTO_PORT_PORTMAPPER = 111; +const short PROTO_PORT_NNTP = 119; +const short PROTO_PORT_NTP = 123; +const short PROTO_PORT_SNMP = 161; +const short PROTO_PORT_SNMP_TRAP = 162; +const short PROTO_PORT_BGP = 179; +const short PROTO_PORT_IRC = 194; +const short PROTO_PORT_IMAP3 = 220; +const short PROTO_PORT_IMAP = 220; +const short PROTO_PORT_LDAP = 389; +const short PROTO_PORT_HTTPS = 443; +const short PROTO_PORT_DHCP_CLIENT = 546; +const short PROTO_PORT_DHCP_SERVER = 547; +const short PROTO_PORT_NDM_REQUEST = 1363; // Peder's Mark on Well Known Ports! +const short PROTO_PORT_NDM_SERVER = 1364; // Peder's Mark on Well Known Ports! +const short PROTO_PORT_NFS = 2049; + +#endif /* MORE_PROTOCOLS_PH */ \ No newline at end of file diff --git a/packetC Programming Source/include/NamedOperators.ph b/packetC Programming Source/include/NamedOperators.ph new file mode 100644 index 0000000..729d15c --- /dev/null +++ b/packetC Programming Source/include/NamedOperators.ph @@ -0,0 +1,35 @@ +//============================================================================== +// namedoperators.ph – Variation on iso646.h +// +// In C++ named operators can be used instead of their native punctuation +// equivalents. In packetC, these are able to be implemented through the +// use of macros. +// +// author +// cloudshield.com +// +// version +// $Revision: 1.0 $ +// +// copyright notice +// © 2009-2011 CloudShield Technologies, Inc. +// +//============================================================================== +#ifndef NAMED_OPERATORS_PH +#define NAMED_OPERATORS_PH +#define _NAMED_OPERATORS_PH 1.00 + +#define and && +#define and_eq &= +#define bitand & +#define bitor | +#define compl ~ +#define not ! +#define not_eq != +#define or || +#define or_eq |= +#define xor ^ +#define xor_eq ^= + + +#endif \ No newline at end of file diff --git a/packetC Programming Source/include/Protocols.ph b/packetC Programming Source/include/Protocols.ph new file mode 100644 index 0000000..cc5e8f0 --- /dev/null +++ b/packetC Programming Source/include/Protocols.ph @@ -0,0 +1,796 @@ +//============================================================================== +// protocols.ph - packetC standard include for layer 2 through 4 headers. +// +// Fundamental to packetC is the identification and processing of packet +// headers using descriptors to map fields into a named reference model. +// The descriptors in protocols.ph are intended to be a staple that all +// programs share to ensure common naming of layer 2 through 4 header +// fields. +// +// :NOTE: Not all layer 2 through 4 headers and layer 7 protocols are +// included in this file. +// +// author +// cloudshield.com +// +// version +// $Revision: 1.02 $ +// +// copyright notice +// © 2009-2011 CloudShield Technologies, Inc. +// +//============================================================================== +#ifndef PROTOCOLS_PH +#define PROTOCOLS_PH + +// Header file versioning +const int PROTOCOLS_PH_VERSION_ = 1.0.2.0; +%pragma control PROTOCOLS_PH_VERSION_(export); + +// Macros to allow recasting of enumerated fields to access +// and compare them to scalar values. +// :WARNING: You are bypassing type safety at this point. +#define RAW_BYTE(x) (byte)(x) +#define RAW_SHORT(x) (short)(x) +#define RAW_INT(x) (int)(x) + +// Define a type that is used for IP addresses +// in the form of xxx.xxx.xxx.xxx i.e. 192.168.0.101 +typedef int IpAddress; + +// Define a type that is used for MAC addresses +// in the form of xx:xx:xx:xx:xx i.e. 05:32:b1:f3:09 +struct MacAddress +{ + byte b0, b1, b2, b3, b4, b5; +}; + +//============================================================================== +// Ethernet II Descriptor +// +// Most common layer 2 Ethernet header utilized in networks, referred to as +// just Ethernet instead of Ethernet II due to common usage. +// +//============================================================================== +enum short EthernetType { + ETHERNET_TYPE_IP = 0x0800, // IPv4 + ETHERNET_TYPE_ARP = 0x0806, // Address Resolution Protocol + ETHERNET_TYPE_RARP = 0x0835, // Reverse Address Resolution Protocol + ETHERNET_TYPE_APPLETALK = 0x809b, // AppleTalk (Ethertalk) + ETHERNET_TYPE_AARP = 0x80f3, // Appletalk ARP + ETHERNET_TYPE_Novell_IPX = 0x8137, // Novell IPX (alt) + ETHERNET_TYPE_Novell = 0x8138, // Novell + ETHERNET_TYPE_MPLS_UNICAST = 0x8847, // MPLS Unicast + ETHERNET_TYPE_MPLS_MULTICAST = 0x8848, // MPLS Multicast + ETHERNET_TYPE_PPPoE_DISCOVERY = 0x8863, // PPPoE Discovery Stage + ETHERNET_TYPE_PPPoE_SESSION = 0x8864, // PPPoE Session Stage + ETHERNET_TYPE_8021Q = 0x8100, // identifies IEEE 802.1Q tag + ETHERNET_TYPE_8023 = 0x05dc, // <= 1500 (0x05DC) are 802.3 + ETHERNET_TYPE_IP6 = 0x86dd, // IPv6 + ETHERNET_TYPE_CLOUDSHIELD = 0xC5C5, // CloudShield Custom Frames + + ETHERNET_TYPE_MASK = 0x0000, + ETHERNET_TYPE_NOMASK = 0xFFFF +}; + +descriptor EthernetStruct +{ + MacAddress destinationAddress; // MAC Address: i.e. 00:0B:A9:00:00:00 + MacAddress sourceAddress; // .. + EthernetType type; // Compare with ETHERNET_TYPE_xx +} ethernet at pib.l2Offset; + +typedef byte EthernetStructBytes[sizeof(EthernetStruct)]; + +//============================================================================== +// Ethernet II 802.1Q VLAN Descriptors (Single and Double VLAN Tagged) +// +// 802.1Q defines Ethernet headers with LAN segmentation in the layer 2 +// Ethernet header that is also utilized in WAN deployments for aggregation and +// virtual LAN services. VLAN tags are at the end of the standard Ethernet II +// header and are denoted by a type field of 0x8100. Following the last tag +// should be a standard type field containing a value such as 0x0800 to +// describe the encapsulated data. +// +// An 802.1Q frame also contains User Priority information, 8 possible values, +// which are part of 802.1P standards. The VLAN ID will generally be 0 when +// the frame is intended as an 802.1P frame. +// +//============================================================================== +#define ETHERNET8021Q_VLANDID_PRIORITY 0x000 /* vlanId = 0 is 802.1p */ +#define ETHERNET8021Q_VLANDID_RESERVED 0xfff /* vlanId = 4095 reserved */ + +struct VlanTag +{ + EthernetType type; // ETHERNET_TYPE_8021Q = 0x8100 + bits short + { + userPriority : 3; // 802.1p Priority Field + formatIndicator : 1; // Must be 0 for Ethernet + vlanId : 12; // 802.1q VLAN Tag Identification + } tag; +}; + +descriptor Ethernet8021QStruct +{ + MacAddress destinationAddress; // MAC Address: i.e. 00:0B:A9:00:00:00 + MacAddress sourceAddress; // .. + VlanTag vlan; // VLAN tag + EthernetType type; // Type for payload, not ETHERNET_TYPE_8021Q +} ethernet8021Q at pib.l2Offset; + +typedef byte Ethernet8021QStructBytes[sizeof(Ethernet8021QStruct)]; + +descriptor Ethernet8021QQStruct +{ + MacAddress destinationAddress; // MAC Address: i.e. 00:0B:A9:00:00:00 + MacAddress sourceAddress; // .. + VlanTag outerVlan; // Outer VLAN tag + VlanTag innerVlan; // Inner VLAN tag + EthernetType type; // Type for payload, not ETHERNET_TYPE_8021Q +} ethernet8021QQ at pib.l2Offset; + +typedef byte Ethernet8021QQStructBytes[sizeof(Ethernet8021QQStruct)]; + +//============================================================================== +// Ethernet 802.3 Descriptor +// +// Common original layer 2 Ethernet header utilized in networks. The length +// field <= 1500 signifies 802.3 versus a value > 1500 signifies this is the +// type field and is not 802.3 but rather a newer Ethernet II header. +// +//============================================================================== + +descriptor Ethernet8023Struct +{ + MacAddress destinationAddress; // MAC Address: i.e. 00:0B:A9:00:00:00 + MacAddress sourceAddress; // .. + short length; // Must be <= ETHERNET_TYPE_8023 (1500) length. +} ethernet8023 at pib.l2Offset; + +typedef byte Ethernet8023StructBytes[sizeof(Ethernet8023Struct)]; + +//============================================================================== +// Standard IPv4 Descriptor +// +// Most common layer 3 IP header utilized in networks. Descriptions taken +// from RFC 791. +// +//============================================================================== + +enum byte IpProtocol { +// -------------------- +// Common Protocols +// -------------------- + IP_PROTOCOL_ICMP = 0x01, // Internet Control Message Protocol + // RFC 792 + IP_PROTOCOL_IGMP = 0x02, // Internet Group Management Protocol + // RFC 1112 + IP_PROTOCOL_TCP = 0x06, // Transmission Control Protocol + // RFC 793 + IP_PROTOCOL_UDP = 0x11, // User Datagram Protocol + // RFC 768 + IP_PROTOCOL_IPV6 = 0x29, // IPv6 (encapsulation) + // RFC 2473 + IP_PROTOCOL_OSPF = 0x59, // Open Shortest Path First + // RFC 1583 + IP_PROTOCOL_SCTP = 0x84, // Stream Control Transmission Protocol + +// ------------------------ +// Other Known Protocols +// ------------------------ + IP_PROTOCOL_HOPOPT = 0x00, // IPv6 Hop-by-Hop Option RFC 2460 + IP_PROTOCOL_GGP = 0x03, // Gateway-to-Gateway Protocol RFC 823 + IP_PROTOCOL_IP = 0x04, // IP in IP (encapsulation) RFC 2003 + IP_PROTOCOL_ST = 0x05, // Internet Stream Protocol RFC 1190, + // RFC 1819 + IP_PROTOCOL_CBT = 0x07, // Core-based trees RFC 2189 + IP_PROTOCOL_EGP = 0x08, // Exterior Gateway Protocol RFC 888 + IP_PROTOCOL_IGP = 0x09, // Interior Gateway Protocol (any private + // interior gateway (used by Cisco for + // their IGRP)) + IP_PROTOCOL_BBN_RCC_MON = 0x0A, // BBN RCC Monitoring + IP_PROTOCOL_NVP_II = 0x0B, // Network Voice Protocol RFC 741 + IP_PROTOCOL_PUP = 0x0C, // Xerox PUP + IP_PROTOCOL_ARGUS = 0x0D, // ARGUS + IP_PROTOCOL_EMCON = 0x0E, // EMCON + IP_PROTOCOL_XNET = 0x0F, // Cross Net Debugger IEN 158 + IP_PROTOCOL_CHAOS = 0x10, // Chaos + IP_PROTOCOL_MUX = 0x12, // Multiplexing IEN 90 + IP_PROTOCOL_DCN_MEAS = 0x13, // DCN Measurement Subsystems + IP_PROTOCOL_HMP = 0x14, // Host Monitoring Protocol RFC 869 + IP_PROTOCOL_PRM = 0x15, // Packet Radio Measurement + IP_PROTOCOL_XNS_IDP = 0x16, // XEROX NS IDP + IP_PROTOCOL_TRUNK_1 = 0x17, // Trunk-1 + IP_PROTOCOL_TRUNK_2 = 0x18, // Trunk-2 + IP_PROTOCOL_LEAF_1 = 0x19, // Leaf-1 + IP_PROTOCOL_LEAF_2 = 0x1A, // Leaf-2 + IP_PROTOCOL_RDP = 0x1B, // Reliable Datagram Protocol RFC 908 + IP_PROTOCOL_IRTP = 0x1C, // Internet Reliable Transaction Protocol + // RFC 938 + IP_PROTOCOL_ISO_TP4 = 0x1D, // ISO Transport Protocol Class 4 RFC 905 + IP_PROTOCOL_NETBLT = 0x1E, // Bulk Data Transfer Protocol RFC 998 + IP_PROTOCOL_MFE_NSP = 0x1F, // MFE Network Services Protocol + IP_PROTOCOL_MERIT_INP = 0x20, // MERIT Internodal Protocol + IP_PROTOCOL_DCCP = 0x21, // Datagram Congestion Control Protocol + // RFC 4340 + IP_PROTOCOL_3PC = 0x22, // Third Party Connect Protocol + IP_PROTOCOL_IDPR = 0x23, // Inter-Domain Policy Routing Protocol + // RFC 1479 + IP_PROTOCOL_XTP = 0x24, // Xpress Transport Protocol + IP_PROTOCOL_DDP = 0x25, // Datagram Delivery Protocol + IP_PROTOCOL_IDPR_CMTP = 0x26, // IDPR Control Message Transport Protocol + IP_PROTOCOL_TPPP = 0x27, // TP++ Transport Protocol + IP_PROTOCOL_IL = 0x28, // IL Transport Protocol + IP_PROTOCOL_SDRP = 0x2A, // Source Demand Routing Protocol + IP_PROTOCOL_IPV6_ROUTE = 0x2B, // Routing Header for IPv6 RFC 2460 + IP_PROTOCOL_IPV6_FRAG = 0x2C, // Fragment Header for IPv6 RFC 2460 + IP_PROTOCOL_IDRP = 0x2D, // Inter-Domain Routing Protocol + IP_PROTOCOL_RSVP = 0x2E, // Resource Reservation Protocol RFC 2205 + IP_PROTOCOL_GRE = 0x2F, // Generic Routing Encapsulation + IP_PROTOCOL_MHRP = 0x30, // Mobile Host Routing Protocol + IP_PROTOCOL_BNA = 0x31, // BNA + IP_PROTOCOL_ESP = 0x32, // Encapsulating Security Payload RFC 2406 + IP_PROTOCOL_AH = 0x33, // Authentication Header RFC 2402 + IP_PROTOCOL_I_NLSP = 0x34, // Integrated Net Layer Security Protocol + // TUBA + IP_PROTOCOL_SWIPE = 0x35, // SwIPe IP with Encryption + IP_PROTOCOL_NARP = 0x36, // NBMA Address Resolution Protocol + // RFC 1735 + IP_PROTOCOL_MOBILE = 0x37, // IP Mobility (Min Encap) RFC 2004 + IP_PROTOCOL_TLSP = 0x38, // Transport Layer Security Protocol (using + // Kryptonet key management) + IP_PROTOCOL_SKIP = 0x39, // Simple Key-Management for Internet + // Protocol RFC 2356 + IP_PROTOCOL_IPV6_ICMP = 0x3A, // ICMP for IPv6 RFC 4443, RFC 4884 + IP_PROTOCOL_IPV6_NONTX = 0x3B, // No Next Header for IPv6 RFC 2460 + IP_PROTOCOL_IPV6_OPTS = 0x3C, // Destination Options for IPv6 RFC 2460 + IP_PROTOCOL_ANY_HOST_INTERNAL = 0x3D, // Any host internal protocol + IP_PROTOCOL_CFTP = 0x3E, // CFTP + IP_PROTOCOL_ANY_LOCAL_NETWORK = 0x3F, // Any local network + IP_PROTOCOL_SAT_EXPAK = 0x40, // SATNET and Backroom EXPAK + IP_PROTOCOL_KRYPTOLAN = 0x41, // Kryptolan + IP_PROTOCOL_RVD = 0x42, // MIT Remote Virtual Disk Protocol + IP_PROTOCOL_IPPC = 0x43, // Internet Pluribus Packet Core + IP_PROTOCOL_ANY_DISTRIBUTED_FILESYSTEM = 0x44,// Any distributed file system + IP_PROTOCOL_SAT_MON = 0x45, // SATNET Monitoring + IP_PROTOCOL_VISA = 0x46, // VISA Protocol + IP_PROTOCOL_IPCV = 0x47, // Internet Packet Core Utility + IP_PROTOCOL_CPNX = 0x48, // Computer Protocol Network Executive + IP_PROTOCOL_CPHB = 0x49, // Computer Protocol Heart Beat + IP_PROTOCOL_WSN = 0x4A, // Wang Span Network + IP_PROTOCOL_PVP = 0x4B, // Packet Video Protocol + IP_PROTOCOL_BR_SAT_MON = 0x4C, // Backroom SATNET Monitoring + IP_PROTOCOL_SUN_ND = 0x4D, // SUN ND PROTOCOL-Temporary + IP_PROTOCOL_WB_MON = 0x4E, // WIDEBAND Monitoring + IP_PROTOCOL_WB_EXPAK = 0x4F, // WIDEBAND EXPAK + IP_PROTOCOL_ISO_IP = 0x50, // International Organization for + // Standardization Internet Protocol + IP_PROTOCOL_VMTP = 0x51, // Versatile Message Transaction Protocol + // RFC 1045 + IP_PROTOCOL_SECURE_VMTP = 0x52, // Secure Versatile Message Transaction + // Protocol RFC 1045 + IP_PROTOCOL_VINES = 0x53, // VINES + IP_PROTOCOL_TTP = 0x54, // TTP +// IP_PROTOCOL_IPTM = 0x54, // Internet Protocol Traffic Manager + IP_PROTOCOL_NSFNET_IGP = 0x55, // NSFNET-IGP + IP_PROTOCOL_DGP = 0x56, // Dissimilar Gateway Protocol + IP_PROTOCOL_TCF = 0x57, // TCF + IP_PROTOCOL_EIGRP = 0x58, // EIGRP + IP_PROTOCOL_SPRITE_RPC = 0x5A, // Sprite RPC Protocol + IP_PROTOCOL_LARP = 0x5B, // Locus Address Resolution Protocol + IP_PROTOCOL_MTP = 0x5C, // Multicast Transport Protocol + IP_PROTOCOL_AX25 = 0x5D, // AX.25 + IP_PROTOCOL_IPIP = 0x5E, // IP-within-IP Encapsulation Protocol + IP_PROTOCOL_MICP = 0x5F, // Mobile Internetworking Control Protocol + IP_PROTOCOL_SCC_SP = 0x60, // Semaphore Communications Sec. Pro + IP_PROTOCOL_ETHERIP = 0x61, // Ethernet-within-IP Encapsulation RFC 3378 + IP_PROTOCOL_ENCAP = 0x62, // Encapsulation Header RFC 1241 + IP_PROTOCOL_ANY_PRIVATE_ENCRYPTION = 0x63,// Any private encryption scheme + IP_PROTOCOL_GMTP = 0x64, // GMTP + IP_PROTOCOL_IFMP = 0x65, // Ipsilon Flow Management Protocol + IP_PROTOCOL_PNNI = 0x66, // PNNI over IP + IP_PROTOCOL_PIM = 0x67, // Protocol Independent Multicast + IP_PROTOCOL_ARIS = 0x68, // IBM's ARIS (Aggregate Route IP Switching) + IP_PROTOCOL_SCPS = 0x69, // SCPS (Space Communications Protocol + // Standards) + IP_PROTOCOL_QNX = 0x6A, // QNX + IP_PROTOCOL_A_N = 0x6B, // Active Networks + IP_PROTOCOL_IPCOMP = 0x6C, // IP Payload Compression Protocol RFC 3173 + IP_PROTOCOL_SNP = 0x6D, // Sitara Networks Protocol + IP_PROTOCOL_COMPAQ_PEER = 0x6E, // Compaq Peer Protocol + IP_PROTOCOL_IPX_IN_IP = 0x6F, // IPX in IP + IP_PROTOCOL_VRRP = 0x70, // Virtual Router Redundancy Protocol,Common + // Address Redundancy Protocol + // (not IANA assigned) VRRP:RFC 3768 + IP_PROTOCOL_PGM = 0x71, // PGM Reliable Transport Protocol RFC 3208 + IP_PROTOCOL_ANY_0_HOP = 0x72, // Any 0-hop protocol + IP_PROTOCOL_L2TP = 0x73, // Layer Two Tunneling Protocol + IP_PROTOCOL_DDX = 0x74, // D-II Data Exchange (DDX) + IP_PROTOCOL_IATP = 0x75, // Interactive Agent Transfer Protocol + IP_PROTOCOL_STP = 0x76, // Schedule Transfer Protocol + IP_PROTOCOL_SRP = 0x77, // SpectraLink Radio Protocol + IP_PROTOCOL_UTI = 0x78, // UTI + IP_PROTOCOL_SMP = 0x79, // Simple Message Protocol + IP_PROTOCOL_SM = 0x7A, // SM + IP_PROTOCOL_PTP = 0x7B, // Performance Transparency Protocol + IP_PROTOCOL_IS_IS = 0x7C, // IS-IS over IPv4 + IP_PROTOCOL_FIRE = 0x7D, // + IP_PROTOCOL_CRTP = 0x7E, // Combat Radio Transport Protocol + IP_PROTOCOL_CRUDP = 0x7F, // Combat Radio User Datagram + IP_PROTOCOL_SSCOPMCE = 0x80, + IP_PROTOCOL_IPLT = 0x81, + IP_PROTOCOL_SPS = 0x82, // Secure Packet Shield + IP_PROTOCOL_PIPE = 0x83, // Private IP Encapsulation within IP + // Expired I-D draft-petri-mobileip-pipe-00.txt + IP_PROTOCOL_FC = 0x85, // Fibre Channel + IP_PROTOCOL_RSVP_E2E_IGNORE = 0x86, // RFC 3175 + IP_PROTOCOL_MOBILITY_HEADER = 0x87, // RFC 3775 + IP_PROTOCOL_UDP_LITE = 0x88, // RFC 3828 + IP_PROTOCOL_MPLS_IN_IP = 0x89, // RFC 4023 + IP_PROTOCOL_MANET = 0x8A, // MANET Protocols RFC 5498 + IP_PROTOCOL_HIP = 0x8B, // Host Identity Protocol RFC 5201 + IP_PROTOCOL_SHIM6 = 0x8C, // Site Multihoming by IPv6 Intermediation + +// :HACK: :NOTE: packetC does not allow duplicate enums +// IP_PROTOCOL_NOMASK = 0x00, +#define IP_PROTOCOL_NOMASK IP_PROTOCOL_HOPOPT + IP_PROTOCOL_MASK = 0xFF +}; + +// These are used for the tos.precedence field. We #define'd these +// because there is no way to enum a bit field currently. +#define IPV_PRECEDENCE_NETWORK_CONTROL 0b111 +#define IPV_PRECEDENCE_INTERNETWORK_CONTROL 0b110 +#define IPV_PRECEDENCE_CRITIC_ECP 0b101 +#define IPV_PRECEDENCE_FLASH_OVERRIDE 0b100 +#define IPV_PRECEDENCE_FLASH 0b011 +#define IPV_PRECEDENCE_IMMEDIATE 0b010 +#define IPV_PRECEDENCE_PRIORITY 0b001 +#define IPV_PRECEDENCE_ROUTINE 0b000 + +descriptor Ipv4Struct +{ + bits byte + { + version : 4; // Specifies the format of the IP packet header. + headerLength : 4; // Specifies the length of the IP packet header in + // 32 bit words, minimum for a valid header is 5. + } bf; // No official name for byte, using bf for bit field. + + bits byte + { + precedence : 3; // Indicate the importance of a datagram, see + // IPV_PRECEDENCE_xxxxx values + delay : 1; // Requests low delay + throughput : 1; // Requests high throughput + reliability : 1; // Requests high reliability + reserved : 2; // Not Used + } tos; // Type of Service RFC791 + + short totalLength; // Contains the length of the datagram. + short identification; // Used to identify the fragments of one datagram + // from those of another. + + bits short + { + evil : 1; // Reserved field renamed Evil Bit in RFC 3514 + dont : 1; // Don't Fragment + more : 1; // More Fragments + fragmentOffset :13; // Fragment Offset (Offset is a reserved word) + } fragment; + + byte ttl; // Time to live + IpProtocol protocol; // See IP_PROTOCOL_xxxx above + short checksum; // Checksum of IPv4 header + IpAddress sourceAddress; // Source IP address + IpAddress destinationAddress; // Destination IP address +} ipv4 at pib.l3Offset; // Optional data follows as IP Options + +typedef byte Ipv4StructBytes[sizeof(Ipv4Struct)]; + +//============================================================================== +// Standard IPv6 Descriptor +// +// Standard form for layer 3 IPv6 header based upon RFC 1883 and 2460 with +// Flow Label based upon RFC 1809. +// +//============================================================================== + +// IPv6 addresses have two logical parts: a 64-bit network prefix, +// and a 64-bit host address part. An IPv6 address is represented +// by 8 groups of 16-bit hexadecimal values separated by colons (:) +// shown as follows: +// 2001:0db8:85a3:0000:0000:8a2e:0370:7334 +// +struct Ipv6Address +{ +// int quad0, quad1, quad2, quad3; + short net0; // Network prefix + short net1; // : + short net2; // : + short net3; // : + short host0; // Host address + short host1; // : + short host2; // : + short host3; // : +}; + +descriptor Ipv6Struct +{ + bits int + { + version : 4; // IPv6 version number + trafficClass : 8; // Internet traffic priority delivery value. + flowLabel :20; // From 1 to 0xFFFFFF, Used Instead of Inspection. + } bf; // Following Naming of Bit Field from IPv4. + + short payloadLength; // Length of Payload + Extensions (Not Header) + + IpProtocol protocol; // Same as IPv4 Protocol, plus IPv6 Next Header + byte hopLimit; // For each router that forwards the packet, the + // hop limit is decremented by 1. When the hop + // limit field reaches zero, the packet is discarded. + + Ipv6Address sourceAddress; // The IPv6 address of the sending node. + Ipv6Address destinationAddress; // The IPv6 address of the destination node. + +} ipv6 at pib.l3Offset; // IPv6 Uses Nested Headers Versus Options + +typedef byte Ipv6StructBytes[sizeof(Ipv6Struct)]; + +//============================================================================== +// Standard TCP Descriptor +// +// A common layer 4 TCP header utilized in networks per RFC 793. TCP Options +// are varied and differ in size based upon the option header type as each may +// differ in size, often from 1 to 4 bytes. As there are trailers to the TCP +// header, these can be developed as descriptors that sit at location +// pib.l4Offset+20 or if nested change 20 as appropriate based upon a runtime +// variable. +// +//============================================================================== + +descriptor TcpStruct +{ + short sourcePort; // Identifies the sending port + short destinationPort; // Identifies the recieving port + int sequenceNumber; // Sequence Number + int acknowledgementNumber; // If the ACK flag is set then the value of + // this field is the next sequence number that + // the receiver is expecting. + + bits byte + { + length :4; // # of 32-bit words in TCP Header, including Options + reserved :4; + } header; + + bits byte + { + cwr:1; // Congestion window reduced per RFC 3168 + ece:1; // ECN-Echo per RFC 3168 + urg:1; // Urgent + ack:1; // Acknowledgement + psh:1; // Push + rst:1; // Reset + syn:1; // Synchronize + fin:1; // Finish + } flags; + + short windowSize; // The size of the receive window + short checksum; // Used for error-checking of the header and data + short urgentPointer; // If the URG flag is set, then this is an offset from + // the sequence number indicating the last urgent byte + +} tcp at pib.l4Offset; + +typedef byte TcpStructBytes[sizeof(TcpStruct)]; + +//============================================================================== +// Standard UDP Descriptor +// +// A common layer 4 UDP header utilized in networks per RFC 768. +// +//============================================================================== + +descriptor UdpStruct +{ + short sourcePort; // The port number of the sender. Cleared to zero + // if not used. + short destinationPort; // The port this packet is addressed to. + short length; // The length in bytes of the UDP header and the + // encapsulated data. The minimum value is 8. + short checksum; // Checksum that covers the UDP message. +} udp at pib.l4Offset; + +typedef byte UdpStructBytes[sizeof(UdpStruct)]; + +//============================================================================== +// Standard ICMP version 4 Descriptor +// +// A common layer 4 ICMP header for IPv4 utilized in networks. The data portion +// of an ICMP packet immediately follows this header and is specific to the +// variety of ICMP Code and Type. Additional varieties are provided as +// well to support the common Echo Request, Echo Reply, Redirect and +// Unreachable types. +// Reference based upon RFC 950. +// +//============================================================================== + +// Used in icmp.type field +enum byte IcmpType { + ICMP_TYPE_ECHO_RESPONSE = 0x00, // See structure IcmpEchoStruct + ICMP_TYPE_DESTINATION_UNREACHABLE = 0x03, // See structure IcmpUnreachableStruct + ICMP_TYPE_SOURCE_QUENCH = 0x04, + ICMP_TYPE_REDIRECT_MESSAGE = 0x05, // Set structure IcmpRedirectStruct + ICMP_TYPE_ECHO_REQUEST = 0x08, + ICMP_TYPE_ROUTER_ADVERTISEMENT = 0x09, + ICMP_TYPE_ROUTER_SOLICITATION = 0x0a, + ICMP_TYPE_TIME_EXCEEDED = 0x0b, + ICMP_TYPE_PARAMETER_PROBLEM = 0x0c, + ICMP_TYPE_TIMESTAMP = 0x0d, + ICMP_TYPE_TIMESTAMP_REPLY = 0x0e, + ICMP_TYPE_INFORMATION_REQUEST = 0x0f, + ICMP_TYPE_INFORMATION_REPLY = 0x10, + ICMP_TYPE_ADDRESS_MASK_REQUEST = 0x11, + ICMP_TYPE_ADDRESS_MASK_REPLY = 0x12, + ICMP_TYPE_TRACEROUTE = 0x1e, + +// :HACK: :NOTE: packetC does not allow duplicate enums +// ICMP_TYPE_MASK = 0x00, +#define ICMP_TYPE_MASK ICMP_TYPE_ECHO_RESPONSE + ICMP_TYPE_NOMASK = 0xff +}; + +descriptor IcmpStruct +{ + IcmpType type; // Specifies the format of the ICMP message. + byte code; // Further qualifies the ICMP message. + short checksum; // Checksum that covers the ICMP message. +} icmp at pib.l4Offset; + +typedef byte IcmpStructBytes[sizeof(IcmpStruct)]; + +// ICMP Echo Reply structure +descriptor IcmpEchoStruct +{ + IcmpType type; // Must be ICMP_TYPE_ECHO_RESPONSE or REQUEST + byte code; // Must be 0 for Echo + short checksum; // Checksum that covers the ICMP message. + short identifier; // Can be used to help match echo requests to the + // associated reply. It may be cleared to zero. + short sequence; // Used to help match echo requests to the + // associated reply. It may be cleared to zero. +} icmpEcho at pib.l4Offset; // Optional data follows + +typedef byte IcmpEchoStructBytes[sizeof(IcmpEchoStruct)]; + +// ICMP Destination Unreachable structure +enum byte IcmpUnreachableCode { + ICMP_CODE_NETWORK_UNREACHABLE = 0x00,// Network Unreachable + ICMP_CODE_HOST_UNREACHABLE = 0x01,// Host Unreachable + ICMP_CODE_PROTOCOL_UNREACHABLE = 0x02,// Protocol unreachable error, + // designated transport protocol + // is not supported. + ICMP_CODE_PORT_UNREACHABLE = 0x03,// Port unreachable error, + // designated protocol is unable + // to inform the host of the + // incoming message. + ICMP_CODE_FRAGMENT_DONTFRAGMENT = 0x04,// The datagram is too big. + // Packet fragmentation is required + // but the 'don't fragment' (DF) + // flag is on. + ICMP_CODE_SOURCE_ROUTE_FAILED = 0x05,// Source route failed error. + ICMP_CODE_DESTINATION_NETWORK_UNKNOWN =0x06,// Destination network unknown error. + ICMP_CODE_DESTINATION_HOST_UNKNOWN = 0x07,// Destination host unknown error. + ICMP_CODE_SOURCE_HOST_ISOLATED = 0x08,// Source host isolated error + // (military use only). + ICMP_CODE_NETWORK_ACCESS_PROHIBITED = 0x09,// The destination network is + // administratively prohibited. + ICMP_CODE_HOST_ACCESS_PROHIBITED = 0x0a,// The destination host is + // administratively prohibited. + ICMP_CODE_NETWORK_UNREACHABLE_FOR_TOS =0x0b,// The network is unreachable for + // Type Of Service. + ICMP_CODE_HOST_UNREACHABLE_FOR_TOS = 0x0c,// The host is unreachable for + // Type Of Service. + ICMP_CODE_ADMINISTRATIVELY_PROHIBITED =0x0d,// Communication administratively + // prohibited (administrative + // filtering prevents packet from + // being forwarded). + ICMP_CODE_HOST_PRECEDENCE_VIOLATION = 0x0e,// Host precedence violation + // (indicates the requested precedence + // is not permitted for the combination + // of host or network and port). + ICMP_CODE_PRECEDENCE_CUTOFF_IN_EFFECT =0x0f,// Precedence cutoff in effect + // (precedence of datagram is below + // the level set by the network + // administrators). + +// :HACK: :NOTE: packetC does not allow duplicate enums +// ICMP_CODE_MASK = 0x00, +#define ICMP_CODE_MASK ICMP_CODE_NETWORK_UNREACHABLE + ICMP_CODE_NOMASK = 0xff +}; + +descriptor IcmpUnreachableStruct +{ + IcmpType type; // Must be ICMP_TYPE_DESTINATION_UNREACHABLE + IcmpUnreachableCode code; // Refer to ICMP_CODE_ Values + short checksum; // Checksum that covers the ICMP message. + int unused; // Must be 0 +// :TODO: Extend ICMP Unreachable To Include Structured Data Portion +//IpHeader ipHeader; // IP Header Enclosed +//byte datagram[8]; // First 64-bits of Failing Datagram. +} icmpUnreachable at pib.l4Offset; + +typedef byte IcmpUnreachableStructBytes[sizeof(IcmpUnreachableStruct)]; + +// ICMP Redirect Message structure +enum byte IcmpRedirectCode { + ICMP_CODE_REDIRECT_NETWORK_ERROR = 0x00, + ICMP_CODE_REDIRECT_HOST_ERROR = 0x01, + ICMP_CODE_REDIRECT_SERVICE_AND_NETWORK_ERROR = 0x02, + ICMP_CODE_REDIRECT_SERVICE_AND_HOST_ERROR = 0x03, + +// :NOTE: packetC does not allow duplicate enums +// ICMP_CODE_MASK = 0x00, +#define ICMP_CODE_REDIRECT_MASK ICMP_CODE_REDIRECT_NETWORK_ERROR + ICMP_CODE_REDIRECT_NOMASK = 0xff +}; + +descriptor IcmpRedirectStruct +{ + IcmpType type; // Must be ICMP_TYPE_REDIRECT_MESSAGE + IcmpRedirectCode code; // Refer to ICMP_CODE_REDIRECT_xxx Values + short checksum; // Checksum that covers the ICMP message. + IpAddress destinationAddress; // IP address to redirect to +} icmpRedirect at pib.l4Offset; + +typedef byte IcmpRedirectStructBytes[sizeof(IcmpRedirectStruct)]; + + +//============================================================================== +// Standard ICMP version 6 Descriptor +// +// IPv6 introduces many new values for fields in ICMP, however, generally it +// follows the ICMP formats from IPv4. The icmp descriptor above applies to +// IPv6 with only the change of code to length. +// +// In IPv6, a type value of 0 through 127 is associated with errors. As such, +// ICMP Echo Request and Response is moved to 128 and 129, respectively. +// +//============================================================================== +enum byte Icmpv6Type { + // ICMPv6 Errors messages + ICMPV6_TYPE_DESTINATION_UNREACHABLE = 0x01, + ICMPV6_TYPE_PACKET_TOO_BIG = 0x02, + ICMPV6_TYPE_TIME_EXCEEDED = 0x03, + ICMPV6_TYPE_PARAMETER_PROBLEM = 0x04, + // 0x79 Reserved for expansion of ICMPv6 error messages + + // ICMPv6 Information messages + ICMPV6_TYPE_REQUEST = 0x80, // See structure Icmpv6EchoStruct + ICMPV6_TYPE_RESPONSE = 0x81, // See structure Icmpv6EchoStruct + + ICMPV6_TYPE_ROUTER_SOLICITATION = 0x85, + ICMPV6_TYPE_ROUTER_ADVERTISEMENT = 0x86, + ICMPV6_TYPE_NEIGHBOR_SOLICITATION = 0x87, + ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT = 0x88, + ICMPV6_TYPE_MULTICAST_ADVERTISEMENT = 0x97, + ICMPV6_TYPE_MULTICAST_SOLICITATION = 0x98, + ICMPV6_TYPE_MULTICAST_TERMINATION = 0x99, + // 0xff Reserved for expansion of ICMPv6 informational messages + + ICMPV6_TYPE_MASK = 0x00, + ICMPV6_TYPE_NOMASK = 0xff +}; + +descriptor Icmpv6Struct // Length Field Difference From IPv4 +{ + Icmpv6Type type; // ICMPv6 msg type + byte length; // Length + short checksum; // Header checksum +} icmpv6 at pib.l4Offset; + +typedef byte Icmpv6StructBytes[sizeof(Icmpv6Struct)]; + +descriptor Icmpv6EchoStruct // Matches IPv4, Field Values Differ. +{ + Icmpv6Type type; // Must be ICMPV6_TYPE_REQUEST or RESPONSE + byte code; // Must be 0 for Echo + short checksum; // Header checksum + short identifier; // Can be used to help match echo requests to the + // associated reply. It may be cleared to zero. + short sequence; // Used to help match echo requests to the + // associated reply. It may be cleared to zero. +} icmpv6Echo at pib.l4Offset; // Optional data follows + +typedef byte Icmpv6EchoStructBytes[sizeof(Icmpv6EchoStruct)]; + +//============================================================================== +// Standard ARP Descriptor +// +// The following ARP descriptor is for IPv4 protocol addresses over Ethernet. +// While fields remain the same for other varieties, lengths of fields change +// when address sizes change an a separate descriptor would be necessary for +// non-Ethernet or non-IPv4 protocol addresses. +// +//============================================================================== + +// :KLUDGE: +// The IP addresses (sourceProtocolAddress and destinationProtocolAddress) +// are not int aligned so we have to cheat to get access to these in the +// ArpStruct by using a 4-byte structure to define them. +// +// The user will have to typecast this field to an IpAddress +// type to get access to the full field. +// +// IpAddress myIpAddr; +// myIpAddr = (IpAddress)arp.destinationProtocolAddress; +// +// The same goes for changing either one of these fields. +// +// arp.sourceProtocolAddress = (IpQuad)10.10.4.211; +// + +struct IpQuads +{ + byte quad0; + byte quad1; + byte quad2; + byte quad3; +}; + +enum short ArpOpcode { + ARP_OPCODE_REQUEST = 0x0001, + ARP_OPCODE_REPLY = 0x0002, + + ARP_OPCODE_MASK = 0x0000, + ARP_OPCODE_NOMASK = 0xffff +}; + +descriptor ArpStruct +{ + short hardwareType; // Specifies the Link Layer protocol + // type. Ethernet is 1. + EthernetType protocolType; // Specifies the upper layer + // protocol for which the ARP request + // is intended. IPv4 is 0x0800 + // matching Ethernet. + byte hardwareAddressLength; // Length of a hardware address. + // Ethernet addresses size is 6. + byte protocolAddressLength; // Length of addresses used in the + // upper layer protocol. IPv4 is 4. + ArpOpcode opcode; // See ARP_OPCODE_xxxx codes + MacAddress sourceHardwareAddress; // Hardware (MAC) address of the sender + IpQuads sourceProtocolAddress; // Upper layer protocol addr of the sender + MacAddress destinationHardwareAddress; // Hardware address of the intended receiver. + // This field is ignored in requests. + IpQuads destinationProtocolAddress; // Upper layer protocol address of + // the intended receiver. +} arp at pib.l3Offset; + +typedef byte ArpStructBytes[sizeof(ArpStruct)]; + + +#endif /* PROTOCOLS_PH_ */ + + + + + + + + + + + + + + + + + + + diff --git a/packetC Programming Source/include/SortedList.ph b/packetC Programming Source/include/SortedList.ph new file mode 100644 index 0000000..4bac951 --- /dev/null +++ b/packetC Programming Source/include/SortedList.ph @@ -0,0 +1,333 @@ +// *************************************************************************** +// SortedList.ph -- provides a fast sorted list. +// ------------ +// Author : dWiGhT +// Date Created: 04/28/2011 +// Version : 1.00 +// ------------ +// +// This provides routines that will create a sorted list without the +// overhead of data movement associated with sorting, inserting, and deleting. +// +// A two dimensional array is used as a sort of singly linked list. Entries +// are inserted at the end and their "next node" set appropriately to +// keep the list sorted. This saves having to move any data around for +// insertions or deletions. Deletions are reused by tracking them in a +// stack that gets +// +// Iterators are provided to transverse the list in a sorted order and +// should be the only way to access the list. +// +// *************************************************************************** +#ifndef SORTEDLIST_PH_ +#define SORTEDLIST_PH_ + +// *************************************************************************** +// Define the 2D array that makes up the list. If the size is not specified +// we default to 0x7fff as the size. +// *************************************************************************** +#ifndef MAX_LIST_SIZE +#define MAX_LIST_SIZE 0x7fff +#endif +int Node_[MAX_LIST_SIZE][2] = {{0xffffffff,0}}; // Init with END-NODE +const int NODE_VALUE = 0; // Col 0 is the value stored in the list +const int NEXT_NODE = 1; // Col 1 is the index/link to the next node + +// Stack used to recover deleted nodes saves having to compact the list. +// [0] stores the number of elements in the stack. 10% of the list size. +int OpenSlots_[MAX_LIST_SIZE/10]; + +// *************************************************************************** +// The HeadNode is the lowest value in the list. +// NumNodes is the current number of nodes in the list and the insertion idx. +// *************************************************************************** +int NumNodes_ = 0; +int HeadNode_ = 0; + +// *************************************************************************** +// List iterators used to iterate through the list in a sorted fashion. +// +// NOTE: +// you should only use iterators to correctly transverse a list +// which will be returned in accending order. +// *************************************************************************** +typedef const int ListIterator; + +// *************************************************************************** +// Test the ListIterator against LIST_END to determine if at the end +// of the list. +// *************************************************************************** +const ListIterator LIST_END = 0; + +// *************************************************************************** +// Returns an iterator that points to the start of the list +// *************************************************************************** +ListIterator listCreateIterator() { + return (ListIterator)HeadNode_; +} + +// Fast inlined version +#define LIST_CREATE_ITERATOR() (ListIterator)HeadNode_ + +// *************************************************************************** +// Returns the value stored at the current iterator +// *************************************************************************** +int listGetValue( ListIterator iter ) { + return Node_[iter][NODE_VALUE]; +} + +// Fast inlined version +#define LIST_GET_VALUE(ITER) Node_[ITER][NODE_VALUE] + +// *************************************************************************** +// Returns the next position after this node +// *************************************************************************** +ListIterator listIncIterator( ListIterator iter ) { + return Node_[iter][NEXT_NODE]; +} + +// Fast inlined version +#define LIST_INC_ITERATOR(ITER) Node_[ITER][NEXT_NODE] + +// *************************************************************************** +// Delete all the nodes in the list. This effectively just resets pointers +// that are tracked. The end-node is the only node that is overwritten. +// *************************************************************************** +void listInit() { + // Simplily set the number of nodes to zero + NumNodes_ = 0; + + // Point headNode to the END-NODE of the list + HeadNode_ = 0; + Node_[0][NODE_VALUE] = 0xffffffff; + Node_[0][NEXT_NODE] = 0; + + // Clear out the open slots list + OpenSlots_[0] = 0; + + return; +} + +// Fast inlined version +#define LIST_INIT() \ +{ \ + NumNodes_ = 0; \ + HeadNode_ = 0; \ + Node_[0][NODE_VALUE] = 0xffffffff; \ + Node_[0][NEXT_NODE] = 0; \ + OpenSlots_[0] = 0; \ +} + + +// *************************************************************************** +// Inserts the value into the list so that the list stays sorted. No +// duplicates are entered in the list. Returns an booleen indicating +// if the item was inserted, right now the only error that can occur is +// a full table condition. +// +// :HACK: Note the use of several exit points (return;) within this code. +// This reduces the amount of code that is executed within the +// special case scenarios and avoids a numerious comparisons. +// *************************************************************************** +bool listInsert( int value ) { + if ( NumNodes_ + 1 == MAX_LIST_SIZE ) + if ( OpenSlots_[0] == 0 ) { + // We don't have anymore room to add a value + return false; + } + + // See if we have some open slots to use from previous deletes, + // use this node then, otherwise use one of the new ones. + int newSlot; + if ( OpenSlots_[0] > 0 ) { + // Reuse one of the open slots + newSlot = OpenSlots_[OpenSlots_[0]--]; + } else { + // Use a new slot at the end of the list + newSlot = ++NumNodes_; + } + + // Special case if we insert before the head + if ( Node_[HeadNode_][NODE_VALUE] > value ) { + // Add the node and repoint the head to it + Node_[newSlot][NEXT_NODE] = HeadNode_; + Node_[newSlot][NODE_VALUE] = value; + HeadNode_ = newSlot; + return true; + } + + // Find out where to insert this value + int nodeValue; + int nextNode; + int testNode; + testNode = HeadNode_; + + ListIterator iter; + iter = LIST_CREATE_ITERATOR(); + while ( iter != LIST_END ) { + + nodeValue = Node_[testNode][NODE_VALUE]; + if ( nodeValue == value ) { + // The value is already in our list so we ditch without adding + + // We have to recover the node back into the stack if we are + // not going to use it + if ( newSlot != NumNodes_ ) { + OpenSlots_[++OpenSlots_[0]] = newSlot; + } else { + --NumNodes_; + } + return true; + } + + nextNode = Node_[testNode][NEXT_NODE]; + + // Test if we should insert this here + nodeValue = Node_[nextNode][NODE_VALUE]; + if ( nodeValue > value ) { + // Kick out to insert the node here + break; + } + + // Move on to the next node to test + testNode = nextNode; + } + + // Insert this node at the correct position + Node_[newSlot][NEXT_NODE] = Node_[testNode][NEXT_NODE]; + Node_[newSlot][NODE_VALUE] = value; + Node_[testNode][NEXT_NODE] = newSlot; + + return true; +} + + +// *************************************************************************** +// Deletes the value in the list. The item is not removed but the next +// pointers rewritten to bypass this node. This avoids having to move +// the elements up in the list to compact it. +// +// :HACK: Note the use of several exit points (return;) within this code. +// This reduces the amount of code that is executed within the +// special case scenarios and avoids a numerious comparisons. +// *************************************************************************** +bool listDelete( int value ) { + int val; + + // Create an iterator to the start of the list + ListIterator iter; + iter = LIST_CREATE_ITERATOR(); + + // We have to track the previous node to modify it + ListIterator iterPrev; + + // Loop through it verifying that all is right + while ( iter != LIST_END ) { + + // Get the value at this position + if ( value == LIST_GET_VALUE( iter ) ) { + // We found the node so reroute the node pointers around + // this node. This saves having to collapse the list. + + // if this is the head we can just point head to the next node + if ( iter == HeadNode_ ) { + // First in the list, point to it + HeadNode_ = Node_[HeadNode_][NEXT_NODE]; + + // See if we deleted the last node in the list + if ( HeadNode_ == LIST_END ) { + // Reinit the list + LIST_INIT(); + } else { + // Make sure we don't overflow the stack + if ( OpenSlots_[0] < MAX_LIST_SIZE/10 ) { + // Add the node that we deleted to the open slots list + OpenSlots_[++OpenSlots_[0]] = iter; + } + } + + // We're done here + return true; + } else { + // Route around this node + Node_[iterPrev][NEXT_NODE] = Node_[iter][NEXT_NODE]; + + // Make sure we don't overflow the stack + if ( OpenSlots_[0] < MAX_LIST_SIZE/10 ) { + // Add the node that we deleted to the open slots list + OpenSlots_[++OpenSlots_[0]] = iter; + } + + // We're done here + return true; + } + } + + // Move on to the next node + iterPrev = iter; + iter = LIST_INC_ITERATOR( iter ); + } + + // At this point we did not find the value in the list + return false; +} + + +// *************************************************************************** +// Returns if the value is already in the list. The list is searched for +// the value and a iterator is returned pointing to the location in the list. +// LIST_END iterator is returned if the value is not in the list. +// +// :HACK: Note the use of several exit points (return;) within this code. +// This reduces the amount of code that is executed within the +// special case scenarios and avoids a numerious comparisons. +// *************************************************************************** +ListIterator listSearch( int value ) { + // Find out where to insert this value + int nodeValue; + int nextNode; + int testNode; + testNode = HeadNode_; + + ListIterator iter; + iter = LIST_CREATE_ITERATOR(); + while ( iter != LIST_END ) { + + nodeValue = Node_[testNode][NODE_VALUE]; + if ( nodeValue == value ) { + // The value is in the list so return an iterator pointing to it + return testNode; + } + + // Test if we should insert this here + nextNode = Node_[testNode][NEXT_NODE]; + nodeValue = Node_[nextNode][NODE_VALUE]; + if ( nodeValue > value ) { + // We are past were the value would me so it isn't in the list + return LIST_END; + } + + // Move on to the next node to test + testNode = nextNode; + } + + // If we get here it means that the value was not in the list + return LIST_END; +} + + +// *************************************************************************** +// Returns a bool if the value is in the list. +// +// :HACK: Note the use of several exit points (return;) within this code. +// This reduces the amount of code that is executed within the +// special case scenarios and avoids a numerious comparisons. +// *************************************************************************** +bool IsValueInList( int value ) { + if ( listSearch(value) != LIST_END ) { + return true; + } + return false; +} + +#endif /*SORTEDLIST_PH_*/ diff --git a/packetC Programming Source/include/TrojanProtocols.ph b/packetC Programming Source/include/TrojanProtocols.ph new file mode 100644 index 0000000..7059843 --- /dev/null +++ b/packetC Programming Source/include/TrojanProtocols.ph @@ -0,0 +1,119 @@ +//============================================================================ +// +// trojanprotocols.ph - packetC sdk include file of trojan protocol constants +// +// Provide Pre-Defined constants for well known Trojan +// ports. As these change often and many run on otherwise well +// known ports, this file is not a definitive classification +// recommendation for protocols by port. As such, consider +// TrojanProtocols.ph having its main value for humor and +// experimentation. Enjoy! +// +// author +// cloudshield.com +// +// version +// $Revision: 1.0 $ +// +// copyright notice +// © 2009-2011 CloudShield Technologies, Inc. +// +//============================================================================ +//==================- START of TROJAN ======================================== +#ifndef TROJAN_PROTOCOLS_PH +#define TROJAN_PROTOCOLS_PH +#define _TROJAN_PROTOCOLS_PH_VERSION 1.00 +//============================================= +//==========- WELL KNOWN TROJAN PORTS ========= +//============================================= + +const short TROJAN_BLADERUNNER = 21; // Blade Runner, Doly Trojan, Fore, + // Invisible FTP, WebEx, WinCrash +const short TROJAN_TINYTELNET = 23; // Tiny Telnet Server +const short TROJAN_ANTIGEN = 25; // Antigen, Email Password Sender, + // Haebu Coceda, Shtrilitz, Stealth, + // Terminator, WinPC, WinSpy +const short TROJAN_PARADISE = 31; // Hacker's Paradise +const short TROJAN_EXECUTOR = 80; // Executor +const short TROJAN_PARADISE2 = 456; // Hacker's Paradise +const short TROJAN_PHASE_ZERO = 555; // Phase Zero, Stealth Spy, Ini-Killer +const short TROJAN_SATANZ = 666; // Satanz Backdoor +const short TROJAN_SILENCER = 1001; // Silencer, WebEx +const short TROJAN_DOLY = 1011; // Doly Trojan +const short TROJAN_PSYBER = 1170; // Psyber Stream Server, Voice +const short TROJAN_ULTORS = 1234; // Ultors Trojan +const short TROJAN_VOODOO_DOLL = 1245; // VooDoo Doll +const short TROJAN_FTP99CMP = 1492; // FTP99CMP +const short TROJAN_SHIVKA_BURKA = 1600; // Shivka-Burka +const short TROJAN_SPYSENDER = 1807; // SpySender +const short TROJAN_SHOCKRAVE = 1981; // Shockrave +const short TROJAN_BACKDOOR = 1999; // BackDoor +const short TROJAN_COW = 2001; // Trojan Cow +const short TROJAN_RIPPER = 2023; // Ripper +const short TROJAN_BUGS = 2115; // Bugs +const short TROJAN_DEEP_THROAT = 2140; // Deep Throat, The Invasor +const short TROJAN_PHINEAS = 2801; // Phineas Phucker +const short TROJAN_WINCRASH = 3024; // WinCrash +const short TROJAN_MASTERS_PARA = 3129; // Masters Paradise +const short TROJAN_INVASOR = 3150; // Deep Throat, The Invasor +const short TROJAN_PORTAL_DOOM = 3700; // Portal of Doom +const short TROJAN_WINCRASH2 = 4092; // WinCrash +const short TROJAN_ICQTROJAN = 4590; // ICQTrojan +const short TROJAN_SOCK_TROIE = 5000; // Sockets de Troie +const short TROJAN_SOCK_TROIE2 = 5001; // Sockets de Troie +const short TROJAN_FIREHOTCKTER = 5321; // Firehotcker +const short TROJAN_BLADERUNNER2 = 5400; // Blade Runner +const short TROJAN_BLADERUNNER3 = 5401; // Blade Runner +const short TROJAN_BLADERUNNER4 = 5402; // Blade Runner +const short TROJAN_ROBO_HACK = 5569; // Robo-Hack +const short TROJAN_WINCRASH3 = 5742; // WinCrash +const short TROJAN_DEEP_THROAT2 = 6670; // DeepThroat +const short TROJAN_DEEP_THROAT3 = 6771; // DeepThroat +const short TROJAN_GATECRASHER = 6969; // GateCrasher, Priority +const short TROJAN_REMOTE_GRAB = 7000; // Remote Grab +const short TROJAN_NETMONITOR = 7300; // NetMonitor +const short TROJAN_NETMONITOR2 = 7301; // NetMonitor +const short TROJAN_NETMONITOR3 = 7306; // NetMonitor +const short TROJAN_NETMONITOR4 = 7307; // NetMonitor +const short TROJAN_NETMONITOR5 = 7308; // NetMonitor +const short TROJAN_ICKILLER = 7789; // ICKiller +const short TROJAN_PORTAL_DOOM2 = 9872; // Portal of Doom +const short TROJAN_PORTAL_DOOM3 = 9873; // Portal of Doom +const short TROJAN_PORTAL_DOOM4 = 9874; // Portal of Doom +const short TROJAN_PORTAL_DOOM5 = 9875; // Portal of Doom +const short TROJAN_INI_KILLER = 9989; // iNi-Killer +const short TROJAN_PORTAL_DOOM6 = 10167; // Portal of Doom +const short TROJAN_SENNA_SPY = 11000; // Senna Spy +const short TROJAN_PROGENIC = 11223; // Progenic trojan +const short TROJAN_HACK99_KEY = 12223; // Hack&99 KeyLogger +const short TROJAN_GANABUS = 12345; // GabanBus, NetBus +const short TROJAN_GANABUS2 = 12346; // GabanBus, NetBus +const short TROJAN_WHACK_A_MOLE = 12361; // Whack-a-mole +const short TROJAN_WHACK_A_MOLE2= 12362; // Whack-a-mole +const short TROJAN_PRIORITY = 16969; // Priority +const short TROJAN_MILLENIUM = 20001; // Millennium +const short TROJAN_NETBUS_PRO = 20034; // NetBus 2 Pro +const short TROJAN_GIRLFRIEND = 21544; // GirlFriend +const short TROJAN_PROSIAK = 22222; // Prosiak +const short TROJAN_EVIL_FTP = 23456; // Evil FTP, Ugly FTP +const short TROJAN_DELTA = 26274; // Delta +const short TROJAN_BACK_ORIFICE = 31337; // Back Orifice +const short TROJAN_DEEP_BO = 31338; // Back Orifice, DeepBO +const short TROJAN_NETSPY = 31339; // NetSpy DK +const short TROJAN_BOWHACK = 31666; // BOWhack +const short TROJAN_PROSIAK2 = 33333; // Prosiak +const short TROJAN_BIGGLUCK = 34324; // BigGluck, TN +const short TROJAN_THE_SPY = 40412; // The Spy +const short TROJAN_MASTERS_PARA2= 40421; // Masters Paradise +const short TROJAN_MASTERS_PARA3= 40422; // Masters Paradise +const short TROJAN_MASTERS_PARA4= 40423; // Masters Paradise +const short TROJAN_MASTERS_PARA5= 40426; // Masters Paradise +const short TROJAN_DELTA2 = 47262; // Delta +const short TROJAN_SOCK_TROIE3 = 50505; // Sockets de Troie +const short TROJAN_FORE = 50766; // Fore +const short TROJAN_REMOTE_DOWN = 53001; // Remote Windows Shutdown +const short TROJAN_TELECOMMANDO = 61466; // Telecommando +const short TROJAN_DEVIL = 65000; // Devil + +//====================- END of TROJAN ======================================= +#endif /* TROJAN_PROTOCOLS_PH_ */ \ No newline at end of file