ion-3.2.0~dfsg1.orig/0000755000175000017500000000000012271475337012706 5ustar l3onl3onion-3.2.0~dfsg1.orig/tutorial_files/0000755000175000017500000000000012260400060015706 5ustar l3onl3onion-3.2.0~dfsg1.orig/tutorial_files/2node.png0000644000175000017500000001610712260400060017430 0ustar l3onl3onPNG  IHDR'sBITOIDATx}PG{X]`*I\yɡ)+;Q )O4Ii*ј#zI:3&(E0(UZhRUDU<.P'ݝeagvA6==ݞ٧ 1a3ƋX!iH;3}CuOOw7`Ntڌ8 WpмSB+YO |2@ yw,‘x)  %m&r HKW:,R!kp͒)dh)d P@' NB薓p4 ] ©߷AH "   Dk@ 'D+ t@ " H @Ij@ -$W$Ix"$a5RBiz&DjCCR(5OLjDP:'`d&FP PApjLUDXDJR()= , vo;v|͊ vvv:_`vxw,N) :hYЂVUU[d2u֗_~Rz4 ARQXXpwСCQQQӦM ۹sGgrS233rqP >䂯j͚5^^^`0 "ZZZȏ۷oz{{ē'OeO:e6jkk<Zv'~gw^/ٻwݻ?PSSSWWaw7 'Ϧ#""@WC ".9s>}cPRRh"Z}v*V  [rѣGi` 3q{{+JJ***ϗd3gT.[BVގ16~~~ c֯_O/XٳF  BQSSCtvvzzz09eOAgVM1:N޼yoijjBz>))v,^k͚5eeeIII̭LU]r)))D~#SZ[[p"իUVQ)j^hhh`*BwYBBGGX7"Boڴ Bh"WiZ__߼<кuj&i׮]r'66N恁d&ɖ,YbŊB2```K68}>Gs}$ t5twōo9f!ӣV ck~i';*J׏ ONMMH43gt{{{)Ν@:Ƙ"[zž>!!!ǞL&#ȃz50HNtxLVWWGOoNe'#ٳT_~e&'"lz1tIy wn(`)JŋZ-Bׯ_GM>ojjjz*9!!A.ٳѣG### JNN&Bx7lƞÇ۷)djkk{饗\T*}l6߸q###^?>e6:\awE&fgg/^^dIVVҥKɵƹs%&&R+ȷoNJJR(wXݽ{Wѐk$k/矗偁w]@8~xzz:~iDD׬YyL392g*U>YAאꫯ:_ҥK|U\P ˸b0CCCc|9s*eh I dVH2ll"@ dER:Ej()58PKJJϟGQzW^Q(RH%7 ?&''SQ.\HecJ㏟y\C;'%_N!2?'B!KMZ޻w鉅JRחfeeuww;RjycuxzѣGɨvV^_\\Ana3#''g߾}W^R+CCNB9?[5!۶m <חc%&&0g`3a͛7[4_.\W.Q1lR9}"N,o'C=SS6\ n rlnýɼBA y$ Y>=+\E.NY[{BnA))"y+\ſl6!B7noY˗k٭q}̑hp; 4>6n9/&tZ#U4 ֭Vph]0.8c]{iXySć5n@ @ H!)@  BR@ H!)@ Y+zk:Μbs?$4W)v"zlBb?ַ@Js<-DŮLLm\3|O6f8:cePm͑@:q#;ܴ# coǻ)v{g\B  'Io 0\q3Yͱ^pl( irVjqu`bRýCa2 wZB n,^quf#m" !H>hjG BOޣo ai9k@ As(di*\7ȓn<1 Oa{Sm2S`j`bC/AO@|yDT )l; j,pJ,EJ!d8 RŚPk] 6&|B (:T9b 2 `VhY!55رc,VoVTT8_866 xB52Fvܙ7Z;:,wG̟?㣏>r///ooo,^vTd2͘1))v566x5kطskkkdd$SmW\yqJJ =nC?P__sϑ)QQQvZ(zt:Vy7|Ԅȃ"sG؁!,5mE o>2?͛ HKK[`AuuB0 mmmccc<[7%d>}z__#ŵZ/Ldݺu3L]vrX Oiii2lɒ%+V(,,$Tlڴ Bh"RVggBjPnn~`1?!??L={65,,'>>o_WJqƑ"M U*^';RGVStww?ӎ_gC6[NAުrooo2)s$((<6͈K}\NsFFFRSSWZE}18/RRf=`HH?*kWWWHHBh˖-njii9rr*E 8{,r_~C&CCCT!!!TzOOy`SO=u}عHNxLVWWGOYu:]TT Ħ\?)}=Ñ??'x{ fCB555W\IMMq$LJ :Bhlld2Sj#R Jロwߙ7ndddk'"::|htUeŋiZ˗_N]uل\gϞG477#f;#ɚmP( 6|F]5&^ČM2~Ry<~/49ͱ^[[1/00/0Ƹ<888 bj۶msQ+klA 駟FDDxyy͚5w1dzccܹsŋK,Zt)f۷o'%%)ݻwcf;c޽hUElL_>>k׮-**tRFFY… 6KYd`3a <=tUVV;mܸ }PUUק닋;::ȍ l{xx۷oxx޽{_իjlTf_fTTg}Y,11=S 3p u)un޼٢ … }}}ry\\7ShV*ӧO/**}[|3A©!y$;4$*Ub $HRH"e .: y`B@ )7 ZC@ZRh(/{2 v)=nw@Br)C@UIëRХ075/"Qn'mـAA4B^0Ln!$P{z@ ȔwcLU > F{twXp$U"\}fX;)G{S&evr2(~ IENDB`ion-3.2.0~dfsg1.orig/tutorial_files/loopback.png0000644000175000017500000001436412260400060020216 0ustar l3onl3onPNG  IHDR\sBITOIDATxPgǟ$D~9Щ2*JixSW@SN3LzXH{hOZG)T+T`Do31nn~nkg}g}$IB?A$1Sч.@־evQ6ګձ],Mo~|N}} ==DkOfбwYsAd V3:?"[[JWKY;u /kнCWfYۂ+x%53<*+-UqG ʍ>t 4SF tY5i -lN5Axth?Z4Y֠E5]j֠iwSA@Pju]]WpUW$|-߶oplqMTgz%QQQ?ӧwi (bWR={cZڵkBDR(,,|p"H,GDDddd>ȑ#ݻ>dŽ9*|rBBBDDDQQlFfHAVVoٲ%444**lSSS6mkmm9==%AP(B!!!x_X,JIII===ؾ%;;ՉbDk׮cǎF#:.\tK.9@ᦲ^n遁ONNfdd;wf9;;;55ubbΝ;999~axx nݺA7^| $I;+Bz'%%4`f!H7$-ks7"HPĝRXXڹsg||ۍFo!ryrr 㩩)Rl 5X,^~3<UBW^iii2쭷ޚ~WWB(""ZL\-!sss4OT.^UTTܾ}d2wvvj4lݽ{٪5Zvƍ;d1 >ydqq =JtUUվ}֭[痢BDԄm۶^saa?Ozsss_H,|;$988l2rN_zܹFht:B Cnܸ!Jsrr,j+))!brrzXAr6+W:Hp7j=m!~l]>77'ɬMX Lׇw3332`kO]]ӧi0c9ldl0oD]]]2LRYz-~HDM^]z55A6mOv_|Q"lذz.H+k ;ŻwTTT;::FFFnjaCBB] 4SKd23N I?L&s=;X|4;;[__o T*I=j+Wt'ख़nᣬ1 fh4xcnnn۶mGų){<믿F7|sffW\wʀ=l包Ǐ>q˗.\o|zʀZꫯ=gݼy-ɟא^YYj\._t3g\0nI{aVX8==yPTf͚&ν+53$4 d-HՀEዬ1NaF52x°E!/d nblɚ-{P rNB, ޓ5ƛ_s斑e>i $||ېï>4 <5hpګ!\4!֠i[|/k49>5h5h>5h`e <5h4?l'NjYXL6`xOB׮C< s~=ܞ |8y $ P6$ k@ k@ k@ k@ޙ-YG}"Q>SK9Wktt4 aE: z kJbO]\@#ALBq6Ms~"`Hsixy>IOVÛC|2fgOOx@ c/㾏x<Dk1 k@αr&IR$D o%X$zCi0Țڱ~T6 52y[VA5#F4wsB4Tp|iP3,lY+p 6K pN0d _YC\EM(k ؀kTw੬ n_Yj KKKkjj8HLNNu떯(bJ:{,U:UKTTT?êʤ~ۅy.` ,ygggm۳] ب~8}Ν;SF^J###333jk׮EI$VK_XXkm|X,8y$ef]H$*))9x 'ֱzݬ[e:tt_}K/a.S[[#J:NMOO#_wB_|djkkkjjz!YYYvO-,,,..>rGjsss?{qxÎ]n: !H|W"##VXqΝݻwOMMmڴ)..~l \nz2lէN6"Hcˬ,`X\˗"""f36f;˖-QQQeee6|jnnNOOn3AA( PHH_uX,J233{zz}KKKvv]WbDk׮cǎF#j.\tK.9m_aK&ItÇ_ptCCChh~~…[neddx\W$Ifk֬ikkc;~iiiyyy8wsԉ;wUww˝"$ϯX!{zzRR{F1 l"|恬w/ҥKd޽"H8{BtZl6LJy쉉'Gyd||ܑCBBΝ;m7xC&dەOMM)JGAhby晒PkkƍgALMMUR*yBz oWVVCg?LcbbFGG׭[o߾CCC/ѣGr["##'''rXjmp\\3J̙3j^B@b1clrl"z%Kjxе=$44FGGLܹ~{>yqt]V$P%CCC]]]7o T|]FGGQ壣xŋ 9~ ˗/p0---ThѢ۷oS -ZFBd恁D7liii&>@566~7jƍ]]]$I*J\>???l6Ԇ *!/j2nܸ /$%%DUV$իQ#:::[lxlZZL&{뭷fgg߿Յ}5cfggsJŋn^^^EE۷M&S}}}ggFq޽l5FVqFG-2$-[v!ӟ vgggrrrHHH|||SSIV\k.@ 4^}U>3=6Tc4L… ?׮][XXN5~/^\jo߾i&ʆؾ BU^^N$AJ5??Oe{w͛7){#Iwݷo{޽⨨(TOŊ ۼySlTKS\pHěпdǎ .e˖6#W˸ݼ[hawA  ..--x>$IZxd`o`N˩N$L \ ^~)k PPq_eM]0([xߧ*k( ˬɭ[* Jh}#sp2!9l %Kd/r^o1?UcQ{̀͸(::Z"洛b2+ ۷[\j6OvA'5>sFFF4Ft! tqT*ɱͮ$c9qqqqwwTMMMYYٕ+WX;8FVm0d2Y__̬bņ]G*؅sss2CyyyNNE]GɺӧO;`r6c>88 B'[D"jի)n K&T*O?/ǢcQ.{dnx%Ɇ qn+wn1ZׇPAP>x `ݻw ***i[Zu˞㏩E\\Q[[k2jkk٦[Ο3˚ @zwny 7}}ZEMOgu<)J/̲҇͠VT$I~xWծ\SzJΊd2=s GrQ$^yV >b4+Z.333ϟrJ~~>>믿f<€ƮFO:77m۶G)ų%9q6'744c9cGFFO8qeG{YjAj\._t)}mzzzee%Qt6@@ OzM Чw߿^ kÀpzzz͡Rt͚5ׂ/g96v!z"dY#Pv"$@^ dT;pxB!5@ dDmA@$.ka;@n«=OqbTc fm  >~ё^v?WǫY;L)}ȟ^FQ븯oxi()@8AoD3 k.am|%6@J]2Y{w-0d,d{l:$n e fIENDB`ion-3.2.0~dfsg1.orig/tutorial_files/3node.png0000644000175000017500000002544712260400060017440 0ustar l3onl3onPNG  IHDRsBITO IDATx{TT?g J`jLPJBOe^4tey D+[&IEBh˷r_ffsٗgϼ_f{?y|faF0 P&pJP02`(eJRT*{H[Ken؀ ƽ*\fC `ʲAtK8+>p0georzvenJ) - +qO>C#jVhL(jMq&w2hSK"p'vNxR{=meA)C;\=D@l".w==PP˥e:dXi&W.'9Av(e\zu(A(K1DiRF68|Rœ2 (khRFR8't Lq$`eRF bLtE!sAAN8!'2"Bs{ ORFxHp90L  +|ۭapxJ % aJa:B*h>&PP8 82 c6 a@.x}qJ`bI' /7N@)* ^8遱!(exa&"*/()j2V)a \$PBaA)?% ;LB! tÖP&$f`>R脙) &6sKLfp R yixWxxBv"c2(b@0@')g.}e'xBpRE OKRvJ0Q+K$}pK쁕`, -eyH`'(LS#k.\hQAA ak׮FRAaoyJEgC眔`1 jh:讹 KSۧ~խ[wy m4uΝ{Ξ=B ʚ/FDDCBBϟ}QFB333x 6{ZNLLo,UT999WvrOA$|4 #93 c}Nژ_~?2sLМF" KnUHmڵ+Wu::4o<1QSN1t:]KK !䧟~bFFFB;XZZZTTyf.=ŋׯ7/fM޻wO+a$ER0r/ny2F ܜ䛄EEEڲeׄ}*z1:ȗF6n( )e$xW\m۶DF3|={ڵ]RzvddVVVss xSNEFFϝ;ݙؚɓ'5eַ℄>kZV@gﲱR>>>111III%%%)))]BV{{{[l5 5۽{|c3͛SN5m*11laÆ9_9裏Bz}uuu||CVVV5K2!eee_uyy9!"Eҹ0!"z2C<18zٳg;::̊f br~_HpQV%hzjhh2LBٳj{gtRFk栠 {IKKSƍ{ꩧrrr!G?~CtM6775K vpԂ T*U@@O<^"D@$]sQ9i5)q_4Sn~ebpĩ-$$tׇsx]]݀-ݺukϰ G/8p 55t5ZmN={5Ks{`h$bF҉0")TaJV_@OChVGH3gm҅HFRJJJ-ׯ_8qZ.޽{ײaaa:csuX9Æ uJJJӳ{q_ׯ_ݻգ<cڨ(DZI!p(8INoXT1V5'jCL7ڎ{ 26VKG5?3J^-//?wwTpp0;njPVVF9s̅ byرc5ͪUӧYƍFqiiiΝYYY˗/k`0TUU?ޞnj$HIECrss͛~^_WWe˖ 6/b>:(=O"##}||[oFvcdž 2jԨ̄;w۷oڽ{'NDGG7n̙&LzKBCCW\i֔Y^0#cd*.Q"RJ?ܛVIYib"2R @(&b=KT2ce;7ɛڰDN]G,[.&&6655=(imm;wn~4Mll'lYΝzj,jr;`chW_e&%%4zhn7}ѠA4Mtt;wlR#_PZP vI&njMMM3gμu=G9`۷Ço߾iY۳+++ rssO>mâBEep>K4IB0 .3ݸsNN~r֭[7o޼{Ƃ???H,`f~' $`.B6KwZ BMs9//oժUf/\o߾'Of$o~򰰰޽{/]Tg!%Zx݁P\C]V޽;gΜ5kB>sa/,,ܱcǾ}Fm8 L%ϡgN999/^h4۷oOJJrJHHMMM Ü>} =`0 &eKY%1VZVjkkKMMMNN!!>>>Q8 :yzFq'i(ϟ/++[`C~v{ɒ%C 5kVIIHODb#1Pxn2 c! \|=YUU&g}622>}3TTY(*;~'T@ɜ<~xmmm !wUTw}gO{{ 1z.;Hh;7CY^2mkoo7 ??iӦXG9}3؝?n(vx|}}?C{}h-766n۶---}٩S% YT$~P;Q7jdVVVMMͅ .\cNwކDB^^^fڰaCkkoW_M2E c$=Z^%p-/6Ν;ihhHMMmڴ:Z}pK *9k%oްs\*k%c&P02`(e@PC) R (JP02`(e@PC) RΔ)mڴE>B$Q +$\/4׹P(:7ἐ=(!X( ̻]loqg[Ί k!Y*JؿPY(gee'U*a1pt3 RN(5{e*q˖>Y= *e@)NeVw] @2}e!op(e{Ԑ͏ G޵A) '3,0HYl@?zG`ܲmx ,i~K|3-oD^SNAFP4G> getݖG¢kfԞ: ,Q&7CREg`Up +x/{t2DBgJWɴEY CFW98) @AZJ @XZM-P-mʊ)(m%1,*Ji  @XZSJ̪ FE)c.3ȘẊ 3 (e8hQQnbP(Ƅ}q2J?KMMݵkP-Z@ք0Lllk/aG(p KnyR9Ir!PVPB"""{n;3P+555׭[OZi+EΝ;{={Y7 ʚ/FDDCBBϟ}تQFB|7U*ZNLLo},TT999W<~iTTTnyޟ/tNє@: DDZsׯF=qCmZEC5CLOO盄/ 9s&۔Yg@C e ̝;7,,;<<ܡ {Vfk׮4i 3;N:lNt---~IFciiiQQ͛Cm?{ŋ333ׯ_o_mN6owwڵ+Wu::4o<wՁip!;зoÇ߾};-----M9%oc(|pƍڲeׄ}JRAQQu悂ӧOy`ZmTTB0 . ѣǣ>zͬ & 8ѣ?s)))ZֹgŇjGׯ3f,Ym?uTdddppܹs !*J׳;$''sg5kjj&Ok# V{jZm@@!ߟˆHV$%%UWW~vj;,,_ܲeKnn`ˬݻ<ɓE^_rm5ٳk׮J`r@?  @Q_W~pp{tҶ6ON6Fs$lmm]lYAA3<xbX ,dϖR/_!7ػ]&kz?((߿wvV)c4̙f̘q֭cǎ--- ܺukϞ=;vڵD;9T}h믿.//'ܿofSSSbbÇmޞ2f̘ƛ7oN:F$+++ D'_9裏Bz}uuu||-VVVI2EΝcŀFYZZwiƎ+(gQ +kD_QQh""")rٳg;::f0BO~VXb]1Yfy{{? 2ڰaɓ/JJKKtCG %g ! ,PTO<;٫g:t ҥK5_llaZZZ7nSO=C9z㽼o[nZMBHPPٽzjhhpF85qp lDƔkݻsYfM``CO֒oc;'#r =YAC@C(,,4ׯ_wӦMK/~an𺺺_gHHHVVV[[$ 6FRWW7`nۖnݺ5p@;EPPN80LSS}}}_kjizgϞ|mBzUNӍ.(BQ RSS"(wNZ9G,zRAIOO߿ '.aaazͰ0Bȿʋ/O;v rTT3f빻uuu///Z]{.{O>%'36lXmm=,))Nƍ]~Ƀh6**FRJJJLVQQ1qD`Y3h b@[m;_EZFg醝ZʝqqqjСCm a3=ϊ"I~رcF㧟~J9xٳgSSS犊 aJ388ꉠvݰ[3fLCCCYY!̙3.\ Thzyys؝ǎhVZ ɤ$Y΃ 谧{.] ӧ{wk֬qhܽ{wyyyZZ_fee-_{``0TUU?ޞ>Cվ/ѣGF?&&/$tVG C@,BQ QAO`;::^x__? k_jFAsL@@@nny߯l]$rChżظm۶۷o|gN< Gy=zd- IDAT̙.//:thQQ0{={⋭ l߾=44{%%%}HsNFPB\w~MvcFFF~~>{ĉƍ9s ا|ر!C5*333!!åKBCCW\Gի\7LqF+.\bUƍ_u{CCC}||F/׸JѣĉcMa3}ti'|ӿzh4i:wu Dpb9\bgJKKU_,$0a/bĈgϞ/_f]Ҡ$?3F!'oL8100gȑɰgat+I/##c߾}0yda_QX l!\FsӞm'-g(tfj iBNkmm--Z{\0իWO7BQ%`3U'.g(qiC)CkHɓߓ;+l($ U#Ga8򆛔2I <#'`8-2I <[#`][2I <#atɍnݺ//~: ""GZ=}iQ&5ceun;wnXXwxxի*\qnmm;wn~4Mll'\|"DjF9i^}UnRROGvG 4HDGG߹s?yYM0`ڵk'Mdz@NNVmjjϟ9s[ZzӈKj4|GYݞ]YY\PP{iGUr`0÷oNKKKKKt.>"r5#㜴g0 p¸8Ӎ;wt:-oݺuͻwnll,((ajaG qVB{V._[n&M߳gYGYr{qHIX޽{߾}6vkz?((Hpl}\q~.]VSS!bV32ItNB >b}}}ZV5{ٳ{mڴ)...000..џ7د.gYJëyT򹼱*..>| Κ5'4h-lZĈz[8WTTh4s3Rr˜漼UVp¾}N< !͛7ztR<|$pq&|^jZ^/RD}w’7V͛lh4fgg|,<9R~XO8߽{wΜ9k֬~\WT3Rr˜ɷ~;'''44ŋ;vlĈIII|ۛ9}tmmɓ'oW_D$cyj^hV^q H257!'===>>~r<6сqnkkKMMMNNq $߄9|YYق OII:th^^^޽l,Y8dȐYfDc$hdR&""a˗/w{1%ŊNߵz`GD8g}622>}"~5#˜0Ǐ߿C={۶m?̎iooltHѦdo0:;;~~~ӦM[b9r3f?~Qf;"1kN6be2;=m۶ݾ}>;uTrrsQr,M>+/~h0[V3rŊops2++… .\HOOرcNۻwoCCCSSS^^^MMMbb"!v//Yfmذ~ꫯLbd1mq /^ش;wd!55o~J;!!aݺu|GO;{8'-VsymЖ[ZZ&N3rȢ"'#3+|W>SC*W&̟?W^a=zF5jԑ#G V۫W+V8%yyvOx- ø/c;ʍ&]an{h)CA>" n/d,-eXHm@# 609^, y J? dBJAj`ʂ9 *$#`D~DE' P (exa01}E5 (e.R\b o8]0 6 LsP 3 B7A)%(e6`z4 6 סqfpo(h@ BA)LDg6[CA Pa= pHPo=FXxM!o 0kRI11` yC2(eDy,*6#<d C)#Lnaa 8 5g4F_B(e$"c\@X4Aa!iPlVbFwYKT'{\A32THh/"=zgOO @lJ.BPo;ؑG\Y S$؃rfV3% X]8e9Iଌ2x˶HqO}OR(+i(9RF' "q}JR?P:,(p3ZEgIENDB`ion-3.2.0~dfsg1.orig/tutorial_files/print.html0000644000175000017500000000051612260400060017732 0ustar l3onl3on 404 Not Found

Not Found

The requested URL /misc/print.css was not found on this server.


Apache/2.0.59 (Unix) PHP/5.2.6 mod_ssl/2.0.59 OpenSSL/0.9.7l Server at ion.ocp.ohiou.edu Port 443
ion-3.2.0~dfsg1.orig/configs/0000755000175000017500000000000012260400056014316 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/loopback-ltp/0000755000175000017500000000000012260400056016705 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/loopback-ltp/loopback.ionsecrc0000644000175000017500000000000612260400056022222 0ustar l3onl3on1 e 1 ion-3.2.0~dfsg1.orig/configs/loopback-ltp/loopback.rc0000644000175000017500000001312212260400056021024 0ustar l3onl3on ## begin ionadmin # ionrc configuration file for loopback test. # This uses ltp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, July 2009 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 0 seconds to reach the other # end (One Way Light Time). a range +1 +3600 1 1 0 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin ltpadmin # ltprc configuration file for the loopback test. # Command: % ltpadmin loopback.ltprc # This command should be run AFTER ionadmin and BEFORE bpadmin. # # Ohio University, July 2009 # # A warning: the ltp configuration is not ideal in this case. # please consult manual pages and other documentation for a # better description. # Initialization command (command 1). # Establishes the LTP retransmission window. # (Prohibiting LTP from seizing all available storage). # A maximum of 32 sessions. A session is assumed to be around one # second of transmission. This value should be estimated at the sum # of maximum round-trip times (in seconds) for all "spans." # Suggest throwing 20% higher number of sessions to account for extra- # long sessions which contain an actual retransmission. # Set a total LTP memory space usage limit as the sum of the memory # space usage of all spans (more or less the number of bytes in transit # on all links for their duration). 1 128 262144 # Add a span. (a connection) # Identify the span as engine number 1. That is the ipn node number # of the node on the other end of this span. # Use 128 as the maximum number of export sessions. # Use 1024 as the maximum size of an export block. This more or less # limits the maximum size of a bundle in the system. # The next two items are the maximum number of import sessions and the # maximum size of an imported block. Since this is loopback, we just # copy the export numbers here. # 1024 is the maximum segment size- more or less, the amount of data # that can be held in a single frame of the underlying protocol. In # this case, UDP packets are the frame, and we will give a conservative # limit. # Limit the aggregation size to 1024 bytes, and set a time limit on # aggregation to 1 second. # Use the command 'udplso localhost:1113' to implement the link # itself. In this case, we use udp to connect to localhost (this is # loopback) using port 1113 (defined by IANA as the default UDP port # for Licklider Transmission Protocol). The single quote is # important, don't use double quotes. a span 1 128 1024 128 1024 1024 1024 1 'udplso localhost:1113' # Start command. # This command actually runs the link service output commands # (defined above, in the "a span" commands). # Also starts the link service INPUT task 'udplsi localhost:1113' to # listen locally on UDP port 1113 for incoming LTP traffic. s 'udplsi 0.0.0.0:1113' ## end ltpadmin ## begin bpadmin # bprc configuration file for the loopback test. # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). # Note that the custodian endpoint ipn:1.0 is automatically generated. a endpoint ipn:1.1 q a endpoint ipn:1.2 q # Add a protocol. # Add the protocol named ltp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, udp on ethernet) for payload, and 100 bytes for overhead. a protocol ltp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # induct). # The induct itself is implemented by the 'ltpcli' command. a induct ltp 1 ltpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # outduct). # The outduct itself is implemented by the 'ltpclo' command. a outduct ltp 1 ltpclo # Start the daemons s ## end bpadmin ## begin ipnadmin # ipnrc configuration file for the loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # The plan is to queue for transmission (x) on protocol 'ltp' using # the outduct identified as '1.' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 ltp/1 ## end ipnadmin ion-3.2.0~dfsg1.orig/configs/loopback-ltp/loopback.ipnrc0000644000175000017500000000100412260400056021527 0ustar l3onl3on# ipnrc configuration file for the loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # The plan is to queue for transmission (x) on protocol 'ltp' using # the outduct identified as '1.' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 ltp/1 ion-3.2.0~dfsg1.orig/configs/loopback-ltp/loopback.ionrc0000644000175000017500000000173312260400056021537 0ustar l3onl3on# ionrc configuration file for loopback test. # This uses ltp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, July 2009 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 0 seconds to reach the other # end (One Way Light Time). a range +1 +3600 1 1 0 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ion-3.2.0~dfsg1.orig/configs/loopback-ltp/loopback.bprc0000644000175000017500000000315412260400056021352 0ustar l3onl3on# bprc configuration file for the loopback test. # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). # Note that the custodian endpoint ipn:1.0 is automatically generated. a endpoint ipn:1.1 q a endpoint ipn:1.2 q # Add a protocol. # Add the protocol named ltp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, udp on ethernet) for payload, and 100 bytes for overhead. a protocol ltp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # induct). # The induct itself is implemented by the 'ltpcli' command. a induct ltp 1 ltpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # outduct). # The outduct itself is implemented by the 'ltpclo' command. a outduct ltp 1 ltpclo # Start the daemons s ion-3.2.0~dfsg1.orig/configs/loopback-ltp/loopback.ltprc0000644000175000017500000000456612260400056021560 0ustar l3onl3on# ltprc configuration file for the loopback test. # Command: % ltpadmin loopback.ltprc # This command should be run AFTER ionadmin and BEFORE bpadmin. # # Ohio University, July 2009 # # A warning: the ltp configuration is not ideal in this case. # please consult manual pages and other documentation for a # better description. # Initialization command (command 1). # Establishes the LTP retransmission window. # (Prohibiting LTP from seizing all available storage). # A maximum of 32 sessions. A session is assumed to be around one # second of transmission. This value should be estimated at the sum # of maximum round-trip times (in seconds) for all "spans." # Suggest throwing 20% higher number of sessions to account for extra- # long sessions which contain an actual retransmission. # Set a total LTP memory space usage limit as the sum of the memory # space usage of all spans (more or less the number of bytes in transit # on all links for their duration). 1 128 262144 # Add a span. (a connection) # Identify the span as engine number 1. That is the ipn node number # of the node on the other end of this span. # Use 128 as the maximum number of export sessions. # Use 1024 as the maximum size of an export block. This more or less # limits the maximum size of a bundle in the system. # The next two items are the maximum number of import sessions and the # maximum size of an imported block. Since this is loopback, we just # copy the export numbers here. # 1024 is the maximum segment size- more or less, the amount of data # that can be held in a single frame of the underlying protocol. In # this case, UDP packets are the frame, and we will give a conservative # limit. # Limit the aggregation size to 1024 bytes, and set a time limit on # aggregation to 1 second. # Use the command 'udplso localhost:1113' to implement the link # itself. In this case, we use udp to connect to localhost (this is # loopback) using port 1113 (defined by IANA as the default UDP port # for Licklider Transmission Protocol). The single quote is # important, don't use double quotes. a span 1 128 1024 128 1024 1024 1024 1 'udplso localhost:1113' # Start command. # This command actually runs the link service output commands # (defined above, in the "a span" commands). # Also starts the link service INPUT task 'udplsi localhost:1113' to # listen on UDP port 1113 for incoming LTP traffic. s 'udplsi 0.0.0.0:1113' ion-3.2.0~dfsg1.orig/configs/loopback-udp/0000755000175000017500000000000012260400056016676 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/loopback-udp/loopback.rc0000644000175000017500000000475012260400056021024 0ustar l3onl3on ## begin ionadmin # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 a range +1 +3600 1 2 1 a range +1 +3600 2 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 # Disable congestion forecasting m horizon +0 ## end ionadmin ## begin bpadmin # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). a endpoint ipn:1.1 q a endpoint ipn:1.2 q a endpoint ipn:1.3 q # Add a protocol. a protocol udp 1400 100 # Add an induct. (listen) a induct udp 0.0.0.0:4556 udpcli # Add an outduct. (since one UDP socket can address any IP, use '*' # for the destination address, then this clo can send to any udp cli) a outduct udp * udpclo s ## end bpadmin ## begin ipnadmin # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # This element is named 'node1.' # The plan is to queue for transmission (x) on protocol 'udp' using # the outduct identified as '*,127.0.0.1:4556'. This specification # will match the udpclo '*' and pass it an auxiliary parameter # (destination address) of '127.0.0.1:4556' a plan 1 udp/*,127.0.0.1:4556 ## end ipnadmin ion-3.2.0~dfsg1.orig/configs/loopback-tcp/0000755000175000017500000000000012260400056016674 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/loopback-tcp/loopback.ionsecrc0000644000175000017500000000000612260400056022211 0ustar l3onl3on1 e 1 ion-3.2.0~dfsg1.orig/configs/loopback-tcp/loopback.ipnrc0000644000175000017500000000111412260400056021520 0ustar l3onl3on# ipnrc configuration file for the tcpcl dos loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # This element is named 'node1.' # The plan is to queue for transmission (x) on protocol 'tcp' using # the outduct identified by IP address 127.0.0.1 # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 tcp/127.0.0.1:4556 ion-3.2.0~dfsg1.orig/configs/loopback-tcp/loopback.ionrc0000644000175000017500000000060612260400056021524 0ustar l3onl3on# ionrc configuration file for tcpcl dos loopback test. # This uses tcp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s ion-3.2.0~dfsg1.orig/configs/loopback-tcp/loopback.bprc0000644000175000017500000000307712260400056021345 0ustar l3onl3on# bprc configuration file for the tcpcl dos loopback test. # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). a endpoint ipn:1.1 q a endpoint ipn:1.2 q # Add a protocol. # Add the protocol named tcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, udp on ethernet) for payload, and 100 bytes for overhead. a protocol tcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the tcp protocol. # The induct itself is implemented by the 'tcpcli' command. a induct tcp 0.0.0.0:4556 tcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the tcp protocol. # The outduct itself is implemented by the 'tcpclo' command. a outduct tcp 127.0.0.1:4556 tcpclo s ion-3.2.0~dfsg1.orig/configs/2node-stcp/0000755000175000017500000000000012260400056016274 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/2node-stcp/host1.rc0000644000175000017500000001257412260400056017671 0ustar l3onl3on## File created by ../../../../branches/release-1.0_r203/ionscript ## Wed Oct 29 17:28:46 EDT 2008 ## Run the following command to start ION node: ## % ionstart -I "host1.rc" ## begin ionadmin # ionrc configuration file for host1 in a 2node stcp test. # This uses stcp as the primary convergence layer. # command: % ionadmin host1.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # They will connect 1 to 2, 2 to 1, and 2 to itself # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 2 2 1 a range +1 +3600 2 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin bpadmin # bprc configuration file for host1 in a 2node test. # Command: % bpadmin host1.bprc # This command should be run AFTER ionadmin and BEFORE ipnadmin # or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:1.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 1 and service number 0 # (ipn requires custodian service to be zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:1.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.0 ipn:1.1 and ipn:1.2 on the local node. # ipn:1.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to dump them 'x', as opposed to # queueing them (use 'q' instead of 'x' to queue). a endpoint ipn 1.0 x a endpoint ipn 1.1 x a endpoint ipn 1.2 x # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, tcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at this host's IP address (private testbed). # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 10.1.1.1:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.1 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.1:4556 stcpclo # Add an outduct. (send to host2) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.2 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.2:4556 stcpclo ## end bpadmin ## begin ipnadmin # ipnrc configuration file for host1 in the 2node stcp network. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host1.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:1.0) called 'admin.' # Add service 1 (ipn:1.1) called 'test1.' # Add service 2 (ipn:1.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. (to yourself) # Bundles to be transmitted to element number 1 (that is, yourself). # This element is named 'host1.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.1:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 host1 x stcp/10.1.1.1:4556 # Add an egress plan. (to the second host) # Bundles to be transmitted to element number 2 (the other node). # This element is named 'host2.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.2:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 2 host2 x stcp/10.1.1.2:4556 ## end ipnadmin ion-3.2.0~dfsg1.orig/configs/2node-stcp/host2.bprc0000644000175000017500000000501012260400056020177 0ustar l3onl3on# bprc configuration file for host2 in a 2node test. # Command: % bpadmin host2.bprc # This command should be run AFTER ionadmin and BEFORE ipnadmin # or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:2.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 2 and service number 0 # (ipn requires custodian service to be zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:2.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:2.0 ipn:2.1 and ipn:2.2 on the local node. # ipn:2.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to dump them 'x', as opposed to # queueing them (use 'q' instead of 'x' to queue). a endpoint ipn 2.0 x a endpoint ipn 2.1 x a endpoint ipn 2.2 x # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, stcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at this host's IP address (private testbed). # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 10.1.1.2:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.2 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.2:4556 stcpclo # Add an outduct. (send to host1) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.1 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.1:4556 stcpclo ion-3.2.0~dfsg1.orig/configs/2node-stcp/host1.ipnrc0000644000175000017500000000230612260400056020370 0ustar l3onl3on# ipnrc configuration file for host1 in the 2node stcp network. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host1.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:1.0) called 'admin.' # Add service 1 (ipn:1.1) called 'test1.' # Add service 2 (ipn:1.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. (to yourself) # Bundles to be transmitted to element number 1 (that is, yourself). # This element is named 'host1.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.1:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 host1 x stcp/10.1.1.1:4556 # Add an egress plan. (to the second host) # Bundles to be transmitted to element number 2 (the other node). # This element is named 'host2.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.2:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 2 host2 x stcp/10.1.1.2:4556 ion-3.2.0~dfsg1.orig/configs/2node-stcp/host2.rc0000644000175000017500000001257412260400056017672 0ustar l3onl3on## File created by ../../../../branches/release-1.0_r203/ionscript ## Wed Oct 29 17:28:46 EDT 2008 ## Run the following command to start ION node: ## % ionstart -I "host2.rc" ## begin ionadmin # ionrc configuration file for host2 in a 2node stcp test. # This uses stcp as the primary convergence layer. # command: % ionadmin host2.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 2 (as in ipn:2). # Use default sdr configuration (empty configuration file name ""). 1 2 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # They will connect 1 to 2, 2 to 1, and 2 to itself # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 2 2 1 a range +1 +3600 2 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin bpadmin # bprc configuration file for host2 in a 2node test. # Command: % bpadmin host2.bprc # This command should be run AFTER ionadmin and BEFORE ipnadmin # or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:2.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 2 and service number 0 # (ipn requires custodian service to be zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:2.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:2.0 ipn:2.1 and ipn:2.2 on the local node. # ipn:2.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to dump them 'x', as opposed to # queueing them (use 'q' instead of 'x' to queue). a endpoint ipn 2.0 x a endpoint ipn 2.1 x a endpoint ipn 2.2 x # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, stcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at this host's IP address (private testbed). # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 10.1.1.2:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.2 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.2:4556 stcpclo # Add an outduct. (send to host1) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.1 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.1:4556 stcpclo ## end bpadmin ## begin ipnadmin # ipnrc configuration file for host1 in the 2node stcp network. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host2.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:2.0) called 'admin.' # Add service 1 (ipn:2.1) called 'test1.' # Add service 2 (ipn:2.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. (to yourself) # Bundles to be transmitted to element number 2 (that is, yourself). # This element is named 'host2.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.2:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 2 host2 x stcp/10.1.1.2:4556 # Add an egress plan. (to the other host) # Bundles to be transmitted to element number 1 (the other node). # This element is named 'host1.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.1:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 host1 x stcp/10.1.1.1:4556 ## end ipnadmin ion-3.2.0~dfsg1.orig/configs/2node-stcp/host1.ionrc0000644000175000017500000000266512260400056020377 0ustar l3onl3on# ionrc configuration file for host1 in a 2node stcp test. # This uses stcp as the primary convergence layer. # command: % ionadmin host1.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # They will connect 1 to 2, 2 to 1, and 2 to itself # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 2 2 1 a range +1 +3600 2 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ion-3.2.0~dfsg1.orig/configs/2node-stcp/host2.ipnrc0000644000175000017500000000230512260400056020370 0ustar l3onl3on# ipnrc configuration file for host1 in the 2node stcp network. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host2.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:2.0) called 'admin.' # Add service 1 (ipn:2.1) called 'test1.' # Add service 2 (ipn:2.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. (to yourself) # Bundles to be transmitted to element number 2 (that is, yourself). # This element is named 'host2.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.2:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 2 host2 x stcp/10.1.1.2:4556 # Add an egress plan. (to the other host) # Bundles to be transmitted to element number 1 (the other node). # This element is named 'host1.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.1:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 host1 x stcp/10.1.1.1:4556 ion-3.2.0~dfsg1.orig/configs/2node-stcp/host1.bprc0000644000175000017500000000500712260400056020204 0ustar l3onl3on# bprc configuration file for host1 in a 2node test. # Command: % bpadmin host1.bprc # This command should be run AFTER ionadmin and BEFORE ipnadmin # or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:1.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 1 and service number 0 # (ipn requires custodian service to be zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:1.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.0 ipn:1.1 and ipn:1.2 on the local node. # ipn:1.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to dump them 'x', as opposed to # queueing them (use 'q' instead of 'x' to queue). a endpoint ipn 1.0 x a endpoint ipn 1.1 x a endpoint ipn 1.2 x # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, tcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at this host's IP address (private testbed). # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 10.1.1.1:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.1 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.1:4556 stcpclo # Add an outduct. (send to host2) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.2 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.2:4556 stcpclo ion-3.2.0~dfsg1.orig/configs/2node-stcp/host2.ionrc0000644000175000017500000000266512260400056020400 0ustar l3onl3on# ionrc configuration file for host2 in a 2node stcp test. # This uses stcp as the primary convergence layer. # command: % ionadmin host2.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 2 (as in ipn:2). # Use default sdr configuration (empty configuration file name ""). 1 2 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # They will connect 1 to 2, 2 to 1, and 2 to itself # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 2 2 1 a range +1 +3600 2 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ion-3.2.0~dfsg1.orig/configs/loopback-brs/0000755000175000017500000000000012260400056016674 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/loopback-brs/loopback.ionsecrc0000644000175000017500000000135712260400056022223 0ustar l3onl3on# loopback-brs/loopback.ionsecrc # # The BRS system uses HMAC to authenticate clients that connect, so we # must initialize the ION security database before using HMAC. # The BRS server must have a key "X.brs" for each BRS client wishing to # connect to duct X. # Each client X must have that same key "X.brs" # In this loopback configuration, there is one server and one client with # one key ("1.brs") for duct 1. # Initialize the ION security database. 1 # Add a key named "1.brs" for the BRS server to use for authenticating # BRS clients. Note that some versions of ION may not come with ciphersuites, # in which case this authentication is trivially insecure. a key 1.brs ../1.brs # Don't require or transmit BABs a bspbabrule * * '' '' ion-3.2.0~dfsg1.orig/configs/loopback-brs/1.brs0000644000175000017500000000002412260400056017540 0ustar l3onl3on1ܱB=FvGa-ion-3.2.0~dfsg1.orig/configs/loopback-brs/loopback.ipnrc0000644000175000017500000000074112260400056021525 0ustar l3onl3on# ipnrc configuration file for the loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, July 2009 # Add an egress plan. # Bundles to be transmitted to element number 1. # Transmission should use the BRS convergence layer for 0.0.0.0:4556 # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 brsc/localhost:4556_1 ion-3.2.0~dfsg1.orig/configs/loopback-brs/restart-brsc.bprc0000644000175000017500000000063512260400056022163 0ustar l3onl3on# loopback-brs/restart-brsc.bprc # Restarts the BRS client CLA task, in case it started before the # BRS server was ready to serve. # # If you get an error message like this: # bp/brs/brsccla.c, Can't connect to server. (localhost:4556) # then you should pass this snippet to bpadmin to restart the BRS client CLA: # bpadmin restart-brsc.bprc # x induct brsc localhost:4556_1 s induct brsc localhost:4556_1 ion-3.2.0~dfsg1.orig/configs/loopback-brs/loopback.ionrc0000644000175000017500000000173312260400056021526 0ustar l3onl3on# ionrc configuration file for loopback test. # This uses stcp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, July 2009 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ion-3.2.0~dfsg1.orig/configs/loopback-brs/loopback.bprc0000644000175000017500000000356712260400056021351 0ustar l3onl3on# bprc configuration file for BRS loopback # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, July 2009 and University of Colorado, Nov 2010 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). # Note that the custodian endpoint "ipn:1.0" is automatically generated. a endpoint ipn:1.1 q a endpoint ipn:1.2 q # Add a protocol. # Add the protocol named brss. # Estimate transmission capacity assuming 1450 bytes of each frame (in # this case, tcp on ethernet) for payload, and 68 bytes for overhead. a protocol brss 1450 68 # Add BRS server induct and outduct. a induct brss 0.0.0.0:4556 brsscla a outduct brss 0.0.0.0:4556 '' # Add a protocol. # Add the protocol named brsc. # Estimate transmission capacity assuming 1450 bytes of each frame (in # this case, tcp on ethernet) for payload, and 68 bytes for overhead. a protocol brsc 1450 68 # Add BRS client induct and outduct. # Add an induct to receive bundles using the brsc protocol. # Add an outduct to send bundles using the brsc protocol. # Both the induct and outduct are implemented in one 'brsccla' task. # The task will connect to the BRS server on port 4556, and # identify itself as node 1. a induct brsc localhost:4556_1 brsccla a outduct brsc localhost:4556_1 '' # Start the bp daemons and defined ducts. s ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/0000755000175000017500000000000012260400056016707 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/README.txt0000644000175000017500000000375012260400056020412 0ustar l3onl3on******************************************************************* NO WARRANTY: DISCLAIMER THE SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET FORTH IN UCC 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE LICENSED PRODUCT, HOWEVER USED. IN NO EVENT SHALL CALTECH/JPL BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN FACT SHALL KNOW OF THE POSSIBILITY. USER BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED MATERIALS. ******************************************************************* Copyright 2004-2007, by the California Institute of Technology. ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. Any commercial use must be negotiated with the Office of Technology Transfer at the California Institute of Technology. This software and/or related materials may be subject to U.S. export control laws. By accepting this software and related materials, the user agrees to comply with all applicable U.S. export laws and regulations. User has the responsibility to obtain export licenses or other export authority as may be required before exporting the software or related materials to foreign countries or providing access to foreign persons. ******************************************************************* These sample ION configuration files establish a simple network of three nodes: 7 <--> 5 <--> 10 Nodes 7 and 5 communicate via LTP over UDP/IP. Nodes 5 and 10 communicate via Bundle Relay Service using TCP/IP, and node 10 also has an LTP/UDP/IP loopback link to itself. Node 5 can send messages to itself only via node 10, and node 7 has no loopback route at all. ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node7/0000755000175000017500000000000012260400056022174 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node7/node7.ionrc0000644000175000017500000000040512260400056024243 0ustar l3onl3on1 7 ionconfig s a range +0 2009/01/01-00:00:00 5 7 600 a contact +0 2009/01/01-00:00:00 5 7 10000 a contact +0 2009/01/01-00:00:00 7 5 10000 a contact +0 2009/01/01-00:00:00 5 10 100000 a contact +0 2009/01/01-00:00:00 10 5 100000 ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node7/node7.ltprc0000644000175000017500000000014012260400056024251 0ustar l3onl3on1 128 262144 a span 5 128 1024 128 1024 1024 1024 1 'udplso host5:1113' s 'udplsi 0.0.0.0:1113' ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node7/ionconfig0000644000175000017500000000030312260400056024066 0ustar l3onl3onwmSize 5000000 wmAddress 0 # configFlags = 1 means ION data store is in DRAM only, no SDR # transaction reversibility, no object bounds checking configFlags 1 heapWords 5000000 pathName /usr/ion ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node7/node7.ipnrc0000644000175000017500000000024112260400056024242 0ustar l3onl3on# Node 7 has no loopback route. It talks to node 5 by LTP/UDP/IP. # Routes to all other nodes are computed dynamically from the contact graph. # a plan 5 ltp/5 ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node7/node7.bprc0000644000175000017500000000030312260400056024054 0ustar l3onl3on1 a scheme ipn 'ipnfw' 'ipnadminep' a endpoint ipn:7.0 x a endpoint ipn:7.1 x a endpoint ipn:7.2 x a protocol ltp 1400 100 a induct ltp 7 ltpcli a outduct ltp 5 ltpclo r 'ipnadmin node7.ipnrc' s ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node7/ionstart0000755000175000017500000000017512260400056023770 0ustar l3onl3on# shell script to get node running #!/bin/bash ionadmin node7.ionrc sleep 1 ltpadmin node7.ltprc sleep 1 bpadmin node7.bprc ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node5/0000755000175000017500000000000012260400056022172 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node5/node5.ltprc0000644000175000017500000000014012260400056024245 0ustar l3onl3on1 128 262144 a span 7 128 1024 128 1024 1024 1024 1 'udplso host7:1113' s 'udplsi 0.0.0.0:1113' ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node5/ionconfig0000644000175000017500000000033612260400056024072 0ustar l3onl3onwmSize 5000000 wmAddress 0 # configFlags = 14 means the ION data store is in a file (in /usr/ion) # only, transactions are reversible, and object boundaries are enforced. configFlags 14 heapWords 5000000 pathName /usr/ion ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node5/node5.bprc0000644000175000017500000000046712260400056024063 0ustar l3onl3on1 a scheme ipn 'ipnfw' 'ipnadminep' a endpoint ipn:5.0 x a endpoint ipn:5.1 x a endpoint ipn:5.2 x a protocol ltp 1400 100 a induct ltp 5 ltpcli a outduct ltp 7 ltpclo a protocol brsc 1400 100 a induct brsc brss.jpl.nasa.gov:5001_5 brsccla a outduct brsc brss.jpl.nasa.gov:5001_5 '' r 'ipnadmin node5.ipnrc' s ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node5/node5.ionrc0000644000175000017500000000046212260400056024242 0ustar l3onl3on1 5 ionconfig s a range +0 2009/01/01-00:00:00 5 7 600 a range +0 2009/01/01-00:00:00 5 10 1 a contact +0 2009/01/01-00:00:00 5 7 10000 a contact +0 2009/01/01-00:00:00 7 5 10000 a contact +0 2009/01/01-00:00:00 5 10 100000 a contact +0 2009/01/01-00:00:00 10 5 100000 ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node5/node5.ipnrc0000644000175000017500000000064312260400056024244 0ustar l3onl3on# Node 5 has a BRSC loopback route (i.e., it sends bundles to itself via # the BRS server at node 10). It also talks to node 10 by BRSC to # the BRS server at node 10. # It talks to node 7 by LTP/UDP/IP. # For all other nodes it uses a default route: via node 7. There is no # dynamic route computation. # a plan 5 brsc/brss.jpl.nasa.gov:5001_5 a plan 10 brsc/brss.jpl.nasa.gov:5001_5 a plan 7 ltp/7 a group 1 9999 7 ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node5/ionstart0000755000175000017500000000017512260400056023766 0ustar l3onl3on# shell script to get node running #!/bin/bash ionadmin node5.ionrc sleep 1 ltpadmin node5.ltprc sleep 1 bpadmin node5.bprc ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node10/0000755000175000017500000000000012260400056022246 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node10/node10.ipnrc0000644000175000017500000000035112260400056024370 0ustar l3onl3on# Node 10 has an LTP/UDP/IP loopback route. # It talks to node 5 by BRSS -- it is the BRS server. # Routes to all other nodes are computed dynamically from the contact graph. # a plan 10 ltp/10 a plan 5 brss/brss.jpl.nasa.gov:5001,5 ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node10/node10.ionrc0000644000175000017500000000052312260400056024370 0ustar l3onl3on1 10 ionconfig s m production 10 m consumption 0 a range +0 2009/01/01-00:00:00 5 7 600 a range +0 2009/01/01-00:00:00 5 10 1 a contact +0 2009/01/01-00:00:00 5 7 10000 a contact +0 2009/01/01-00:00:00 7 5 10000 a contact +0 2009/01/01-00:00:00 5 10 100000 a contact +0 2009/01/01-00:00:00 10 5 100000 ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node10/ionconfig0000644000175000017500000000037112260400056024145 0ustar l3onl3onwmSize 5000000 wmAddress 0 # configFlags = 15 means that ION's data store is in DRAM with # automatic write-through to a file, SDR transactions are reversible, # and object boundaries are enforced. configFlags 15 heapWords 5000000 pathName /usr/ion ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node10/ionstart0000755000175000017500000000020012260400056024027 0ustar l3onl3on# shell script to get node running #!/bin/bash ionadmin node10.ionrc sleep 1 ltpadmin node10.ltprc sleep 1 bpadmin node10.bprc ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node10/node10.bprc0000644000175000017500000000047012260400056024205 0ustar l3onl3on1 a scheme ipn 'ipnfw' 'ipnadminep' a endpoint ipn:10.0 x a endpoint ipn:10.1 x a endpoint ipn:10.2 x a protocol ltp 1400 100 a induct ltp 10 ltpcli a outduct ltp 10 ltpclo a protocol brss 1400 100 a induct brss brss.jpl.nasa.gov:5001 brsscla a outduct brss brss.jpl.nasa.gov:5001 '' r 'ipnadmin node10.ipnrc' s ion-3.2.0~dfsg1.orig/configs/3node-ltp-brs/iontest.ipn.node10/node10.ltprc0000644000175000017500000000016712260400056024406 0ustar l3onl3on1 128 262144 a span 10 128 1024 128 1024 1024 1024 1 'udplso brss.jpl.nasa.gov:1113' s 'udplsi brss.jpl.nasa.gov:1113' ion-3.2.0~dfsg1.orig/configs/bsp-loopback/0000755000175000017500000000000012260400056016672 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/bsp-loopback/bsp+stcp_loopback.rc0000644000175000017500000000732412260400056022631 0ustar l3onl3on## File created by /usr/local/bin/ionscript ## Tue Jul 14 13:56:36 EDT 2009 ## Run the following command to start ION node: ## % ionstart -I "loopback.rc" ## begin ionadmin # ionrc configuration file for loopback test. # This uses stcp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, July 2009 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin bpadmin # bprc configuration file for the loopback test. # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, July 2009 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). # Note that the custodian endpoint "ipn:1.0" is automatically generated. a endpoint ipn:1.1 q a endpoint ipn:1.2 q # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, tcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at the loopback IP address. # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. #a induct stcp 127.0.0.1:4556 stcpcli a induct stcp localhost.localdomain:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the localhost IP using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. #a outduct stcp 127.0.0.1:4556 stcpclo a outduct stcp localhost.localdomain:4556 stcpclo # Start the Daemons. s ## end bpadmin ## begin ipnadmin # ipnrc configuration file for the loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, July 2009 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # Transmission should use the stcp convergence layer for 127.0.0.1:4556 # See your bprc file or bpadmin for outducts/protocols you can use. #a plan 1 stcp/127.0.0.1:4556 a plan 1 stcp/localhost.localdomain:4556 ## end ipnadmin ## begin ionsecadmin 1 e 1 a bspbabrule ipn:1.* ipn:1.* 'HMAC-SHA1' testkey a key 'testkey' testkey.bin ## end ionsecadmin ion-3.2.0~dfsg1.orig/configs/bsp-loopback/testkey.bin0000644000175000017500000000040012260400056021046 0ustar l3onl3onܻ`Gu*]Bzq6˗4:*4|hӖ$V}5i0"e6x)mBTF4*uP,Ƨ'KdTSx2: $?K5+~Ifr6H@ŗetݲ kP<:g4q#/˻Х[)^ C5T&231T4tߞ85}aO7swtt*eGJeC!aq:cion-3.2.0~dfsg1.orig/configs/bsp-loopback/stcp_ion2.rc0000644000175000017500000000742012260400056021123 0ustar l3onl3on## File created by /usr/local/bin/ionscript ## Tue Jul 14 13:56:36 EDT 2009 ## Run the following command to start ION node: ## % ionstart -I "loopback.rc" ## begin ionadmin # ionrc configuration file for loopback test. # This uses stcp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, July 2009 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 2 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin bpadmin # bprc configuration file for the loopback test. # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, July 2009 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). # Note that the custodian endpoint "ipn:1.0" is automatically generated. a endpoint ipn:2.1 q a endpoint ipn:2.2 q # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, tcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at the loopback IP address. # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. #a induct stcp 127.0.0.1:4556 stcpcli a induct stcp ion-2:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the localhost IP using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. #a outduct stcp 127.0.0.1:4556 stcpclo a outduct stcp ion-2:4556 stcpclo a outduct stcp ion-1:4556 stcpclo # Start the Daemons. s ## end bpadmin ## begin ipnadmin # ipnrc configuration file for the loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, July 2009 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # Transmission should use the stcp convergence layer for 127.0.0.1:4556 # See your bprc file or bpadmin for outducts/protocols you can use. #a plan 1 stcp/127.0.0.1:4556 a plan 1 stcp/ion-1:4556 a plan 2 stcp/ion-2:4556 ## end ipnadmin ## begin ionsecadmin 1 e 2 a bspbabrule ipn:1.* ipn:1.* 'HMAC-SHA1' testkey a bspbabrule ipn:2.* ipn:2.* 'HMAC-SHA1' testkey a key 'testkey' testkey.bin ## end ionsecadmin ion-3.2.0~dfsg1.orig/configs/bsp-loopback/README0000644000175000017500000000016712260400056017556 0ustar l3onl3onNote: The ion1/ion2 rc files assume that ion-1, and ion-2 are in the /etc/hosts file for each machine, respectively. ion-3.2.0~dfsg1.orig/configs/bsp-loopback/bsp+ltp_loopback.rc0000644000175000017500000001332312260400056022453 0ustar l3onl3on ## begin ionadmin # ionrc configuration file for loopback test. # This uses ltp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, July 2009 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin ltpadmin # ltprc configuration file for the loopback test. # Command: % ltpadmin loopback.ltprc # This command should be run AFTER ionadmin and BEFORE bpadmin. # # Ohio University, July 2009 # # A warning: the ltp configuration is not ideal in this case. # please consult manual pages and other documentation for a # better description. # Initialization command (command 1). # Establishes the LTP retransmission window. # (Prohibiting LTP from seizing all available storage). # A maximum of 32 sessions. A session is assumed to be around one # second of transmission. This value should be estimated at the sum # of maximum round-trip times (in seconds) for all "spans." # Suggest throwing 20% higher number of sessions to account for extra- # long sessions which contain an actual retransmission. # Set a total LTP memory space usage limit as the sum of the memory # space usage of all spans (more or less the number of bytes in transit # on all links for their duration). 1 128 262144 # Add a span. (a connection) # Identify the span as engine number 1. That is the ipn node number # of the node on the other end of this span. # Use 128 as the maximum number of export sessions. # Use 1024 as the maximum size of an export block. This more or less # limits the maximum size of a bundle in the system. # The next two items are the maximum number of import sessions and the # maximum size of an imported block. Since this is loopback, we just # copy the export numbers here. # 1024 is the maximum segment size- more or less, the amount of data # that can be held in a single frame of the underlying protocol. In # this case, UDP packets are the frame, and we will give a conservative # limit. # Limit the aggregation size to 1024 bytes, and set a time limit on # aggregation to 1 second. # Use the command 'udplso localhost:1113' to implement the link # itself. In this case, we use udp to connect to localhost (this is # loopback) using port 1113 (defined by IANA as the default UDP port # for Licklider Transmission Protocol). The single quote is # important, don't use double quotes. a span 1 128 1024 128 1024 1024 1024 1 'udplso localhost:1113' # Start command. # This command actually runs the link service output commands # (defined above, in the "a span" commands). # Also starts the link service INPUT task 'udplsi localhost:1113' to # listen locally on UDP port 1113 for incoming LTP traffic. s 'udplsi localhost:1113' ## end ltpadmin ## begin bpadmin # bprc configuration file for the loopback test. # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). # Note that the custodian endpoint ipn:1.0 is automatically generated. a endpoint ipn:1.1 q a endpoint ipn:1.2 q # Add a protocol. # Add the protocol named ltp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, udp on ethernet) for payload, and 100 bytes for overhead. a protocol ltp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # induct). # The induct itself is implemented by the 'ltpcli' command. a induct ltp 1 ltpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # outduct). # The outduct itself is implemented by the 'ltpclo' command. a outduct ltp 1 ltpclo # Start the daemons s ## end bpadmin ## begin ipnadmin # ipnrc configuration file for the loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # The plan is to queue for transmission (x) on protocol 'ltp' using # the outduct identified as '1.' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 ltp/1 ## end ipnadmin ## begin ionsecadmin 1 e 1 a bspbabrule ipn:1.* ipn:1.* 'HMAC-SHA1' testkey a key 'testkey' testkey.bin ## end ionsecadmin ion-3.2.0~dfsg1.orig/configs/bsp-loopback/stcp_ion1.rc0000644000175000017500000000742012260400056021122 0ustar l3onl3on## File created by /usr/local/bin/ionscript ## Tue Jul 14 13:56:36 EDT 2009 ## Run the following command to start ION node: ## % ionstart -I "loopback.rc" ## begin ionadmin # ionrc configuration file for loopback test. # This uses stcp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, July 2009 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin bpadmin # bprc configuration file for the loopback test. # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, July 2009 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). # Note that the custodian endpoint "ipn:1.0" is automatically generated. a endpoint ipn:1.1 q a endpoint ipn:1.2 q # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, tcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at the loopback IP address. # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. #a induct stcp 127.0.0.1:4556 stcpcli a induct stcp ion-1:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the localhost IP using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. #a outduct stcp 127.0.0.1:4556 stcpclo a outduct stcp ion-2:4556 stcpclo a outduct stcp ion-1:4556 stcpclo # Start the Daemons. s ## end bpadmin ## begin ipnadmin # ipnrc configuration file for the loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, July 2009 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # Transmission should use the stcp convergence layer for 127.0.0.1:4556 # See your bprc file or bpadmin for outducts/protocols you can use. #a plan 1 stcp/127.0.0.1:4556 a plan 1 stcp/ion-1:4556 a plan 2 stcp/ion-2:4556 ## end ipnadmin ## begin ionsecadmin 1 e 1 a bspbabrule ipn:1.* ipn:1.* 'HMAC-SHA1' testkey a bspbabrule ipn:2.* ipn:2.* 'HMAC-SHA1' testkey a key 'testkey' testkey.bin ## end ionsecadmin ion-3.2.0~dfsg1.orig/configs/ion-dtn2-example/0000755000175000017500000000000012260400056017401 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/ion-dtn2-example/dtn2-host.conf0000644000175000017500000001300712260400056022073 0ustar l3onl3on# # dtn.conf # # Default configuration file for Internet-connected DTN nodes. The # daemon uses a tcl interpreter to parse this file, thus any standard # tcl commands are valid, and all settings are get/set using a single # 'set' functions as: set # log /dtnd info "dtnd parsing configuration..." ######################################## # # Daemon Console Configuration # ######################################## # # console set stdio [ true | false ] # # If set to false, disable the interactive console on stdin/stdout. # The default is set to true (unless the dtnd process is run as a # daemon). # # console set stdio false # # console set addr # console set port # # Settings for the socket based console protocol. # (this interprets user commands) # console set addr 127.0.0.1 console set port 5050 # # console set prompt # # Set the prompt string. Helps if running multiple dtnd's # set shorthostname [lindex [split [info hostname] .] 0] console set prompt "$shorthostname dtn% " ######################################## # # Storage Configuration # ######################################## # # storage set type [ berkeleydb | external | memorydb ] # # Set the storage system to be used # storage set type berkeleydb # the following are for use with external data stores # # The server port to connect to (on localhost) # Note that 62345 has no special significance -- chosen randomly storage set server_port 62345 # The external data store schema location, which can be # found in dtn2/oasys/storage/DS.xsd. storage set schema /etc/DS.xsd # # Do a runtime check for the standard locations for the persistent # storage directory # set dbdir "" foreach dir {/var/dtn /var/tmp/dtn} { if {[file isdirectory $dir]} { set dbdir $dir break } } if {$dbdir == ""} { puts stderr "Must create /var/dtn or /var/tmp/dtn storage directory" exit 1 } # # storage set payloaddir # # Set the directory to be used for bundle payload files # #storage set payloaddir $dbdir/bundles storage set payloaddir /home/mrajan/work/irg/dtn2/test/dtn/bundles # # storage set dbname # # Set the database name (appended with .db as the filename in berkeley # db, used as-is for SQL variants # storage set dbname DTN # # storage set dbdir # # # When using berkeley db, set the directory to be used for the # database files and the name of the files and error log. # #storage set dbdir $dbdir/db storage set dbdir /home/mrajan/work/irg/dtn2/test/dtn/db ######################################## # # Routing configuration # ######################################## # # Set the algorithm used for dtn routing. # # route set type [static | flood | neighborhood | linkstate | external] # route set type static # # route local_eid # # Set the local administrative id of this node. The default just uses # the internet hostname plus the appended string ".dtn" to make it # clear that the hostname isn't really used for DNS lookups. # route local_eid "dtn://[info hostname].dtn" # # External router specific options # # route set server_port 8001 # route set hello_interval 30 # route set schema "/etc/router.xsd" ######################################## # # TCP convergence layer configuration # ######################################## # # interface add [name] [CL] # # Add an input interface to listen on addr:port for incoming bundles # from other tcp / udp convergence layers # # For IP-based interfaces, interfaces listen on INADDR_ANY port 4556 # by default. These can be overridden by using the local_addr and/or # local_port arguments. interface add tcp0 tcp #interface add udp0 udp local_addr=10.1.1.7 local_port=4556 # # link add # # Add a link to a peer node. # # For IP-based links (tcp or udp), the nexthop should contain a DNS # hostname or IP address, followed optionally by a : and a port. If # the port is not specified, the default of 4556 is used. # # e.g. link add link1 dtn.dtnrg.org ONDEMAND tcp # link add link2 dtn2.dtnrg.org:10000 ONDEMAND tcp link add link_tcp 10.1.1.8:4556 ONDEMAND tcp # # route add # # Add a route to the given bundle endpoint id pattern using the # specified link name or peer endpoint. # # e.g. route add dtn://host.domain/* tcp0 route add dtn://host1.dtn/* link_tcp ######################################## # # Service discovery # ######################################## # # discovery add # discovery announce # # Add a local neighborhood discovery module # # e.g. discovery add discovery_bonjour bonjour ######################################## # # Parameter Tuning # ######################################## # # Set the size threshold for the daemon so any bundles smaller than this # size maintain a shadow copy in memory to minimize disk accesses. # # param set payload_mem_threshold 16384 # # Test option to keep all bundle files in the filesystem, even after the # bundle is no longer present at the daemon. # # param set payload_test_no_remove true # # Set the size for which the tcp convergence layer sends partial reception # acknowledgements. Used with reactive fragmentation # # param set tcpcl_partial_ack_len 4096 # # Set if bundles are automatically deleted after transmission # # param set early_deletion true # (others exist but are not fully represented here) log /dtnd info "dtnd configuration parsing complete" ## emacs settings to use tcl-mode by default ## Local Variables: *** ## mode:tcl *** ## End: *** ion-3.2.0~dfsg1.orig/configs/ion-dtn2-example/ion-host.rc0000644000175000017500000000306612260400056021474 0ustar l3onl3on ## begin ionadmin # Initialization command 1 1 "" # Start ION s # Add contacts (1-2 connected for 1 hr, 100 kbps) a contact +1 +3600 1 1 100000 a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 # Assign ranges (for the next hour, 1 second or less OWLT) a range +1 +3600 1 1 1 a range +1 +3600 1 2 1 a range +1 +3600 2 2 1 # Assign production/consumption rates (dummy) m production 100000 m consumption 100000 ## end ionadmin ## begin bpadmin 1 # Add scheme (DTN w/EIDs) a scheme dtn 'dtn2fw' 'dtn2adminep' # the scheme will use the "gethostname" command and # automatically create the custodian eid dtn://.dtn # NOTE: in this situation, the host was named host1. your # configuration will be different. # Alert ION which endpoints are on this host a endpoint dtn://host1.dtn/sink q a endpoint dtn://host1.dtn/ping q # add the tcp convergence layer and outducts # note that your IPs will be different a protocol tcp 1400 100 a induct tcp 0.0.0.0:4556 tcpcli #loopback outduct a outduct tcp 10.1.1.8:4556 tcpclo # outduct to dtn2 node a outduct tcp 10.1.1.7:4556 tcpclo # start daemons s ## end bpadmin ## begin ipnadmin # this may not be necessary a plan 1 tcp/10.1.1.8:4556 a plan 2 tcp/10.1.1.7:4556 ## end ipnadmin ## begin dtn2admin # note that the "dtn:" is omitted from the routing plans. a plan //host1.dtn x tcp/10.1.1.8:4556 a plan //dtn2box.dtn x tcp/10.1.1.7:4556 # plans support an * character as a wildcard. # a default route would look like this # a plan //* f dtn://dtn2box.dtn # this will use dtn2box.dtn as the "next hop" ## end dtn2admin ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/0000755000175000017500000000000012260400056017072 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host2.ltprc0000644000175000017500000000436612260400056021210 0ustar l3onl3on# ltprc configuration file for host2 in a 3node ltp/stcp test. # Command: % ltpadmin host2.ltprc # This command should be run AFTER ionadmin and BEFORE bpadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Establishes the LTP retransmission window. # (Prohibiting LTP from seizing all available storage). # A maximum of 32 sessions. A session is assumed to be around one # second of transmission. This value should be estimated at the sum # of maximum round-trip times (in seconds) for all "spans." # Suggest throwing 20% higher number of sessions to account for extra- # long sessions which contain an actual retransmission. # Set a block size limit of 131072 bytes. The block size is around # the amount of data expected to be sent in a session. Determine # this with the maximum amount of data (in bytes) transferred in one # second on your fastest available link. 1 32 131072 # Add a span. (a connection) # Identify the span as engine number 1. # Use 1400 byte segments (assuming a standard ethernet frame # underlying this link and accounting for ip/udp/eth header overhead). # Use a nominal block size of 10000 bytes. This is the amount of data # (which can span several bundles) sent in a session. You should # consider this to be the maximum number of bytes sent in one second # on the link. (you can also use the block size limit in the # initialization command). # Use the command 'udplso 10.1.1.1:1113' to implement the link # itself. In this case, we use udp to connect to the local machine # (loopback) using port 1113 (defined by IANA as the default UDP port # for Licklider Transmission Protocol). The single quote is # important, don't use double quotes. a span 1 1400 10000 'udplso 10.1.1.1:1113' # Add another span. (to yourself) # Identify the span as engine number 2. # Use the command 'udplso 10.1.1.2:1113' to implement the link # itself. In this case, we use udp to connect to host2 using the # default port. a span 2 1400 10000 'udplso 10.1.1.2:1113' # Start command. # This command actually runs the link service output commands # (defined above, in the "a span" commands). # Also starts the link service INPUT task 'udplsi 10.1.1.2:1113' to # listen locally on UDP port 1113 for incoming LTP traffic. s 'udplsi 10.1.1.2:1113' ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host1.rc0000644000175000017500000001731012260400056020460 0ustar l3onl3on## File created by ../../ionscript ## Wed Oct 29 17:33:43 EDT 2008 ## Run the following command to start ION node: ## % ionstart -I "host1.rc" ## begin ionadmin # ionrc configuration file for host1 in a 3node stcp/ltp test. # This uses ltp from 1 to 2 and ltp from 2 to 3. # command: % ionadmin host1.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # The network goes 1--2--3 # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 a contact +1 +3600 2 3 100000 a contact +1 +3600 3 2 100000 a contact +1 +3600 3 3 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 1 2 1 a range +1 +3600 2 2 1 a range +1 +3600 2 3 1 a range +1 +3600 3 3 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin ltpadmin # ltprc configuration file for host1 in a 3node ltp/stcp test. # Command: % ltpadmin host1.ltprc # This command should be run AFTER ionadmin and BEFORE bpadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Establishes the LTP retransmission window. # (Prohibiting LTP from seizing all available storage). # A maximum of 32 sessions. A session is assumed to be around one # second of transmission. This value should be estimated at the sum # of maximum round-trip times (in seconds) for all "spans." # Suggest throwing 20% higher number of sessions to account for extra- # long sessions which contain an actual retransmission. # Set a block size limit of 131072 bytes. The block size is around # the amount of data expected to be sent in a session. Determine # this with the maximum amount of data (in bytes) transferred in one # second on your fastest available link. 1 32 131072 # Add a span. (a connection) # Identify the span as engine number 1. # Use 1400 byte segments (assuming a standard ethernet frame # underlying this link and accounting for ip/udp/eth header overhead). # Use a nominal block size of 10000 bytes. This is the amount of data # (which can span several bundles) sent in a session. You should # consider this to be the maximum number of bytes sent in one second # on the link. (you can also use the block size limit in the # initialization command). # Use the command 'udplso 10.1.1.1:1113' to implement the link # itself. In this case, we use udp to connect to the local machine # (loopback) using port 1113 (defined by IANA as the default UDP port # for Licklider Transmission Protocol). The single quote is # important, don't use double quotes. a span 1 1400 10000 'udplso 10.1.1.1:1113' # Add another span. (to host2) # Identify the span as engine number 2. # Use the command 'udplso 10.1.1.2:1113' to implement the link # itself. In this case, we use udp to connect to host2 using the # default port. a span 2 1400 10000 'udplso 10.1.1.2:1113' # Start command. # This command actually runs the link service output commands # (defined above, in the "a span" commands). # Also starts the link service INPUT task 'udplsi 10.1.1.1:1113' to # listen locally on UDP port 1113 for incoming LTP traffic. s 'udplsi 10.1.1.1:1113' ## end ltpadmin ## begin bpadmin # bprc configuration file for host1 in a 3node ltp/stcp test. # Command: % bpadmin host1.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:1.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 1 and service number 0 # (ipn requires custodian service is zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:1.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.0 ipn:1.1 and ipn:1.2 on the local node. # ipn:1.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). a endpoint ipn 1.0 x a endpoint ipn 1.1 x a endpoint ipn 1.2 x # Add a protocol. # Add the protocol named ltp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, udp on ethernet) for payload, and 100 bytes for overhead. a protocol ltp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # induct). # The induct itself is implemented by the 'ltpcli' command. a induct ltp 1 ltpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # outduct). The name should correspond to a span (in your ltprc). # The outduct itself is implemented by the 'ltpclo' command. a outduct ltp 1 ltpclo # NOTE: what happens if 1 does not match the id of an ltp span? # Add an outduct. (send to host2) # Add an outduct to send bundles using the ltp protocol. # The duct's name is 2 (this is for future changing/deletion of the # outduct). The name should correpsond to a span (in your ltprc). # The outduct itself is implemented by the 'ltpclo' command. a outduct ltp 2 ltpclo ## end bpadmin ## begin ipnadmin # ipnrc configuration file for host1 in a 3node ltp/stcp test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host1.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:1.0) called 'admin.' # Add service 1 (ipn:1.1) called 'test1.' # Add service 2 (ipn:1.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # This element is named 'host1.' # The plan is to queue for transmission (x) on protocol 'ltp' using # the outduct identified as '1.' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 host1 x ltp/1 # Add other egress plans. # Bundles for elemetn 2 can be transmitted directly to host2 using # ltp outduct identified as '2.' See bprc file for available outducts # and/or protocols. a plan 2 host2 x ltp/2 # Add a group static route # host 3 is not a neighbor to host1, but it is a neighbor to host2. # send bundles for 3 via 2. a group 3 3 2 ## end ipnadmin ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host2.bprc0000644000175000017500000000650012260400056021002 0ustar l3onl3on# bprc configuration file for host2 in a 3node ltp/stcp test. # Command: % bpadmin host2.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:2.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 2 and service number 0 # (ipn requires custodian service is zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:2.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:2.0 ipn:2.1 and ipn:2.2 on the local node. # ipn:2.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). a endpoint ipn 2.0 x a endpoint ipn 2.1 x a endpoint ipn 2.2 x # Add a protocol. # Add the protocol named ltp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, udp on ethernet) for payload, and 100 bytes for overhead. a protocol ltp 1400 100 # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, stcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the ltp protocol. # The duct's name is 2 (this is for future changing/deletion of the # induct). # The induct itself is implemented by the 'ltpcli' command. a induct ltp 2 ltpcli # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at this host's IP address (private testbed). # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 10.1.1.2:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.2 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.2:4556 stcpclo # Add an outduct. (send to host3) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.3 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.3:4556 stcpclo # Add an outduct. (send to host1) # Add an outduct to send bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # outduct). The name should correpsond to a span (in your ltprc). # The outduct itself is implemented by the 'ltpclo' command. a outduct ltp 1 ltpclo ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host3.rc0000644000175000017500000001316512260400056020466 0ustar l3onl3on## File created by ../../ionscript ## Wed Oct 29 17:33:43 EDT 2008 ## Run the following command to start ION node: ## % ionstart -I "host3.rc" ## begin ionadmin # ionrc configuration file for host3 in a 3node stcp/ltp test. # This uses ltp from 1 to 2 and ltp from 2 to 3. # command: % ionadmin host3.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 3 (as in ipn:3). # Use default sdr configuration (empty configuration file name ""). 1 3 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # The network goes 1--2--3 # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 a contact +1 +3600 2 3 100000 a contact +1 +3600 3 2 100000 a contact +1 +3600 3 3 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 1 2 1 a range +1 +3600 2 2 1 a range +1 +3600 2 3 1 a range +1 +3600 3 3 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin bpadmin # bprc configuration file for host3 in a 3node ltp/stcp test. # Command: % bpadmin host3.bprc # This command should be run AFTER ionadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:3.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 3 and service number 0 # (ipn requires custodian service is zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:3.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:3.0 ipn:3.1 and ipn:3.2 on the local node. # ipn:3.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). a endpoint ipn 3.0 x a endpoint ipn 3.1 x a endpoint ipn 3.2 x # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, stcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at this host's IP address (private testbed). # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 10.1.1.3:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.3 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.3:4556 stcpclo # Add an outduct. (send to host2) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.2 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.2:4556 stcpclo ## end bpadmin ## begin ipnadmin # ipnrc configuration file for host3 in a 3node ltp/stcp test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host3.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:3.0) called 'admin.' # Add service 1 (ipn:3.1) called 'test1.' # Add service 2 (ipn:3.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. (to yourself) # Bundles to be transmitted to element number 3 (that is, yourself). # This element is named 'host3.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.3:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 3 host3 x stcp/10.1.1.3:4556 # Add an egress plan. (to host2) # Bundles to be transmitted to element number 2 (the other node). # This element is named 'host2.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.2:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 2 host2 x stcp/10.1.1.2:4556 # Add a group static route. # Host1 is not a neigbor to host3, but is is a neighbor to host 2; # send bundles for 1 via 2. a group 1 1 2 ## end ipnadmin ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host1.ipnrc0000644000175000017500000000221712260400056021167 0ustar l3onl3on# ipnrc configuration file for host1 in a 3node ltp/tcp test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host1.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:1.0) called 'admin.' # Add service 1 (ipn:1.1) called 'test1.' # Add service 2 (ipn:1.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # This element is named 'host1.' # The plan is to queue for transmission (x) on protocol 'ltp' using # the outduct identified as '1.' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 host1 x ltp/1 # Add other egress plans. # Bundles for elemetn 2 can be transmitted directly to host2 using # ltp outduct identified as '2.' See bprc file for available outducts # and/or protocols. a plan 2 host2 x ltp/2 # Add a group static route # host 3 is not a neighbor to host1, but it is a neighbor to host2. # send bundles for 3 via 2. a group 3 3 2 ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host2.rc0000644000175000017500000002151412260400056020462 0ustar l3onl3on## File created by ../../ionscript ## Wed Oct 29 17:33:43 EDT 2008 ## Run the following command to start ION node: ## % ionstart -I "host2.rc" ## begin ionadmin # ionrc configuration file for host2 in a 3node stcp/ltp test. # This uses ltp from 1 to 2 and ltp from 2 to 3. # command: % ionadmin host2.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 2 (as in ipn:2). # Use default sdr configuration (empty configuration file name ""). 1 2 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # The network goes 1--2--3 # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 a contact +1 +3600 2 3 100000 a contact +1 +3600 3 2 100000 a contact +1 +3600 3 3 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 1 2 1 a range +1 +3600 2 2 1 a range +1 +3600 2 3 1 a range +1 +3600 3 3 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin ltpadmin # ltprc configuration file for host2 in a 3node ltp/stcp test. # Command: % ltpadmin host2.ltprc # This command should be run AFTER ionadmin and BEFORE bpadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Establishes the LTP retransmission window. # (Prohibiting LTP from seizing all available storage). # A maximum of 32 sessions. A session is assumed to be around one # second of transmission. This value should be estimated at the sum # of maximum round-trip times (in seconds) for all "spans." # Suggest throwing 20% higher number of sessions to account for extra- # long sessions which contain an actual retransmission. # Set a block size limit of 131072 bytes. The block size is around # the amount of data expected to be sent in a session. Determine # this with the maximum amount of data (in bytes) transferred in one # second on your fastest available link. 1 32 131072 # Add a span. (a connection) # Identify the span as engine number 1. # Use 1400 byte segments (assuming a standard ethernet frame # underlying this link and accounting for ip/udp/eth header overhead). # Use a nominal block size of 10000 bytes. This is the amount of data # (which can span several bundles) sent in a session. You should # consider this to be the maximum number of bytes sent in one second # on the link. (you can also use the block size limit in the # initialization command). # Use the command 'udplso 10.1.1.1:1113' to implement the link # itself. In this case, we use udp to connect to the local machine # (loopback) using port 1113 (defined by IANA as the default UDP port # for Licklider Transmission Protocol). The single quote is # important, don't use double quotes. a span 1 1400 10000 'udplso 10.1.1.1:1113' # Add another span. (to yourself) # Identify the span as engine number 2. # Use the command 'udplso 10.1.1.2:1113' to implement the link # itself. In this case, we use udp to connect to host2 using the # default port. a span 2 1400 10000 'udplso 10.1.1.2:1113' # Start command. # This command actually runs the link service output commands # (defined above, in the "a span" commands). # Also starts the link service INPUT task 'udplsi 10.1.1.2:1113' to # listen locally on UDP port 1113 for incoming LTP traffic. s 'udplsi 10.1.1.2:1113' ## end ltpadmin ## begin bpadmin # bprc configuration file for host2 in a 3node ltp/stcp test. # Command: % bpadmin host2.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:2.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 2 and service number 0 # (ipn requires custodian service is zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:2.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:2.0 ipn:2.1 and ipn:2.2 on the local node. # ipn:2.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). a endpoint ipn 2.0 x a endpoint ipn 2.1 x a endpoint ipn 2.2 x # Add a protocol. # Add the protocol named ltp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, udp on ethernet) for payload, and 100 bytes for overhead. a protocol ltp 1400 100 # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, stcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the ltp protocol. # The duct's name is 2 (this is for future changing/deletion of the # induct). # The induct itself is implemented by the 'ltpcli' command. a induct ltp 2 ltpcli # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at this host's IP address (private testbed). # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 10.1.1.2:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.2 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.2:4556 stcpclo # Add an outduct. (send to host3) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.3 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.3:4556 stcpclo # Add an outduct. (send to host1) # Add an outduct to send bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # outduct). The name should correpsond to a span (in your ltprc). # The outduct itself is implemented by the 'ltpclo' command. a outduct ltp 1 ltpclo ## end bpadmin ## begin ipnadmin # ipnrc configuration file for host2 in a 3node ltp/stcp test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host2.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:2.0) called 'admin.' # Add service 1 (ipn:2.1) called 'test1.' # Add service 2 (ipn:2.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. (to yourself) # Bundles to be transmitted to element number 2 (that is, yourself). # This element is named 'host2.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.2:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 2 host2 x stcp/10.1.1.2:4556 # Add an egress plan. (to host3) # Bundles to be transmitted to element number 3 (the other node). # This element is named 'host3.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.3:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 3 host3 x stcp/10.1.1.3:4556 # Add an egress plan. (to host1) # Bundles to be transmitted to element number 1. # This element is named 'host1.' # The plan is to queue for transmission (x) on protocol 'ltp' using # the outduct identified as '1.' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 host1 x ltp/1 ## end ipnadmin ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host3.ipnrc0000644000175000017500000000250612260400056021172 0ustar l3onl3on# ipnrc configuration file for host3 in a 3node ltp/stcp test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host3.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:3.0) called 'admin.' # Add service 1 (ipn:3.1) called 'test1.' # Add service 2 (ipn:3.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. (to yourself) # Bundles to be transmitted to element number 3 (that is, yourself). # This element is named 'host3.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.3:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 3 host3 x stcp/10.1.1.3:4556 # Add an egress plan. (to host2) # Bundles to be transmitted to element number 2 (the other node). # This element is named 'host2.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.2:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 2 host2 x stcp/10.1.1.2:4556 # Add a group static route. # Host1 is not a neigbor to host3, but is is a neighbor to host 2; # send bundles for 1 via 2. a group 1 1 2 ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host3.ionrc0000644000175000017500000000307712260400056021175 0ustar l3onl3on# ionrc configuration file for host3 in a 3node stcp/ltp test. # This uses ltp from 1 to 2 and ltp from 2 to 3. # command: % ionadmin host3.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 3 (as in ipn:3). # Use default sdr configuration (empty configuration file name ""). 1 3 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # The network goes 1--2--3 # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 a contact +1 +3600 2 3 100000 a contact +1 +3600 3 2 100000 a contact +1 +3600 3 3 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 1 2 1 a range +1 +3600 2 2 1 a range +1 +3600 2 3 1 a range +1 +3600 3 3 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host1.ionrc0000644000175000017500000000307612260400056021172 0ustar l3onl3on# ionrc configuration file for host1 in a 3node tcp/ltp test. # This uses ltp from 1 to 2 and ltp from 2 to 3. # command: % ionadmin host1.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # The network goes 1--2--3 # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 a contact +1 +3600 2 3 100000 a contact +1 +3600 3 2 100000 a contact +1 +3600 3 3 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 1 2 1 a range +1 +3600 2 2 1 a range +1 +3600 2 3 1 a range +1 +3600 3 3 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host3.bprc0000644000175000017500000000505612260400056021010 0ustar l3onl3on# bprc configuration file for host3 in a 3node ltp/stcp test. # Command: % bpadmin host3.bprc # This command should be run AFTER ionadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:3.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 3 and service number 0 # (ipn requires custodian service is zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:3.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:3.0 ipn:3.1 and ipn:3.2 on the local node. # ipn:3.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). a endpoint ipn 3.0 x a endpoint ipn 3.1 x a endpoint ipn 3.2 x # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, stcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen at this host's IP address (private testbed). # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 10.1.1.3:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.3 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.3:4556 stcpclo # Add an outduct. (send to host2) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the IP address 10.1.1.2 using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 10.1.1.2:4556 stcpclo ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host2.ipnrc0000644000175000017500000000276012260400056021173 0ustar l3onl3on# ipnrc configuration file for host2 in a 3node ltp/stcp test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin host2.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, Oct 2008 # Add services # Add service 0 (i.e. ipn:2.0) called 'admin.' # Add service 1 (ipn:2.1) called 'test1.' # Add service 2 (ipn:2.2) called 'test2.' # See your bprc file for endpoint IDs you should use. a service 0 admin a service 1 test1 a service 2 test2 # Add an egress plan. (to yourself) # Bundles to be transmitted to element number 2 (that is, yourself). # This element is named 'host2.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.2:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 2 host2 x stcp/10.1.1.2:4556 # Add an egress plan. (to host3) # Bundles to be transmitted to element number 3 (the other node). # This element is named 'host3.' # The plan is to queue for transmission (x) on protocol 'stcp' using # the outduct identified as '10.1.1.3:4556' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 3 host3 x stcp/10.1.1.3:4556 # Add an egress plan. (to host1) # Bundles to be transmitted to element number 1. # This element is named 'host1.' # The plan is to queue for transmission (x) on protocol 'ltp' using # the outduct identified as '1.' # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 host1 x ltp/1 ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host1.bprc0000644000175000017500000000503612260400056021004 0ustar l3onl3on# bprc configuration file for host1 in a 3node ltp/tcp test. # Command: % bpadmin host1.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Use ipn:1.0 as the custodian endpoint of this node. # That is, scheme IPN with element_number 1 and service number 0 # (ipn requires custodian service is zero). # Note that this EID must be understood by the node itself, so be sure # to add the scheme below. 1 ipn:1.0 # Add an EID scheme. # The scheme's name is ipn. # The scheme's number is 1. Note that this number is defined for # Compressed Bundle Header Encoding (CBHE) schemes ONLY. All other # schemes (dtn for example) should use number -1. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 1 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.0 ipn:1.1 and ipn:1.2 on the local node. # ipn:1.0 is expected for custodian traffic. The rest are usually # used for specific applications (such as bpsink). # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). a endpoint ipn 1.0 x a endpoint ipn 1.1 x a endpoint ipn 1.2 x # Add a protocol. # Add the protocol named ltp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, udp on ethernet) for payload, and 100 bytes for overhead. a protocol ltp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # induct). # The induct itself is implemented by the 'ltpcli' command. a induct ltp 1 ltpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the ltp protocol. # The duct's name is 1 (this is for future changing/deletion of the # outduct). The name should correspond to a span (in your ltprc). # The outduct itself is implemented by the 'ltpclo' command. a outduct ltp 1 ltpclo # NOTE: what happens if 1 does not match the id of an ltp span? # Add an outduct. (send to host2) # Add an outduct to send bundles using the ltp protocol. # The duct's name is 2 (this is for future changing/deletion of the # outduct). The name should correpsond to a span (in your ltprc). # The outduct itself is implemented by the 'ltpclo' command. a outduct ltp 2 ltpclo ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host2.ionrc0000644000175000017500000000307712260400056021174 0ustar l3onl3on# ionrc configuration file for host2 in a 3node stcp/ltp test. # This uses ltp from 1 to 2 and ltp from 2 to 3. # command: % ionadmin host2.ionrc # This command should be run FIRST. # # Ohio University, Oct 2008 # Initialization command (command 1). # Set this node to be node 2 (as in ipn:2). # Use default sdr configuration (empty configuration file name ""). 1 2 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add more contacts. # The network goes 1--2--3 # Note that contacts are unidirectional, so order matters. a contact +1 +3600 1 2 100000 a contact +1 +3600 2 1 100000 a contact +1 +3600 2 2 100000 a contact +1 +3600 2 3 100000 a contact +1 +3600 3 2 100000 a contact +1 +3600 3 3 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # Add more ranges. # We will assume every range is one second. # Note that ranges cover both directions, so you only need define # one range for any combination of nodes. a range +1 +3600 1 2 1 a range +1 +3600 2 2 1 a range +1 +3600 2 3 1 a range +1 +3600 3 3 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ion-3.2.0~dfsg1.orig/configs/3node-stcp-ltp/host1.ltprc0000644000175000017500000000436212260400056021203 0ustar l3onl3on# ltprc configuration file for host1 in a 3node ltp/tcp test. # Command: % ltpadmin host1.ltprc # This command should be run AFTER ionadmin and BEFORE bpadmin. # # Ohio University, Oct 2008 # Initialization command (command 1). # Establishes the LTP retransmission window. # (Prohibiting LTP from seizing all available storage). # A maximum of 32 sessions. A session is assumed to be around one # second of transmission. This value should be estimated at the sum # of maximum round-trip times (in seconds) for all "spans." # Suggest throwing 20% higher number of sessions to account for extra- # long sessions which contain an actual retransmission. # Set a block size limit of 131072 bytes. The block size is around # the amount of data expected to be sent in a session. Determine # this with the maximum amount of data (in bytes) transferred in one # second on your fastest available link. 1 32 131072 # Add a span. (a connection) # Identify the span as engine number 1. # Use 1400 byte segments (assuming a standard ethernet frame # underlying this link and accounting for ip/udp/eth header overhead). # Use a nominal block size of 10000 bytes. This is the amount of data # (which can span several bundles) sent in a session. You should # consider this to be the maximum number of bytes sent in one second # on the link. (you can also use the block size limit in the # initialization command). # Use the command 'udplso 10.1.1.1:1113' to implement the link # itself. In this case, we use udp to connect to the local machine # (loopback) using port 1113 (defined by IANA as the default UDP port # for Licklider Transmission Protocol). The single quote is # important, don't use double quotes. a span 1 1400 10000 'udplso 10.1.1.1:1113' # Add another span. (to host2) # Identify the span as engine number 2. # Use the command 'udplso 10.1.1.2:1113' to implement the link # itself. In this case, we use udp to connect to host2 using the # default port. a span 2 1400 10000 'udplso 10.1.1.2:1113' # Start command. # This command actually runs the link service output commands # (defined above, in the "a span" commands). # Also starts the link service INPUT task 'udplsi 10.1.1.1:1113' to # listen locally on UDP port 1113 for incoming LTP traffic. s 'udplsi 10.1.1.1:1113' ion-3.2.0~dfsg1.orig/configs/loopback-stcp/0000755000175000017500000000000012260400056017057 5ustar l3onl3onion-3.2.0~dfsg1.orig/configs/loopback-stcp/loopback.rc0000644000175000017500000000705512260400056021206 0ustar l3onl3on## File created by /usr/local/bin/ionscript ## Tue Jul 14 13:56:36 EDT 2009 ## Run the following command to start ION node: ## % ionstart -I "loopback.rc" ## begin ionadmin # ionrc configuration file for loopback test. # This uses stcp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, July 2009 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ## end ionadmin ## begin bpadmin # bprc configuration file for the loopback test. # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, July 2009 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). # Note that the custodian endpoint "ipn:1.0" is automatically generated. a endpoint ipn:1.1 q a endpoint ipn:1.2 q # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, tcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 0.0.0.0:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the localhost IP using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 127.0.0.1:4556 stcpclo # Start the Daemons. s ## end bpadmin ## begin ipnadmin # ipnrc configuration file for the loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, July 2009 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # Transmission should use the stcp convergence layer for 127.0.0.1:4556 # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 stcp/127.0.0.1:4556 ## end ipnadmin ## begin ionsecadmin 1 e 1 a bspbabrule ipn:1.* ipn:1.* 'HMAC-SHA1' testkey a key 'testkey' testkey.bin a key 'testkey2' testkey2.bin ## end ionsecadmin ion-3.2.0~dfsg1.orig/configs/loopback-stcp/loopback.ipnrc0000644000175000017500000000076612260400056021717 0ustar l3onl3on# ipnrc configuration file for the loopback test. # Essentially, this is the IPN scheme's routing table. # Command: % ipnadmin loopback.ipnrc # This command should be run AFTER bpadmin (likely to be run last). # # Ohio University, July 2009 # Add an egress plan. # Bundles to be transmitted to element number 1 (that is, yourself). # Transmission should use the stcp convergence layer for 127.0.0.1:4556 # See your bprc file or bpadmin for outducts/protocols you can use. a plan 1 stcp/127.0.0.1:4556 ion-3.2.0~dfsg1.orig/configs/loopback-stcp/loopback.ionrc0000644000175000017500000000173312260400056021711 0ustar l3onl3on# ionrc configuration file for loopback test. # This uses stcp as the primary convergence layer. # command: % ionadmin loopback.ionrc # This command should be run FIRST. # # Ohio University, July 2009 # Initialization command (command 1). # Set this node to be node 1 (as in ipn:1). # Use default sdr configuration (empty configuration file name ""). 1 1 "" # start ion node s # Add a contact. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself # It will transmit 100000 bytes/second. a contact +1 +3600 1 1 100000 # Add a range. This is the physical distance between nodes. # It will start at +1 seconds from now, ending +3600 seconds from now. # It will connect node 1 to itself. # Data on the link is expected to take 1 second to reach the other # end (One Way Light Time). a range +1 +3600 1 1 1 # set this node to consume and produce a mean of 1000000 bytes/second. m production 1000000 m consumption 1000000 ion-3.2.0~dfsg1.orig/configs/loopback-stcp/loopback.bprc0000644000175000017500000000327712260400056021532 0ustar l3onl3on# bprc configuration file for the loopback test. # Command: % bpadmin loopback.bprc # This command should be run AFTER ionadmin and ltpadmin and # BEFORE ipnadmin or dtnadmin. # # Ohio University, July 2009 # Initialization command (command 1). 1 # Add an EID scheme. # The scheme's name is ipn. # This scheme's forwarding engine is handled by the program 'ipnfw.' # This scheme's administration program (acting as the custodian # daemon) is 'ipnadminep.' a scheme ipn 'ipnfw' 'ipnadminep' # Add endpoints. # Establish endpoints ipn:1.1 and ipn:1.2 on the local node. # The behavior for receiving a bundle when there is no application # currently accepting bundles, is to queue them 'q', as opposed to # immediately and silently discarding them (use 'x' instead of 'q' to # discard). # Note that the custodian endpoint "ipn:1.0" is automatically generated. a endpoint ipn:1.1 q a endpoint ipn:1.2 q # Add a protocol. # Add the protocol named stcp. # Estimate transmission capacity assuming 1400 bytes of each frame (in # this case, tcp on ethernet) for payload, and 100 bytes for overhead. a protocol stcp 1400 100 # Add an induct. (listen) # Add an induct to accept bundles using the stcp protocol. # The induct will listen on port 4556, the IANA assigned default DTN # TCP convergence layer port. # The induct itself is implemented by the 'stcpcli' command. a induct stcp 0.0.0.0:4556 stcpcli # Add an outduct. (send to yourself) # Add an outduct to send bundles using the stcp protocol. # The outduct will connect to the localhost IP using the # IANA assigned default DTN TCP port of 4556. # The outduct itself is implemented by the 'stcpclo' command. a outduct stcp 127.0.0.1:4556 stcpclo # Start the Daemons. s ion-3.2.0~dfsg1.orig/doc/0000755000175000017500000000000012271475337013453 5ustar l3onl3onion-3.2.0~dfsg1.orig/doc/psjoin0000755000175000017500000001203412260400056014663 0ustar l3onl3on#!/usr/bin/perl # # psjoin - concatenate PostScript files # # version 0.2, 2002-07-18 # version 0.3, 2003-11-30 # # by Tom Sato , http://homepage3.nifty.com/tsato/ # License: Public Domain $force_even = 0; $force_save = 0; $dont_strip = 0; $save = "save %psjoin\n"; $restore = "restore %psjoin\n"; while ($ARGV[0] =~ /^-[a-z]/i) { if ($ARGV[0] eq "-a") { $force_even = 1; shift; } elsif ($ARGV[0] eq "-s") { $force_save = 1; $save = "/#psjoin-save# save def %psjoin\n"; $restore = "#psjoin-save# restore %psjoin\n"; shift; } elsif ($ARGV[0] eq "-p") { $dont_strip = 1; shift; } elsif ($ARGV[0] eq "-h") { print STDERR "psjoin - concatenate PostScript files (version 0.3)\n"; print STDERR "by Tom Sato ,"; print STDERR " http://member.nifty.ne.jp/tsato/\n\n"; print STDERR "Usage: psjoin [ options... ] filenames...\n\n"; print STDERR "Option:\n"; print STDERR " -a: align first page of each documents to odd page\n"; print STDERR " -s: try to close unclosed save operators\n"; print STDERR " -p: not strip prolog/trailer of the input files\n"; print STDERR " -h: display this\n"; exit 0; } else { print STDERR "$0: unknown option: $ARGV[0]\n"; print STDERR "(\"$0 -h\" for short description)\n"; exit 2; } } shift if $ARGV[0] eq "--"; if ($dont_strip) { $prolog_inx = 9999; $prolog[$prolog_inx] = "% [ psjoin: don't strip ]\n"; $trailer[$prolog_inx] = "% [ psjoin: don't strip ]\n"; } else { for ($i = 0; $i <= $#ARGV; $i++) { open(IN, $ARGV[$i]) || die "$0: can't open \"$ARGV[$i]\" ($!)"; $in_comment = 1; $in_prolog = 1; $in_trailer = 0; $comments[$i] = ""; $prolog[$i] = ""; $trailer[$i] = ""; $pages[$i] = 0; while () { next if /^%%BeginDocument/ .. /^%%EndDocument/; if ($in_comment) { next if /^%!PS-Adobe-/; next if /^%%Title/; next if /^%%Pages/; next if /^%%Creator/; $in_comment = 0 if /^%%EndComments/; $comments[$i] .= $_; next; } elsif ($in_prolog) { if (/^%%Page:/) { $in_prolog = 0; } else { $prolog[$i] .= $_; next; } } $in_trailer = 1 if /^%%Trailer/; if ($in_trailer) { $trailer[$i] .= $_; next; } $pages[$i]++ if /^%%Page:/; } close(IN); if ($prolog[$i]) { for ($j = 0; $j < $i; $j++) { if ($prolog[$j] eq $prolog[$i]) { $pages[$j] += $pages[$i]; break; } } } } $largest = 0; $prolog_inx = 0; for ($i = 0; $i <= $#ARGV; $i++) { $size = length($prolog[$i]) * $pages[$i]; if ($largest < $size) { $largest = $size; $prolog_inx = $i; } } } print "%!PS-Adobe-3.0\n"; print "%%Title: @ARGV\n"; print "%%Creator: psjoin 0.2\n"; print "%%Pages: (atend)\n"; print $comments[$prolog_inx]; print "\n"; print $prolog[$prolog_inx]; for ($i = 0; $i <= $#ARGV; $i++) { $prolog[$i] =~ s/^%%/% %%/; $prolog[$i] =~ s/\n%%/\n% %%/g; $trailer[$i] =~ s/^%%/% %%/; $trailer[$i] =~ s/\n%%/\n% %%/g; } $total_pages = 0; for ($i = 0; $i <= $#ARGV; $i++) { print "\n"; print "% [ psjoin: file = $ARGV[$i] ]\n"; if ($prolog[$i] ne $prolog[$prolog_inx]) { print "% [ psjoin: Prolog/Trailer will be inserted to every page ]\n"; } else { print "% [ psjoin: common Prolog/Trailer will be used ]\n"; } $in_comment = 1 if !$dont_strip; $in_prolog = 1 if !$dont_strip; $in_trailer = 0; $saved = 0; $pages = 0; open(IN, $ARGV[$i]) || die "$0: can't open \"$ARGV[$i]\" ($!)"; while () { if (/^%%BeginDocument/ .. /^%%EndDocument/) { # s/^(%[%!])/% \1/; print $_; } else { if ($in_comment) { $in_comment = 0 if /^%%EndComments/; } elsif ($in_prolog) { if (/^%%Page:/) { $in_prolog = 0; } else { next; } } $in_trailer = 1 if !$dont_strip && /^%%Trailer/; next if $in_trailer; if (/^%%Page:/) { if ($saved) { print $trailer[$i]; print $restore; $saved = 0; } $pages++; $total_pages++; print "\n"; print "%%Page: ($i-$pages) $total_pages\n"; if ($prolog[$i] ne $prolog[$prolog_inx]) { print $save; print $prolog[$i]; $saved = 1; } elsif ($force_save) { print $save; } } else { s/^(%[%!])/% \1/; print $_; } } } close(IN); if ($force_even && $pages % 2 != 0) { $pages++; $total_pages++; print "\n"; print "%%Page: ($i-E) $total_pages\n"; print "% [ psjoin: empty page inserted to force even pages ]\n"; print "showpage\n"; } if ($saved) { print $trailer[$i]; print $restore; } elsif ($force_save) { print $restore; } } print "\n"; print "%%Trailer\n"; print $trailer[$prolog_inx]; print "%%Pages: $total_pages\n"; print "%%EOF\n"; ion-3.2.0~dfsg1.orig/Makefile.winion0000755000175000017500000000066212260400055015636 0ustar l3onl3onall: gmake -C ici $@ gmake -C ici install gmake -C ltp $@ gmake -C ltp install gmake -C dgr $@ gmake -C dgr install gmake -C bp $@ gmake -C bp install gmake -C ams $@ gmake -C ams install gmake -C cfdp $@ gmake -C cfdp install gmake -C bss $@ gmake -C bss install clean: gmake -C ici $@ gmake -C ltp $@ gmake -C dgr $@ gmake -C bp $@ gmake -C ams $@ gmake -C cfdp $@ gmake -C bss $@ test: cd tests ./runtests ion-3.2.0~dfsg1.orig/dgr/0000755000175000017500000000000012260400056013442 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/i86-mingw/0000755000175000017500000000000012260400056015167 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/i86-mingw/Makefile0000644000175000017500000000334412260400056016633 0ustar l3onl3onINCL = ../include API = ../library TEST = ../test # OPT = -g -Wall -Dmingw -DINITIAL_RETARD=2 OPT = -g -Wall -Dmingw CC = gcc $(OPT) -I$(API) -I$(TEST) -I$(INCL) -I$(ROOT)/include LDFLAGS = -fPIC -shared LD = gcc $(LDFLAGS) LIBDGROBJS = \ libdgr.o PUBINCLS = \ $(INCL)/dgr.h RUNTIMES = file2dgr dgr2file file2tcp tcp2file # file2udp udp2file ALL = check libdgr.dll $(RUNTIMES) all: $(ALL) check: $(PUBINCLS) rm -f *.o touch check clean: rm -f *.o rm -f *.exe rm -f $(ALL) rm -f ./lib/* rm -f ./bin/* install: cp ../include/* $(ROOT)/include cp lib/* $(ROOT)/lib cp bin/* $(ROOT)/bin # - - Test executables - - - - file2dgr: file2dgr.o libdgr.dll $(TEST)/file2dgr.h $(CC) -o file2dgr file2dgr.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread -lws2_32 cp file2dgr ./bin dgr2file: dgr2file.o libdgr.dll $(TEST)/file2dgr.h $(CC) -o dgr2file dgr2file.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread -lws2_32 cp dgr2file ./bin tcp2file: tcp2file.o $(TEST)/file2tcp.h $(CC) -o tcp2file tcp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread -lws2_32 cp tcp2file ./bin file2tcp: file2tcp.o $(TEST)/file2tcp.h $(CC) -o file2tcp file2tcp.o -L$(ROOT)/lib -L./lib -lici -lpthread -lws2_32 cp file2tcp ./bin udp2file: udp2file.o $(TEST)/file2udp.h $(CC) -o udp2file udp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread -lws2_32 cp udp2file ./bin file2udp: file2udp.o $(TEST)/file2udp.h $(CC) -o file2udp file2udp.o -L$(ROOT)/lib -L./lib -lici -lpthread -lws2_32 cp file2udp ./bin # - - Libraries - - - - - libdgr.dll: $(LIBDGROBJS) $(LD) -o libdgr.dll $(LIBDGROBJS) -L$(ROOT)/lib -lici -lpthread -lws2_32 cp libdgr.dll ./lib # - - Object modules - - - - - %.o: $(API)/%.c $(CC) -c $< %.o: $(TEST)/%.c $(CC) -c $< ion-3.2.0~dfsg1.orig/dgr/doc/0000755000175000017500000000000012260400056014207 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/doc/Makefile0000644000175000017500000000142012260400056015644 0ustar l3onl3onPODM1 = pod2man -s 1 -c "DGR executables" PODM3 = pod2man -s 3 -c "DGR library functions" PODH = pod2html --noindex MANFILES = \ ./man/man1/dgr2file.1 \ ./man/man1/file2dgr.1 \ ./man/man3/dgr.3 HTMLFILES = \ ./html/man1/dgr2file.html \ ./html/man1/file2dgr.html \ ./html/man3/dgr.html ALL = $(MANFILES) $(HTMLFILES) all: $(ALL) clean: rm -f man/man1/*.1 rm -f man/man3/*.3 rm -f html/man1/*.html rm -f html/man3/*.html rm -f *.tmp install: cp man/man1/*.1 $(ROOT)/man/man1 cp man/man3/*.3 $(ROOT)/man/man3 # - - Man files - - - - - ./man/man1/%.1: pod1/%.pod $(PODM1) $< $@ ./man/man3/%.3: pod3/%.pod $(PODM3) $< $@ ./html/man1/%.html: pod1/%.pod $(PODH) --infile=$< --outfile=$@ ./html/man3/%.html: pod3/%.pod $(PODH) --infile=$< --outfile=$@ ion-3.2.0~dfsg1.orig/dgr/doc/pod1/0000755000175000017500000000000012260400056015052 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/doc/pod1/dgr2file.pod0000644000175000017500000000346712260400056017266 0ustar l3onl3on=head1 NAME dgr2file - DGR reception test program =head1 SYNOPSIS B =head1 DESCRIPTION B uses DGR to receive multiple copies of the text of a file transmitted by B, writing each copy of the file to the current working directory. The name of each file written by B is file_copy_I, where I is initially zero and is increased by 1 every time B closes the file it is currently writing and opens a new one. Upon receiving a DGR datagram from B, B extracts the content of the datagram (either a line of text from the file that is being transmitted by B or else an EOF string indicating the end of that file). It appends each extracted line of text to the local copy of that file that B is currently writing. When the extracted datagram content is an EOF string (the ASCII text "*** End of the file ***"), B closes the file it is writing, increments I, opens a new copy of the file for writing, and prints the message "working on cycle I." B always receives datagrams at port 2101. =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS =over 4 =item can't open dgr service Operating system error. Check errtext, correct problem, and rerun. =item can't open output file Operating system error. Check errtext, correct problem, and rerun. =item dgr_receive failed Operating system error. Check errtext, correct problem, and rerun. =item can't write to output file Operating system error. Check errtext, correct problem, and rerun. =back =head1 BUGS Report bugs to =head1 SEE ALSO file2dgr(1), dgr(3) ion-3.2.0~dfsg1.orig/dgr/doc/pod1/file2dgr.pod0000644000175000017500000000363612260400056017264 0ustar l3onl3on=head1 NAME file2dgr - DGR transmission test program =head1 SYNOPSIS B I I [I] =head1 DESCRIPTION B uses DGR to send I copies of the text of the file named I to the B process running on the computer identified by I. If not specified (or if less than 1), I defaults to 1. After sending all lines of the file, B sends a datagram containing an EOF string (the ASCII text "*** End of the file ***") before reopening the file and starting transmission of the next copy. When all copies of the file have been sent, B prints a performance report: Bytes sent = I, usec elapsed = I. Sending I bits per second. =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS Diagnostic messages produced by B are written to the ION log file I. =over 4 =item Can't open dgr service. ION system error. Check for earlier diagnostic messages describing the cause of the error; correct problem and rerun. =item Can't open input file Operating system error. Check errtext, correct problem, and rerun. =item Can't acquire DGR working memory. ION system error. Check for earlier diagnostic messages describing the cause of the error; correct problem and rerun. =item Can't reopen input file Operating system error. Check errtext, correct problem, and rerun. =item Can't read from input file Operating system error. Check errtext, correct problem, and rerun. =item dgr_send failed. ION system error. Check for earlier diagnostic messages describing the cause of the error; correct problem and rerun. =back =head1 BUGS Report bugs to =head1 SEE ALSO file2dgr(1), dgr(3) ion-3.2.0~dfsg1.orig/dgr/doc/pod3/0000755000175000017500000000000012260400056015054 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/doc/pod3/dgr.pod0000644000175000017500000001613512260400056016342 0ustar l3onl3on=head1 NAME dgr - Datagram Retransmission system library =head1 SYNOPSIS #include "dgr.h" [see description for available functions] =head1 DESCRIPTION The DGR library is an alternative implementation of a subset of LTP, intended for use over UDP/IP in the Internet; unlike ION's canonical LTP implementation it includes a congestion control mechanism that interprets LTP block transmission failure as an indication of network congestion (not data corruption) and reduces data transmission rate in response. As such, DGR differs from many reliable-UDP systems in two main ways: It uses adaptive timeout interval computation techniques borrowed from TCP to try to avoid introducing congestion into the network. It borrows the concurrent-session model of transmission from LTP (and ultimately from CFDP), rather than waiting for one datagram to be acknowledged before sending the next, to improve bandwidth utilization. At this time DGR is interoperable with other implementations of LTP only when each block it receives is transmitted in a single LTP data segment encapsulated in a single UDP datagram. More complex LTP behavior may be implemented in the future. =over 4 =item int dgr_open(uvast ownEngineId, unsigned in clientSvcId, unsigned short ownPortNbr, unsigned int ownIpAddress, char *memmgrName, Dgr *dgr, DgrRC *rc) Establishes the application's access to DGR communication service. I is the sending LTP engine ID that will characterize segments issued by this DGR service access point. In order to prevent erroneous system behavior, never assign the same LTP engine ID to any two interoperating DGR SAPs. I identifies the LTP client service to which all LTP segments issued by this DGR service access point will be directed. I is the port number to use for DGR service. If zero, a system-assigned UDP port number is used. I is the Internet address of the network interface to use for DGR service. If zero, this argument defaults to the address of the interface identified by the local machine's host name. I is the name of the memory manager (see memmgr(3)) to use for dynamic memory management in DGR. If NULL, defaults to the standard system malloc() and free() functions. I is the location in which to store the service access pointer that must be supplied on subsequent DGR function invocations. I is the location in which to store the DGR return code resulting from the attempt to open this service access point (always DgrOpened). On any failure, returns -1. On success, returns zero. =item void dgr_getsockname(Dgr dgr, unsigned short *portNbr, unsigned int *ipAddress) States the port number and IP address of the UDP socket used for this DGR service access point. =item void dgr_close(Dgr dgr) Reverses dgr_open(), releasing resources where possible. =item int dgr_send(Dgr dgr, unsigned short toPortNbr, unsigned int toIpAddress, int notificationFlags, char *content, int length, DgrRC *rc) Sends the indicated content, of length as indicated, to the remote DGR service access point identified by I and I. The message will be retransmitted as necessary until either it is acknowledged or DGR determines that it cannot be delivered. I, if non-zero, is the logical OR of the notification behaviors requested for this datagram. Available behaviors are DGR_NOTE_FAILED (a notice of datagram delivery failure will issued if delivery of the datagram fails) and DGR_NOTE_ACKED (a notice of datagram delivery success will be issued if delivery of the datagram succeeds). Notices are issued via dgr_receive() that is, the thread that calls dgr_receive() on this DGR service access point will receive these notices interspersed with inbound datagram contents. I of content must be greater than zero and may be as great as 65535, but lengths greater than 8192 may not be supported by the local underlying UDP implementation; to minimize the chance of data loss when transmitting over the internet, length should not exceed 512. I is the location in which to store the DGR return code resulting from the attempt to send the content. On any failure, returns -1 and sets I<*rc> to DgrFailed. On success, returns zero. =item int dgr_receive(Dgr dgr, unsigned short *fromPortNbr, unsigned int *fromIpAddress, char *content, int *length, int *errnbr, int timeoutSeconds, DgrRC *rc) Delivers the oldest undelivered DGR event queued for delivery. DGR events are of two type: (a) messages received from a remote DGR service access point and (b) notices of previously sent messages that DGR has determined either have been or cannot be delivered, as requested in the I parameters provided to the dgr_send() calls that sent those messages. In the former case, dgr_receive() will place the content of the inbound message in I, its length in I, and the IP address and port number of the sender in I and I, and it will set I<*rc> to DgrDatagramReceived and return zero. In the latter case, dgr_receive() will place the content of the affected B message in I and its length in I and return zero. If the event being reported is a delivery success, then DgrDatagramAcknowledged will be placed in I<*rc>. Otherwise, DgrDatagramNotAcknowledged will be placed in I<*rc> and the relevant errno (if any) will be placed in I<*errnbr>. The I buffer should be at least 65535 bytes in length to enable delivery of the content of the received or delivered/undeliverable message. I controls blocking behavior. If I is DGR_BLOCKING (i.e., -1), dgr_receive() will not return until (a) there is either an inbound message to deliver or an outbound message delivery result to report, or (b) the function is interrupted by means of dgr_interrupt(). If I is DGR_POLL (i.e., zero), dgr_receive() returns immediately; if there is currently no inbound message to deliver and no outbound message delivery result to report, the function sets I<*rc> to DgrTimedOut and returns zero. For any other positive value of I, dgr_receive() returns after the indicated number of seconds have lapsed (in which case the returned value of I<*rc> is DgrTimedOut), or when there is a message to deliver or a delivery result to report, or when the function is interrupted by means of dgr_interrupt(), whichever occurs first. When the function returns due to interruption by dgr_interrupt(), the value placed in I<*rc> is DgrInterrupted instead of DgrDatagramReceived. I is the location in which to store the DGR return code resulting from the attempt to receive content. On any I/O error or other unrecoverable system error, returns -1. Otherwise always returns zero, placing DgrFailed in I<*rc> and writing a failure message in the event of an operating error. =item void dgr_interrupt(Dgr dgr) Interrupts a dgr_receive() invocation that is currently blocked. Designed to be called from a signal handler; for this purpose, I may need to be obtained from a static variable. =back =head1 SEE ALSO ltp(3), file2dgr(1), dgr2file(1) ion-3.2.0~dfsg1.orig/dgr/library/0000755000175000017500000000000012260400056015106 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/library/libdgr.c0000644000175000017500000017106212260400056016524 0ustar l3onl3on/* libdgr.c: functions enabling the implementation of DGR applications. Author: Scott Burleigh, JPL Copyright (c) 2003, California Institute of Technology. ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. */ #include "dgr.h" #include "memmgr.h" #ifndef DGRDEBUG #define DGRDEBUG 0 #endif #ifndef DGRWATCHING #define DGRWATCHING 0 #endif #define DGR_DB_ORDER (8) #define DGR_BUCKETS (1 << DGR_DB_ORDER) #define DGR_BIN_COUNT (257) /* Must be prime for hash. */ #define DGR_MAX_DESTS (256) #define DGR_SESNBR_MASK (DGR_BUCKETS - 1) #define DGR_MIN_XMIT (2) #define NBR_OF_OCC_LVLS (3) #define DGR_MAX_XMIT (DGR_MIN_XMIT + NBR_OF_OCC_LVLS) #define DGR_BUF_SIZE (65535) #define MAX_DATA_HDR (58) #define MAX_DATA_SIZE (DGR_BUF_SIZE - MAX_DATA_HDR) #define MTAKE(size) sap->mtake(__FILE__, __LINE__, size) #define MRELEASE(ptr) sap->mrelease(__FILE__, __LINE__, ptr) #ifndef SYS_CLOCK_RES #define SYS_CLOCK_RES 10000 /* Linux (usec per tick) */ #endif #ifndef EPISODE_PERIOD #define EPISODE_PERIOD 100000 /* .1 sec (microseconds) */ #endif #ifndef MAX_BACKLOG #define MAX_BACKLOG 524288 /* .5 MB (bytes) */ #endif #ifndef MIN_TIMEOUT #define MIN_TIMEOUT 2 /* per Stevens (seconds) */ #endif #ifndef MAX_TIMEOUT #define MAX_TIMEOUT 60 /* per Stevens (seconds) */ #endif /* For initial rate control it's usually best to start slow, to * avoid thrashing. So the default retard rate is 10 usec/byte. */ #ifndef INITIAL_RETARD #define INITIAL_RETARD 10 /* microseconds per byte */ #endif /* Initial RTT estimation parameters per Stevens. */ #define INIT_SMOOTHED (0) #define INIT_MRD (750000) /* .75 seconds */ #define INIT_RTT (INIT_SMOOTHED + (4 * INIT_MRD)) static int _watching() { static int watching = DGRWATCHING; return watching; } static int _occupancy(int j) { static int occupancy[NBR_OF_OCC_LVLS]; static int initialized = 0; int i; int factor; if (!initialized) { for (i = 0, factor = 64; i < NBR_OF_OCC_LVLS; i++, factor /= 4) { occupancy[i] = MAX_BACKLOG / factor; } initialized = 1; } return occupancy[j]; } /* DGR is a simplified LTP: each block is transmitted as a * single segment in a single UDP datagram. So each segment * contains all bytes of all service data units in a single * block, so there is a one-to-one correspondence between * segments and sessions. */ typedef struct { /* Segment ID is an LTP session (block) ID. */ uvast engineId; unsigned int sessionNbr; } SegmentId; typedef struct { SegmentId id; char content[1]; } Segment; typedef enum { DgrMsgOut = 1, DgrMsgIn, DgrDeliverySuccess, DgrDeliveryFailure } DgrRecordType; typedef struct { Lyst msgs; /* (DgrRecord *) */ pthread_mutex_t mutex; } DgrArqBucket; typedef struct dgr_rec { DgrRecordType type; /* Refer to destination if outbound, source if inbound. */ unsigned short portNbr; unsigned int ipAddress; /* Relevant only for outbound messages. */ int notificationFlags; int transmissionCount; DgrArqBucket *bucket; LystElt outboundMsgsElt; struct timeval transmitTime; LystElt pendingResendsElt; /* Relevant only for delivery failures. */ int errnbr; /* Common to all types of record. */ int contentLength; Segment segment; } *DgrRecord; typedef struct { SegmentId id; } SendReq; typedef struct { SegmentId id; struct timeval resendTime; } ResendReq; typedef enum { DgrSapClosed = 0, DgrSapOpen, DgrSapDamaged } DgrSapState; typedef struct { int capacity; int serviceLoad; int bytesTransmitted; int bytesAcknowledged; int unusedCapacity; } EpisodeHistory; typedef struct { /* Dests are functionally equivalent to the Spans in * ION's LTP implementation, but entirely volatile. */ unsigned short portNbr; unsigned int ipAddress; int msgsSent; int backlog; /* bytes */ int msgsInBacklog; int lessActiveDest; int moreActiveDest; LystElt ownElt; struct timeval cursorXmitTime; int rttSmoothed; /* microseconds */ int meanRttDeviation; int rttPredicted; /* microseconds */ int predictedResends; /* For congestion avoidance by flow control and * dynamic estimation of sustainable data rate. */ int episodeCount; int bytesOriginated; int meanBytesResent; int bytesTransmitted; int bytesAcknowledged; int serviceLoad; /* bytes sendable */ EpisodeHistory episodes[8]; int currentEpisode; int totalCapacity; int totalServiceLoad; int totalBytesTransmitted; int totalBytesAcknowledged; int totalUnusedCapacity; int retard; /* microseconds per byte */ int bytesToTransmit; int pendingDelay; /* microseconds */ } DgrDest; typedef struct dgrsapst { /* The DgrSAP is roughly equivalent to the LTP database * in ION's LTP implementation, but entirely volatile * and allocated only to a single client service. */ uvast engineId; unsigned int clientSvcId; DgrSapState state; MemAllocator mtake; MemDeallocator mrelease; int udpSocket; pthread_mutex_t sapMutex; pthread_cond_t sapCV; unsigned int sessionNbr; int backlog; /* Total, for all dests. */ Lyst outboundMsgs; /* (SendReq *) */ struct llcv_str outboundCV_str; Llcv outboundCV; Lyst pendingResends; /* (ResendReq *) */ pthread_mutex_t pendingResendsMutex; Lyst inboundEvents; /* (DgrRecord *) */ struct llcv_str inboundCV_str; Llcv inboundCV; DgrArqBucket buckets[DGR_BUCKETS]; pthread_t sender; pthread_t resender; pthread_t receiver; pthread_mutex_t destsMutex; int destsCount; DgrDest dests[DGR_MAX_DESTS]; Lyst destLysts[DGR_BIN_COUNT]; int leastActiveDest; int mostActiveDest; DgrDest defaultDest; char inputBuffer[DGR_BUF_SIZE]; char outputBuffer[DGR_BUF_SIZE]; } DgrSAP; typedef enum { DgrSendMessage = 1, DgrHandleTimeout, DgrHandleRpt } RecordOperation; #if DGRDEBUG /* * * Test instrumentation * * * */ static int originalMsgs; static int resends[DGR_MAX_XMIT - 1]; static int timeouts[DGR_MAX_XMIT]; static int appliedAcks; static int traceMeasuredRtt; static int traceRttDeviation; static int traceRttSmoothed; static int traceMeanRttDeviation; static int traceRttPredicted; static int tracePredictedResends; static int computedRtt; static int traceBytesOriginated; static int traceBytesTransmitted; static int traceBytesAcknowledged; static int traceBytesResent; static int traceUnusedCapacity; static int traceBytesToTransmit; static int traceRetard; static int aggregateDelay; static int rcSnoozes; static void dgrtrace() { char tracebuf[128]; iprintf(tracebuf, sizeof tracebuf, "%7d %7d %7d %7d %7d %7d %7d %7d %7d %3d\n", originalMsgs, resends[0], traceBytesOriginated, traceBytesResent, traceBytesTransmitted, traceUnusedCapacity, traceBytesAcknowledged, timeouts[0], traceBytesToTransmit, traceRetard); PUTS(tracebuf); } #endif /* * * Common utility functions * * */ static void crashThread(DgrSAP *sap, char *msg) { if (sap->state == DgrSapOpen) { sap->state = DgrSapDamaged; } putErrmsg(msg, NULL); } static int time_to_stop(Llcv llcv) { return 1; } /* Hash function adapted from Dr. Dobbs, April 1996. */ static int hashDestId(unsigned short portNbr, unsigned int ipAddress) { struct x { unsigned int ipAddress; unsigned short portNbr; } w; char *name = (char *) &w; int length = sizeof(unsigned int) + sizeof(unsigned short); int i = 0; unsigned int h = 0; unsigned int g = 0; w.ipAddress = ipAddress; w.portNbr = portNbr; for (i = 0; i < length; i++, name++) { h = (h << 4) + *name; g = h & 0xf0000000; if (g) { h ^= g >> 24; } h &= ~g; } return h % DGR_BIN_COUNT; } static DgrDest *findDest(DgrSAP *sap, unsigned short portNbr, unsigned int ipAddress, int *idx) { int bin; LystElt elt; unsigned long i; DgrDest *dest; bin = hashDestId(portNbr, ipAddress); for (elt = lyst_first(sap->destLysts[bin]); elt; elt = lyst_next(elt)) { dest = sap->dests + (i = (unsigned long) lyst_data(elt)); if (dest->ipAddress == ipAddress && dest->portNbr == portNbr) { *idx = i; return dest; } } *idx = -1; return &sap->defaultDest; } static int insertEvent(DgrSAP *sap, DgrRecord rec) { LystElt elt; llcv_lock(sap->inboundCV); if (rec == NULL) /* Interruption. */ { elt = lyst_insert_first(sap->inboundEvents, rec); } else /* Normal event. */ { elt = lyst_insert_last(sap->inboundEvents, rec); } llcv_unlock(sap->inboundCV); if (elt == NULL) { crashThread(sap, "Can't insert event"); return -1; } /* Tell the application that there's an event to handle. */ llcv_signal(sap->inboundCV, llcv_lyst_not_empty); return 0; } /* * * Common operational functions * * */ static void initializeDest(DgrDest *dest, unsigned short portNbr, unsigned int ipAddress) { dest->portNbr = portNbr; dest->ipAddress = ipAddress; dest->rttSmoothed = INIT_SMOOTHED; dest->meanRttDeviation = INIT_MRD; dest->rttPredicted = INIT_RTT; dest->retard = INITIAL_RETARD; dest->bytesToTransmit = EPISODE_PERIOD / dest->retard; #if DGRDEBUG computedRtt = 0; traceMeasuredRtt = 0; traceRttDeviation = 0; traceRttSmoothed = dest->rttSmoothed; traceMeanRttDeviation = dest->meanRttDeviation; traceRttPredicted = dest->rttPredicted; tracePredictedResends = dest->predictedResends; traceRetard = dest->retard; traceBytesToTransmit = dest->bytesToTransmit; #endif } static DgrDest *addNewDest(DgrSAP *sap, unsigned short portNbr, unsigned int ipAddress, int *destIdx) { unsigned long newDest; DgrDest *dest; int nextDest; int bin; if (sap->destsCount < DGR_MAX_DESTS) /* Empty slot. */ { nextDest = DGR_MAX_DESTS - sap->destsCount; newDest = nextDest - 1; dest = sap->dests + newDest; sap->leastActiveDest = newDest; if (sap->destsCount == 0) /* The first one. */ { sap->mostActiveDest = newDest; } sap->destsCount++; } else /* Replace the dest that's currently least active. */ { newDest = sap->leastActiveDest; dest = sap->dests + newDest; lyst_delete(dest->ownElt); nextDest = dest->moreActiveDest; memset((char *) dest, 0, sizeof(DgrDest)); } /* Insert subscript of this location as new entry in * the dests list that this IP address hashes to. */ bin = hashDestId(portNbr, ipAddress); dest->ownElt = lyst_insert_last(sap->destLysts[bin], (void *) newDest); if (dest->ownElt == NULL) { crashThread(sap, "Can't add new active destination"); return NULL; } dest->lessActiveDest = -1; /* New one's least active. */ dest->moreActiveDest = nextDest; initializeDest(dest, portNbr, ipAddress); *destIdx = newDest; return dest; } static void loseOutboundMsg(DgrSAP *sap, DgrRecord rec) { SendReq *req; llcv_lock(sap->outboundCV); req = (SendReq *) lyst_data(rec->outboundMsgsElt); MRELEASE(req); lyst_delete(rec->outboundMsgsElt); llcv_unlock(sap->outboundCV); rec->outboundMsgsElt = NULL; } static void losePendingResend(DgrSAP *sap, DgrRecord rec) { ResendReq *req; pthread_mutex_lock(&sap->pendingResendsMutex); req = (ResendReq *) lyst_data(rec->pendingResendsElt); MRELEASE(req); lyst_delete(rec->pendingResendsElt); rec->pendingResendsElt = NULL; pthread_mutex_unlock(&sap->pendingResendsMutex); } static void removeRecord(DgrSAP *sap, DgrRecord rec, LystElt arqElt) { /* Any pendingResendsElt for this record has already * been deleted. */ if (rec->outboundMsgsElt) { loseOutboundMsg(sap, rec); } lyst_delete(arqElt); /* Remove from database bucket. */ /* Enable more messages to be sent. */ pthread_mutex_lock(&sap->sapMutex); sap->backlog -= (rec->contentLength + sizeof(SegmentId)); if (sap->backlog <= MAX_BACKLOG) { pthread_cond_signal(&sap->sapCV); } pthread_mutex_unlock(&sap->sapMutex); } static void adjustActiveDestChain(DgrSAP *sap, int destIdx) { int ceiling; DgrDest *dest; DgrDest *other = NULL; DgrDest *next; DgrDest *prev; dest = sap->dests + destIdx; ceiling = dest->moreActiveDest; while (ceiling < DGR_MAX_DESTS) { other = sap->dests + ceiling; if (dest->msgsSent <= other->msgsSent) /* ceiling */ { break; } /* Have become more active than this one. */ ceiling = other->moreActiveDest; } if (ceiling != dest->moreActiveDest) /* more active now */ { /* Detach from current neighbors in list. */ if (dest->lessActiveDest == -1) /* currently least */ { sap->leastActiveDest = dest->moreActiveDest; } else /* Not currently the least active dest. */ { prev = sap->dests + dest->lessActiveDest; prev->moreActiveDest = dest->moreActiveDest; } /* (Cannot already be the most active dest.) */ next = sap->dests + dest->moreActiveDest; next->lessActiveDest = dest->lessActiveDest; /* Insert before new ceiling, overtaking another. */ dest->moreActiveDest = ceiling; if (ceiling == DGR_MAX_DESTS) /* now most active */ { dest->lessActiveDest = sap->mostActiveDest; sap->mostActiveDest = destIdx; } else /* Insert before the more active dest. */ { dest->lessActiveDest = other->lessActiveDest; other->lessActiveDest = destIdx; } prev = sap->dests + dest->lessActiveDest; prev->moreActiveDest = destIdx; } } static int insertResendReq(DgrSAP *sap, DgrRecord rec, DgrDest *dest, int destIdx) { ResendReq *req; int rtt; LystElt elt; ResendReq *pending; static int minTimeout = MIN_TIMEOUT * 1000000; static int maxTimeout = MAX_TIMEOUT * 1000000; req = MTAKE(sizeof(ResendReq)); if (req == NULL) { crashThread(sap, "Can't create resend request"); return -1; } req->id.engineId = rec->segment.id.engineId; req->id.sessionNbr = rec->segment.id.sessionNbr; req->resendTime.tv_sec = rec->transmitTime.tv_sec; req->resendTime.tv_usec = rec->transmitTime.tv_usec; /* Locate and apply RTT computation parameters. */ if (rec->transmissionCount > 1) /* Retransmission. */ { if (destIdx < 0) /* Destination not active. */ { rtt = INIT_RTT; /* Default RTT. */ } else /* Dest is active, we predict RTT for it. */ { dest = sap->dests + destIdx; /* Apply exponential backoff to predicted * round-trip time as necessary. */ rtt = dest->rttPredicted << dest->predictedResends; } #if DGRDEBUG resends[rec->transmissionCount - 2]++; #endif } else /* Original transmission, note dest activity. */ { if (destIdx < 0) /* Newly active dest. */ { dest = addNewDest(sap, rec->portNbr, rec->ipAddress, &destIdx); if (dest == NULL) { return -1; } } /* Apply exponential backoff to predicted round- * trip time as necessary. */ rtt = dest->rttPredicted << dest->predictedResends; /* Record activity and reorder dests by level of * activity as necessary. */ dest->backlog += (rec->contentLength + sizeof(SegmentId)); dest->msgsInBacklog++; dest->msgsSent++; adjustActiveDestChain(sap, destIdx); dest->bytesOriginated += rec->contentLength; #if DGRDEBUG traceBytesOriginated = dest->bytesOriginated; originalMsgs++; #endif } dest->bytesTransmitted += rec->contentLength; #if DGRDEBUG traceBytesTransmitted = dest->bytesTransmitted; #endif if (rtt < minTimeout) { rtt = minTimeout; } if (rtt > maxTimeout) { rtt = maxTimeout; } #if DGRDEBUG computedRtt = rtt; #endif /* Compute acknowledgment deadline (resendTime). */ req->resendTime.tv_usec += rtt; while (req->resendTime.tv_usec > 1000000) { req->resendTime.tv_sec += 1; req->resendTime.tv_usec -= 1000000; } /* Now insert the retransmission request into the * pendingResends list, preserving resendTime order. */ pthread_mutex_lock(&sap->pendingResendsMutex); for (elt = lyst_last(sap->pendingResends); elt; elt = lyst_prev(elt)) { pending = (ResendReq *) lyst_data(elt); if (pending->resendTime.tv_sec > req->resendTime.tv_sec) { continue; } if (pending->resendTime.tv_sec < req->resendTime.tv_sec || pending->resendTime.tv_usec <= req->resendTime.tv_usec) { break; /* Found "floor" item. */ } } if (elt) { elt = rec->pendingResendsElt = lyst_insert_after(elt, req); } else { elt = rec->pendingResendsElt = lyst_insert_first(sap->pendingResends, req); } pthread_mutex_unlock(&sap->pendingResendsMutex); if (elt == NULL) { crashThread(sap, "Can't append resend request"); return -1; } return 0; } static int sendMessage(DgrSAP *sap, DgrRecord rec, LystElt arqElt, DgrDest *dest, int destIdx) { unsigned char *cursor; int length; Sdnv sdnv; unsigned int ckptSerialNbr = rand(); struct sockaddr_in socketAddress; struct sockaddr *sockName = (struct sockaddr *) &socketAddress; /* Construct LTP data segment in sap->outputBuffer. */ cursor = (unsigned char *) (sap->outputBuffer); length = 0; /* Version number and segment type. */ *cursor = 3; /* 0000 0011 */ length++; cursor++; /* Engine ID. */ encodeSdnv(&sdnv, rec->segment.id.engineId); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* SessionNbr. */ encodeSdnv(&sdnv, rec->segment.id.sessionNbr); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Extension lengths. */ *cursor = 0; /* 0000 0000 */ length++; cursor++; /* Client service ID. */ encodeSdnv(&sdnv, sap->clientSvcId); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Service data offset. */ encodeSdnv(&sdnv, 0); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Service data length. */ encodeSdnv(&sdnv, rec->contentLength); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Checkpoint serial number. */ encodeSdnv(&sdnv, ckptSerialNbr); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Report serial number. */ encodeSdnv(&sdnv, 0); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Data content. */ memcpy(cursor, rec->segment.content, rec->contentLength); length += rec->contentLength; cursor += rec->contentLength; /* Plug current time into record's transmit time. */ getCurrentTime(&(rec->transmitTime)); /* Send the message. Error results returned by sendto * do not crash the thread; eventually the application * will be notified of the delivery failure and take * some action such as closing the SAP. */ socketAddress.sin_family = AF_INET; socketAddress.sin_port = htons(rec->portNbr); socketAddress.sin_addr.s_addr = htonl(rec->ipAddress); if (isendto(sap->udpSocket, sap->outputBuffer, length, 0, sockName, sizeof(struct sockaddr_in)) < 0) { putSysErrmsg("DGR can't send segment", NULL); rec->errnbr = errno; } if (_watching()) { putchar('g'); fflush(stdout); } /* Update record's transmission counter for ARQ control. */ rec->transmissionCount++; /* Delete outboundMsgs object; it's no longer needed. */ loseOutboundMsg(sap, rec); /* We may need to retransmit this record, so tell resender * to schedule retransmission in case acknowledgment is * not received. */ return insertResendReq(sap, rec, dest, destIdx); } static void noteCompletion(DgrRecord rec, DgrDest *dest, int destIdx) { struct timeval arrivalTime; int measuredRtt; int deviation; int negative; /* Boolean */ int adj; int change; /* Update predicted RTT, but only if this is not a * delayed acknowledgement, and only if we can be sure * that the original transmission is the one that has * been acknowledged (else we have the retransmission * ambiguity problem: we can't have any confidence in * computed round-trip time for this segment, so we * can't use that RTT to predict appropriate retransmit * times for future segments). */ getCurrentTime(&arrivalTime); /* At the least, update backlog count to mitigate * maximum transmissions limit. */ dest->backlog -= (rec->contentLength + sizeof(SegmentId)); dest->msgsInBacklog--; if (rec->transmissionCount > 1) { return; /* Might not be ack of most recent xmit. */ } if (rec->transmitTime.tv_sec < dest->cursorXmitTime.tv_sec || (rec->transmitTime.tv_sec == dest->cursorXmitTime.tv_sec && rec->transmitTime.tv_usec < dest->cursorXmitTime.tv_usec)) { return; /* A delayed acknowledgment, somehow. */ } /* Timely acknowledgment of an original transmission to * an active dest. Update retransmission parameters with * acknowledgement information. */ dest->cursorXmitTime.tv_sec = rec->transmitTime.tv_sec; dest->cursorXmitTime.tv_usec = rec->transmitTime.tv_usec; if (arrivalTime.tv_usec < rec->transmitTime.tv_usec) { arrivalTime.tv_usec += 1000000; arrivalTime.tv_sec--; } /* Lifting all of this calculation from Jacobson (1988) * via Stevens (1997). */ measuredRtt = ((arrivalTime.tv_sec - rec->transmitTime.tv_sec) * 1000000) + (arrivalTime.tv_usec - rec->transmitTime.tv_usec); #if DGRDEBUG traceMeasuredRtt = measuredRtt; #endif /* Add 1/8 of deviation to smoothed RTT. */ deviation = measuredRtt - dest->rttSmoothed; #if DGRDEBUG traceRttDeviation = deviation; #endif negative = deviation < 0 ? 1 : 0; deviation = abs(deviation); adj = (deviation >> 3) & 0x1fffffff; if (negative) adj = 0 - adj; dest->rttSmoothed += adj; #if DGRDEBUG traceRttSmoothed = dest->rttSmoothed; #endif /* Add 1/4 of change in deviation to mean deviation. */ change = deviation - dest->meanRttDeviation; negative = change < 0 ? 1 : 0; change = abs(change); adj = (change >> 2) & 0x3fffffff; if (negative) adj = 0 - adj; dest->meanRttDeviation += adj; #if DGRDEBUG traceMeanRttDeviation = dest->meanRttDeviation; #endif /* For new prediction of RTT use smoothed RTT plus four * times the mean deviation. */ dest->rttPredicted = dest->rttSmoothed + (dest->meanRttDeviation << 2); #if DGRDEBUG traceRttPredicted = dest->rttPredicted; #endif dest->predictedResends = 0; #if DGRDEBUG tracePredictedResends = dest->predictedResends; #endif } static int handleRpt(DgrSAP *sap, DgrRecord rec, LystElt arqElt, DgrDest *dest, int destIdx) { #if DGRDEBUG appliedAcks++; #endif if (_watching()) { putchar('h'); fflush(stdout); } dest->bytesAcknowledged += rec->contentLength; /* May want to update predicted RTT if the acknowledging * dest is active enough for us to be trying to predict * accurate RTT. */ if (destIdx >= 0) /* An active destination. */ { noteCompletion(rec, dest, destIdx); } /* Delete pendingResends object; it's now moot. */ losePendingResend(sap, rec); /* Remove record from database; it won't be sent again. */ removeRecord(sap, rec, arqElt); /* If application doesn't want to be notified of delivery * success for this record, just erase it and return. */ if ((rec->notificationFlags & DGR_NOTE_ACKED) == 0) { MRELEASE(rec); return 0; } /* Pass the record back to the application as a delivery * success. */ rec->type = DgrDeliverySuccess; return insertEvent(sap, rec); } static int insertSendReq(DgrSAP *sap, DgrRecord rec) { SendReq *req; LystElt elt; req = MTAKE(sizeof(SendReq)); if (req == NULL) { crashThread(sap, "Can't create send request"); return -1; } req->id.engineId = rec->segment.id.engineId; req->id.sessionNbr = rec->segment.id.sessionNbr; llcv_lock(sap->outboundCV); elt = rec->outboundMsgsElt = lyst_insert_last(sap->outboundMsgs, req); llcv_unlock(sap->outboundCV); if (elt == NULL) { crashThread(sap, "Can't append send request"); return -1; } /* Tell the sender thread that there's something to send. */ llcv_signal(sap->outboundCV, llcv_lyst_not_empty); return 0; } static int handleTimeout(DgrSAP *sap, DgrRecord rec, LystElt arqElt, DgrDest *dest, int destIdx) { int maxTransmissions = 0; int i; #if DGRDEBUG timeouts[rec->transmissionCount - 1]++; #endif if (destIdx >= 0) /* An active destination. */ { /* Update retransmission control if this is * the most up-to-date information on this dest * relationship. * * Because in DGR we do concurrent rather than * sequential transmission to each destination * dest, we can't base our RTT estimation * adjustments on the transmission time of the * most recently transmitted message -- it may * not be useful. In its place, we track the * "cursor" transmission time for the dest: * the transmission time of the message for * which we've got the most recent information, * be it an acknowledgment or a timeout. */ if (rec->transmitTime.tv_sec > dest->cursorXmitTime.tv_sec || (rec->transmitTime.tv_sec == dest->cursorXmitTime.tv_sec && rec->transmitTime.tv_usec >= dest->cursorXmitTime.tv_usec)) { dest->cursorXmitTime.tv_sec = rec->transmitTime.tv_sec; dest->cursorXmitTime.tv_usec = rec->transmitTime.tv_usec; if (rec->transmissionCount > dest->predictedResends) { dest->predictedResends = rec->transmissionCount; #if DGRDEBUG tracePredictedResends = dest->predictedResends; #endif } } /* Adjust transmission limit: diminishes as an * exponential function of increase in backlog * of unacknowledged messages: * * If dest's backlog < this ...then transmission * fraction of max backlog... limit is ... * 1/(2**6 = 64) 5 * 1/(2**4 = 16) 4 * 1/(2**2 = 4) 3 * * If dest's backlog is not less than 1/4 of * the maximum backlog, the maximum number of * transmissions is 2 (that is, original * transmission and one retransmission). */ maxTransmissions = DGR_MAX_XMIT; for (i = 0; i < NBR_OF_OCC_LVLS; i++) { if (dest->backlog < _occupancy(i)) { break; } maxTransmissions--; } if (rec->transmissionCount == maxTransmissions) { /* Record will not be retransmitted, so * remove it from backlog. */ dest->backlog -= (rec->contentLength + sizeof(SegmentId)); dest->msgsInBacklog--; } } /* Delete pendingResends object; sender will insert * a new one if necessary. */ losePendingResend(sap, rec); /* If record has reached the retransmit limit, send it * to the application as a delivery failure. */ if (rec->transmissionCount == maxTransmissions) { /* Remove record from database; it won't be * sent again. */ removeRecord(sap, rec, arqElt); if (_watching()) { putchar('{'); fflush(stdout); } /* If application doesn't want to be notified * of delivery failure for this record, just * erase it and return. */ if ((rec->notificationFlags & DGR_NOTE_FAILED) == 0) { MRELEASE(rec); return 0; } /* Pass the record back to the application as a * delivery failure. */ rec->type = DgrDeliveryFailure; if (rec->errnbr == 0) { rec->errnbr = ETIMEDOUT; } return insertEvent(sap, rec); } /* We're going to transmit this record one more time, * so leave it in its current location in the ARQ bucket * and tell sender to re-send it. */ if (_watching()) { putchar('='); fflush(stdout); } dest->serviceLoad += rec->contentLength; return insertSendReq(sap, rec); } static int arq(DgrSAP *sap, uvast engineId, unsigned int sessionNbr, RecordOperation op) { DgrArqBucket *bucket; LystElt elt; DgrRecord rec; DgrDest *dest; int destIdx; int result; bucket = sap->buckets + (sessionNbr & DGR_SESNBR_MASK); pthread_mutex_lock(&bucket->mutex); pthread_mutex_lock(&sap->destsMutex); if (op == DgrSendMessage) { for (elt = lyst_last(bucket->msgs); elt; elt = lyst_prev(elt)) { rec = (DgrRecord) lyst_data(elt); if (rec->segment.id.engineId > engineId) { continue; } if (rec->segment.id.engineId < engineId) { pthread_mutex_unlock(&sap->destsMutex); pthread_mutex_unlock(&bucket->mutex); return 0; /* What happened? */ } /* Found a match on engine ID. */ if (rec->segment.id.sessionNbr > sessionNbr) { continue; } if (rec->segment.id.sessionNbr < sessionNbr) { pthread_mutex_unlock(&sap->destsMutex); pthread_mutex_unlock(&bucket->mutex); return 0; /* What happened? */ } /* Found the matching record. */ break; } if (elt == NULL) { pthread_mutex_unlock(&sap->destsMutex); pthread_mutex_unlock(&bucket->mutex); return 0; /* What happened? */ } dest = findDest(sap, rec->portNbr, rec->ipAddress, &destIdx); result = sendMessage(sap, rec, elt, dest, destIdx); pthread_mutex_unlock(&sap->destsMutex); pthread_mutex_unlock(&bucket->mutex); return result; } /* Timeout or ACK for previously sent message, so search * from the front of the list rather than the back. */ for (elt = lyst_first(bucket->msgs); elt; elt = lyst_next(elt)) { rec = (DgrRecord) lyst_data(elt); if (rec->segment.id.engineId < engineId) { continue; } if (rec->segment.id.engineId > engineId) { pthread_mutex_unlock(&sap->destsMutex); pthread_mutex_unlock(&bucket->mutex); return 0; /* Record is already gone. */ } /* Found a match on engine ID. */ if (rec->segment.id.sessionNbr < sessionNbr) { continue; } if (rec->segment.id.sessionNbr > sessionNbr) { pthread_mutex_unlock(&sap->destsMutex); pthread_mutex_unlock(&bucket->mutex); return 0; /* Record is already gone. */ } /* Found the matching record. */ break; } if (elt == NULL) { pthread_mutex_unlock(&sap->destsMutex); pthread_mutex_unlock(&bucket->mutex); return 0; /* Record is already gone. */ } dest = findDest(sap, rec->portNbr, rec->ipAddress, &destIdx); if (op == DgrHandleRpt) { result = handleRpt(sap, rec, elt, dest, destIdx); } else { result = handleTimeout(sap, rec, elt, dest, destIdx); } pthread_mutex_unlock(&sap->destsMutex); pthread_mutex_unlock(&bucket->mutex); return result; } static void resetDestActivity(DgrSAP *sap) { int i; DgrDest *dest; int maxActivity; int mostActive; int n; int ceiling; DgrDest *ceilingDest; pthread_mutex_lock(&sap->destsMutex); if (sap->destsCount < DGR_MAX_DESTS) { /* Table is not full, no need to clear out dests * that used to be active but no longer are. */ pthread_mutex_unlock(&sap->destsMutex); return; } /* Time to clean house. First, find the most active dest. */ maxActivity = -1; for (i = 0; i < DGR_MAX_DESTS; i++) { dest = sap->dests + i; /* Reduce activity count to current backlog for * all dests, and flag all as not yet inserted * into activity chain. */ dest->msgsSent = dest->msgsInBacklog; dest->moreActiveDest = -1; dest->lessActiveDest = -1; if (dest->msgsSent > maxActivity) { maxActivity = dest->msgsSent; mostActive = i; } } sap->mostActiveDest = mostActive; sap->leastActiveDest = mostActive; dest = sap->dests + mostActive; dest->moreActiveDest = DGR_MAX_DESTS; /* Now insert all other dests into the chain in descending * activity order. Obviously there are faster ways to do * this sort, but we don't do it very often, so optimizing * it seems premature; something to come back to later. */ for (n = 0; n < (DGR_MAX_DESTS - 1); n++) { ceiling = mostActive; ceilingDest = dest; maxActivity = -1; /* Find most active dest other than those that * have already been sorted into the list. */ for (i = 0; i < DGR_MAX_DESTS; i++) { dest = sap->dests + i; if (dest->moreActiveDest > 0) { continue; /* Already sorted. */ } /* This dest hasn't been reinserted into * the chain yet. */ if (dest->msgsSent > maxActivity) { maxActivity = dest->msgsSent; mostActive = i; } } /* Insert this one in front of the one found * on the prior pass. */ ceilingDest->lessActiveDest = mostActive; sap->leastActiveDest = mostActive; dest = sap->dests + mostActive; dest->moreActiveDest = ceiling; } pthread_mutex_unlock(&sap->destsMutex); } static void adjustRetard(DgrDest *dest) { /* (minRate, the minimum number of bytes to transmit in * each episode is based on a minimum transmission rate * of 1200 bps = 150 bytes per second. Must scale 150 * by length of rate control episode.) */ static int minRate = (150 * EPISODE_PERIOD) / 1000000; int i; int maxIncrease; int maxDecrease; int unusedCapacity; int capacity; int newDataRate; int booster; #if DGRDEBUG traceBytesAcknowledged = dest->bytesAcknowledged; traceBytesResent = dest->bytesTransmitted - dest->bytesOriginated; #endif if (dest->episodeCount < 8) { dest->episodeCount++; } /* The basic rate control principle: base planned data * transmission rate on the mean rate of acknowledgement * over the recent past, inflated by a 50% aggressiveness * factor to increase the rate rapidly when recovering * from a period of lost connectivity. Then compute * retard as a function of the planned transmission rate. * * Start by computing upper and lower limits on the * amount by which planned data transmission rate may * change in any one episode. */ maxIncrease = dest->bytesToTransmit; /* Double. */ maxDecrease = (dest->bytesToTransmit >> 3) & 0x1fffffff; /* Next, finish compiling statistics for the current * episode. Begin by computing the current episode's * unused capacity (number of bytes that could have been * sent but were not) as the episode's estimated total * capacity minus actual number of bytes transmitted. */ i = dest->currentEpisode; unusedCapacity = dest->episodes[i].capacity - dest->bytesTransmitted; if (unusedCapacity < 0) { unusedCapacity = 0; } #if DGRDEBUG traceUnusedCapacity = unusedCapacity; #endif dest->totalServiceLoad -= dest->episodes[i].serviceLoad; dest->totalBytesTransmitted -= dest->episodes[i].bytesTransmitted; dest->totalBytesAcknowledged -= dest->episodes[i].bytesAcknowledged; dest->totalUnusedCapacity -= dest->episodes[i].unusedCapacity; dest->episodes[i].serviceLoad = dest->serviceLoad; dest->episodes[i].bytesTransmitted = dest->bytesTransmitted; dest->episodes[i].bytesAcknowledged = dest->bytesAcknowledged; dest->episodes[i].unusedCapacity = unusedCapacity; dest->totalServiceLoad += dest->episodes[i].serviceLoad; dest->totalBytesTransmitted += dest->episodes[i].bytesTransmitted; dest->totalBytesAcknowledged += dest->episodes[i].bytesAcknowledged; dest->totalUnusedCapacity += dest->episodes[i].unusedCapacity; /* Then advance to the next history slot. */ if (++i > 7) i = 0; dest->currentEpisode = i; /* Now start compiling statistics for the next episode: * insert the projected capacity for that episode, which * is estimated as the mean sum of bytes acknowledged and * unused capacity over the past eight episodes. */ capacity = (dest->totalBytesAcknowledged + dest->totalUnusedCapacity) / dest->episodeCount; dest->totalCapacity -= dest->episodes[i].capacity; dest->episodes[i].capacity = capacity; dest->totalCapacity += dest->episodes[i].capacity; /* To compute the next episode's planned data transmission * rate, start with the episode's estimated capacity and * then inflate that rate by 50%. */ booster = (capacity >> 1) & 0x7fffffff; newDataRate = capacity + booster; /* Now limit change in data rate as determined earlier. */ if (newDataRate < dest->bytesToTransmit) /* Slower. */ { if ((dest->bytesToTransmit - newDataRate) > maxDecrease) { newDataRate = dest->bytesToTransmit - maxDecrease; } } else /* Faster. */ { if ((newDataRate - dest->bytesToTransmit) > maxIncrease) { newDataRate = dest->bytesToTransmit + maxIncrease; } } /* But never let data rate drop below minimum pulse rate. */ if (newDataRate < minRate) { newDataRate = minRate; } dest->bytesToTransmit = newDataRate; #if DGRDEBUG traceBytesToTransmit = newDataRate; #endif /* To calculate retard (the number of microseconds of * delay to impose per byte of transmitted content), * divide the control episode duration in microseconds * by the number of bytes to transmit in the next * episode. */ dest->retard = EPISODE_PERIOD / newDataRate; #if DGRDEBUG traceRetard = dest->retard; #endif /* Note that retard may be zero, in the event that the * network is transmitting way faster than we need it to. */ #if DGRDEBUG dgrtrace(); traceBytesAcknowledged = 0; dest->serviceLoad = 0; traceBytesTransmitted = 0; traceBytesOriginated = 0; aggregateDelay = 0; #endif dest->bytesAcknowledged = 0; dest->bytesTransmitted = 0; dest->bytesOriginated = 0; } static void adjustRateControl(DgrSAP *sap) { int i; DgrDest *dest; #if DGRDEBUG PUTS("---------------------------------------------------------------"); #endif pthread_mutex_lock(&sap->destsMutex); for (i = 0, dest = sap->dests; i < DGR_MAX_DESTS; i++, dest++) { if (dest->bytesToTransmit > 0) { adjustRetard(dest); } } #if DGRDEBUG appliedAcks = 0; #endif pthread_mutex_unlock(&sap->destsMutex); } /* * * DGR background thread functions * */ static void *sender(void *parm) { DgrSAP *sap = (DgrSAP *) parm; LystElt elt; SendReq *req; uvast engineId; unsigned int sessionNbr; #ifndef mingw sigset_t signals; sigfillset(&signals); pthread_sigmask(SIG_BLOCK, &signals, NULL); #endif while (sap->state == DgrSapOpen) { if (llcv_wait(sap->outboundCV, llcv_lyst_not_empty, LLCV_BLOCKING)) { crashThread(sap, "Sender thread failed on wait"); return NULL; } if (sap->state != DgrSapOpen) { return NULL; } while (1) { llcv_lock(sap->outboundCV); elt = lyst_first(sap->outboundMsgs); if (elt == NULL) { llcv_unlock(sap->outboundCV); break; } req = (SendReq *) lyst_data(elt); engineId = req->id.engineId; sessionNbr = req->id.sessionNbr; llcv_unlock(sap->outboundCV); if (arq(sap, engineId, sessionNbr, DgrSendMessage)) { writeMemo("[i] DGR sender thread ended."); return NULL; } } } return NULL; } static void *resender(void *parm) { DgrSAP *sap = (DgrSAP *) parm; int cycleNbr = 1; struct timeval currentTime; LystElt elt; ResendReq *req; uvast engineId; unsigned int sessionNbr; #ifndef mingw sigset_t signals; sigfillset(&signals); pthread_sigmask(SIG_BLOCK, &signals, NULL); #endif while (1) { microsnooze(EPISODE_PERIOD); if (sap->state != DgrSapOpen) { return NULL; } adjustRateControl(sap); if ((cycleNbr & 0x7f) == 0) /* Every 128th. */ { resetDestActivity(sap); } /* Deal with all retransmissions that are now due. */ getCurrentTime(¤tTime); while (1) { pthread_mutex_lock(&sap->pendingResendsMutex); elt = lyst_first(sap->pendingResends); if (elt == NULL) { pthread_mutex_unlock(&sap->pendingResendsMutex); break; /* No more for now. */ } req = (ResendReq *) lyst_data(elt); if (req->resendTime.tv_sec > currentTime.tv_sec) { pthread_mutex_unlock(&sap->pendingResendsMutex); break; /* No more for now. */ } if (req->resendTime.tv_sec < currentTime.tv_sec || req->resendTime.tv_usec <= currentTime.tv_usec) { /* Segment's resend time is here. */ engineId = req->id.engineId; sessionNbr = req->id.sessionNbr; pthread_mutex_unlock(&sap->pendingResendsMutex); if (arq(sap, engineId, sessionNbr, DgrHandleTimeout)) { writeMemo("[i] DGR resender ended."); return NULL; } continue; } pthread_mutex_unlock(&sap->pendingResendsMutex); break; /* No more for now. */ } } } static int sendAck(DgrSAP *sap, char *reportBuffer, int headerLength, unsigned int rptSerialNbr, struct sockaddr *sockName, socklen_t sockaddrlen) { char *cursor; int length; Sdnv sdnv; memcpy(reportBuffer, sap->inputBuffer, headerLength); *reportBuffer = 9; /* 00001001; report ACK. */ length = headerLength; cursor = reportBuffer + length; /* Report serial number. */ encodeSdnv(&sdnv, rptSerialNbr); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* ACK is now ready to transmit. */ if (isendto(sap->udpSocket, reportBuffer, length, 0, sockName, sockaddrlen) < 0) { if (errno != EBADF) /* Socket closed. */ { crashThread(sap, "Receiver thread failed sending \ acknowledgement"); } return -1; } return 0; } static int sendReport(DgrSAP *sap, char *reportBuffer, int headerLength, unsigned int ckptSerialNbr, unsigned int dataLength, struct sockaddr *sockName, socklen_t sockaddrlen) { char *cursor; int length; Sdnv sdnv; unsigned int rptSerialNbr = rand(); memcpy(reportBuffer, sap->inputBuffer, headerLength); *reportBuffer = 8; /* 00001000; report. */ length = headerLength; cursor = reportBuffer + length; /* Report serial number. */ encodeSdnv(&sdnv, rptSerialNbr); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Checkpoint serial number. */ encodeSdnv(&sdnv, ckptSerialNbr); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Upper bound. */ encodeSdnv(&sdnv, dataLength); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Lower bound. */ encodeSdnv(&sdnv, 0); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Reception claim count. */ encodeSdnv(&sdnv, 1); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Reception claim 1 offset. */ encodeSdnv(&sdnv, 0); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Reception claim 1 length. */ encodeSdnv(&sdnv, dataLength); memcpy(cursor, sdnv.text, sdnv.length); length += sdnv.length; cursor += sdnv.length; /* Report is now ready to transmit. */ if (isendto(sap->udpSocket, reportBuffer, length, 0, sockName, sockaddrlen) < 0) { if (errno != EBADF) /* Socket closed. */ { crashThread(sap, "Receiver thread failed sending \ report"); } return -1; } return 0; } static void *receiver(void *parm) { DgrSAP *sap = (DgrSAP *) parm; struct sockaddr_in socketAddress; struct sockaddr *sockName = (struct sockaddr *) &socketAddress; socklen_t sockaddrlen; unsigned short portNbr; int length; unsigned char *cursor; int bytesRemaining; unsigned int versionNbr; unsigned int segmentType; int sdnvLength; uvast engineId; uvast sessionNbr; unsigned int extensionCounts; int headerLength; uvast clientSvcId; uvast svcDataOffset; uvast svcDataLength; uvast ckptSerialNbr; uvast rptSerialNbr; char reportBuffer[64]; int reclength; DgrRecord rec; #ifndef mingw sigset_t signals; sigfillset(&signals); pthread_sigmask(SIG_BLOCK, &signals, NULL); #endif while (1) { sockaddrlen = sizeof(struct sockaddr_in); length = irecvfrom(sap->udpSocket, sap->inputBuffer, DGR_BUF_SIZE, 0, sockName, &sockaddrlen); if (length < 0) { switch (errno) { case EBADF: /* Socket has been closed. */ break; case ECONNRESET:/* Connection reset. */ case EAGAIN: /* Bad checksum? Ignore. */ continue; default: crashThread(sap, "Receiver thread failed on \ recvfrom"); break; /* Out of switch. */ } break; /* Out of main loop. */ } if (sap->state != DgrSapOpen) { break; /* Out of main loop. */ } /* Parse the LTP segment header. */ cursor = (unsigned char *) (sap->inputBuffer); bytesRemaining = length; /* Version number. */ if (bytesRemaining < 1) { continue; /* Ignore random guck. */ } versionNbr = ((*cursor) >> 4) & 0x0f; if (versionNbr != 0) { continue; /* Invalid segment. */ } /* Segment type. */ segmentType = (*cursor) & 0x0f; cursor++; bytesRemaining--; /* Engine ID. */ if (bytesRemaining < 1) { continue; /* Invalid segment. */ } sdnvLength = decodeSdnv(&engineId, cursor); if (sdnvLength < 1) { continue; /* Invalid segment. */ } cursor += sdnvLength; bytesRemaining -= sdnvLength; /* Session Nbr. */ if (bytesRemaining < 1) { continue; /* Invalid segment. */ } sdnvLength = decodeSdnv(&sessionNbr, cursor); if (sdnvLength < 1) { continue; /* Invalid segment. */ } cursor += sdnvLength; bytesRemaining -= sdnvLength; /* Extension counts. */ if (bytesRemaining < 1) { continue; /* Invalid segment. */ } extensionCounts = *cursor; if (extensionCounts != 0) { continue; /* No extension support. */ } cursor++; bytesRemaining--; /* Segment content. */ if (bytesRemaining < 1) /* No content. */ { continue; /* Invalid segment. */ } /* Process content as indicated by segment type. */ headerLength = length - bytesRemaining; if (segmentType == 8) /* Report. */ { /* Get report serial number. */ sdnvLength = decodeSdnv(&rptSerialNbr, cursor); if (sdnvLength < 1) { continue; /* Invalid segment.*/ } cursor += sdnvLength; bytesRemaining -= sdnvLength; if (sendAck(sap, reportBuffer, headerLength, rptSerialNbr, sockName, sockaddrlen) < 0) { break; /* Main loop. */ } if (arq(sap, engineId, sessionNbr, DgrHandleRpt)) { writeMemo("[i] DGR receiver thread ended."); break; /* Out of main loop. */ } continue; } /* Note: we always return report ACKs (9s), for * compliance, but we always ignore all received * report ACKs. DGR reports are not retransmitted. * If the report isn't received, the data segment * is eventually retransmitted and is acknowledged * at that time. */ if (segmentType != 3) { continue; /* Not supported. */ } /* Red data, EOB. Extract sender's port nbr. */ portNbr = ntohs(socketAddress.sin_port); /* Client service ID. */ sdnvLength = decodeSdnv(&clientSvcId, cursor); if (sdnvLength < 1) { continue; /* Invalid segment. */ } cursor += sdnvLength; bytesRemaining -= sdnvLength; /* Service data offset. */ if (bytesRemaining < 1) { continue; /* Invalid segment. */ } sdnvLength = decodeSdnv(&svcDataOffset, cursor); if (sdnvLength < 1) { continue; /* Invalid segment. */ } if (svcDataOffset != 0) { continue; /* Not supported. */ } cursor += sdnvLength; bytesRemaining -= sdnvLength; /* Service data length. */ if (bytesRemaining < 1) { continue; /* Invalid segment. */ } sdnvLength = decodeSdnv(&svcDataLength, cursor); if (sdnvLength < 1) { continue; /* Invalid segment. */ } cursor += sdnvLength; bytesRemaining -= sdnvLength; /* Checkpoint serial number. */ if (bytesRemaining < 1) { continue; /* Invalid segment. */ } sdnvLength = decodeSdnv(&ckptSerialNbr, cursor); if (sdnvLength < 1) { continue; /* Invalid segment. */ } cursor += sdnvLength; bytesRemaining -= sdnvLength; /* Report serial number. */ if (bytesRemaining < 1) { continue; /* Invalid segment. */ } sdnvLength = decodeSdnv(&rptSerialNbr, cursor); if (sdnvLength < 1) { continue; /* Invalid segment. */ } cursor += sdnvLength; bytesRemaining -= sdnvLength; /* Client service data. */ if (bytesRemaining < 1) { continue; /* Invalid segment. */ } if (rptSerialNbr != 0) { continue; /* Not supported. */ } if (_watching()) { putchar('s'); fflush(stdout); } /* Now send acknowledgment (report). */ if (sendReport(sap, reportBuffer, headerLength, ckptSerialNbr, svcDataLength, sockName, sockaddrlen) < 0) { break; /* Out of main loop. */ } /* Create content arrival event. */ reclength = sizeof(struct dgr_rec) + (svcDataLength - 1); rec = (DgrRecord) MTAKE(reclength); if (rec == NULL) { crashThread(sap, "Receiver thread failed creating \ content arrival event"); break; /* Out of main loop. */ } memset((char *) rec, 0, reclength); rec->type = DgrMsgIn; rec->portNbr = portNbr; rec->ipAddress = ntohl(socketAddress.sin_addr.s_addr); rec->contentLength = svcDataLength; rec->segment.id.engineId = engineId; rec->segment.id.sessionNbr = sessionNbr; memcpy(rec->segment.content, cursor, svcDataLength); if (insertEvent(sap, rec)) { writeMemo("[i] DGR receiver thread ended."); break; /* Out of main loop. */ } if (_watching()) { putchar('t'); fflush(stdout); } } /* Main loop terminated for some reason; wrap up. */ return NULL; } /* * * DGR API functions * * * */ static void forgetObject(LystElt elt, void *userData) { DgrSAP *sap = (DgrSAP *) userData; MRELEASE(lyst_data(elt)); } static void cleanUpSAP(DgrSAP *sap) { int i; DgrArqBucket *bucket; if (sap->udpSocket >= 0) { closesocket(sap->udpSocket); } if (sap->outboundMsgs) { lyst_delete_set(sap->outboundMsgs, forgetObject, sap); lyst_destroy(sap->outboundMsgs); } if (sap->outboundCV) { llcv_close(sap->outboundCV); } if (sap->inboundEvents) { lyst_delete_set(sap->inboundEvents, forgetObject, sap); lyst_destroy(sap->inboundEvents); } if (sap->inboundCV) { llcv_close(sap->inboundCV); } for (i = 0, bucket = sap->buckets; i < DGR_BUCKETS; i++, bucket++) { if (bucket->msgs) { lyst_delete_set(bucket->msgs, forgetObject, sap); lyst_destroy(bucket->msgs); } pthread_mutex_destroy(&bucket->mutex); } for (i = 0; i < DGR_BIN_COUNT; i++) { lyst_destroy(sap->destLysts[i]); } if (sap->pendingResends) { lyst_delete_set(sap->pendingResends, forgetObject, sap); lyst_destroy(sap->pendingResends); } pthread_mutex_lock(&sap->sapMutex); pthread_cond_destroy(&sap->sapCV); pthread_mutex_destroy(&sap->sapMutex); pthread_mutex_destroy(&sap->pendingResendsMutex); pthread_mutex_destroy(&sap->destsMutex); MRELEASE(sap); } int dgr_open(uvast ownEngineId, unsigned int clientSvcId, unsigned short ownPortNbr, unsigned int ownIpAddress, char *memmgrName, DgrSAP **sapp, DgrRC *rc) { struct sockaddr_in socketAddress; struct sockaddr *sockName = (struct sockaddr *) &socketAddress; int mmid; DgrSAP *sap; int i; DgrArqBucket *bucket; CHKERR(ownEngineId); CHKERR(clientSvcId); CHKERR(sapp); CHKERR(rc); memset((char *) sockName, 0, sizeof(struct sockaddr_in)); socketAddress.sin_family = AF_INET; ownIpAddress = htonl(ownIpAddress); socketAddress.sin_addr.s_addr = ownIpAddress; ownPortNbr = htons(ownPortNbr); socketAddress.sin_port = ownPortNbr; /* Determine memory management procedures. */ if (memmgrName) { mmid = memmgr_find(memmgrName); if (mmid < 0) { putErrmsg("DGR can't find memory manager.", memmgrName); return -1; } } else { mmid = 0; /* default is malloc/free */ } /* Initialize service access point constants. */ sap = (DgrSAP *)(memmgr_take(mmid))(__FILE__, __LINE__, sizeof(DgrSAP)); if (sap == NULL) { putErrmsg("DGR can't create DGR service access point.", NULL); return -1; } memset((char *) sap, 0, sizeof(DgrSAP)); sap->engineId = ownEngineId; sap->clientSvcId = clientSvcId; sap->state = DgrSapOpen; sap->mtake = memmgr_take(mmid); sap->mrelease = memmgr_release(mmid); sap->leastActiveDest = -1; sap->mostActiveDest = DGR_MAX_DESTS; initializeDest(&sap->defaultDest, 0, 0); /* Initialize UDP socket for DGR service. */ sap->udpSocket = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP); if (sap->udpSocket < 0) { putSysErrmsg("Can't open DGR UDP socket", NULL); cleanUpSAP(sap); return -1; } #if (SOCK_CLOEXEC == 0) closeOnExec(sap->udpSocket); #endif if (reUseAddress(sap->udpSocket) < 0) { putSysErrmsg("Can't reuse address on DGR UDP socket", utoa(ntohs(ownPortNbr))); cleanUpSAP(sap); return -1; } if (bind(sap->udpSocket, sockName, sizeof(struct sockaddr)) < 0) { putSysErrmsg("Can't bind DGR UDP socket", utoa(ntohs(ownPortNbr))); cleanUpSAP(sap); return -1; } /* Create lists and management structures. */ if ((sap->outboundMsgs = lyst_create_using(mmid)) == NULL) { putErrmsg("DGR can't create list of outbound messages.", NULL); cleanUpSAP(sap); return -1; } if ((sap->outboundCV = llcv_open(sap->outboundMsgs, &(sap->outboundCV_str))) == NULL) { putErrmsg("DGR can't outbound messages CV.", NULL); cleanUpSAP(sap); return -1; } if ((sap->inboundEvents = lyst_create_using(mmid)) == NULL) { putErrmsg("DGR can't create list of inbound events.", NULL); cleanUpSAP(sap); return -1; } if ((sap->inboundCV = llcv_open(sap->inboundEvents, &(sap->inboundCV_str))) == NULL) { putErrmsg("DGR can't create inbound events CV.", NULL); cleanUpSAP(sap); return -1; } for (i = 0; i < DGR_BIN_COUNT; i++) { if ((sap->destLysts[i] = lyst_create_using(mmid)) == NULL) { putErrmsg("DGR can't create destinations list.", NULL); cleanUpSAP(sap); return -1; } } for (i = 0, bucket = sap->buckets; i < DGR_BUCKETS; i++, bucket++) { if ((bucket->msgs = lyst_create_using(mmid)) == NULL || pthread_mutex_init(&bucket->mutex, NULL)) { putSysErrmsg("DGR can't create message bucket", NULL); cleanUpSAP(sap); return -1; } } if ((sap->pendingResends = lyst_create_using(mmid)) == NULL) { putErrmsg("DGR can't create list of resend requests.", NULL); cleanUpSAP(sap); return -1; } if (pthread_mutex_init(&sap->sapMutex, NULL) || pthread_cond_init(&sap->sapCV, NULL) || pthread_mutex_init(&sap->pendingResendsMutex, NULL) || pthread_mutex_init(&sap->destsMutex, NULL)) { putSysErrmsg("DGR can't initialize mutex(es)", NULL); cleanUpSAP(sap); return -1; } /* Spawn all threads. */ if (pthread_begin(&(sap->sender), NULL, sender, sap) || pthread_begin(&(sap->resender), NULL, resender, sap) || pthread_begin(&(sap->receiver), NULL, receiver, sap)) { putSysErrmsg("DGR can't spawn thread(s)", NULL); cleanUpSAP(sap); return -1; } *sapp = sap; *rc = DgrOpened; return 0; } void dgr_getsockname(DgrSAP *sap, unsigned short *portNbr, unsigned int *ipAddress) { struct sockaddr buf; socklen_t buflen = sizeof buf; struct sockaddr_in *nm = (struct sockaddr_in *) &buf; CHKVOID(sap); CHKVOID(portNbr); CHKVOID(ipAddress); *portNbr = *ipAddress = 0; /* Default. */ if (getsockname(sap->udpSocket, &buf, &buflen) < 0) { putSysErrmsg("DGR can't get socket name.", NULL); return; } memcpy((char *) ipAddress, (char *) &(nm->sin_addr.s_addr), 4); *ipAddress = ntohl(*ipAddress); *portNbr = nm->sin_port; *portNbr = ntohs(*portNbr); } void dgr_close(DgrSAP *sap) { struct sockaddr sockName; socklen_t sockNameLen = sizeof(sockName); char shutdown = 1; CHKVOID(sap); if (sap->state == DgrSapClosed) { return; } sap->state = DgrSapClosed; /* Terminate any dgr_receive that is currently in * progress. */ llcv_signal(sap->inboundCV, time_to_stop); /* Tell the sender thread to shut itself down. */ llcv_signal(sap->outboundCV, time_to_stop); pthread_join(sap->sender, NULL); /* The resender thread will shut down on its next timeout. */ pthread_join(sap->resender, NULL); /* Prompt the receiver thread to shut itself down. */ if (getsockname(sap->udpSocket, &sockName, &sockNameLen) < 0) { putSysErrmsg("DGR can't get socket name.", NULL); } else { if (isendto(sap->udpSocket, &shutdown, 1, 0, &sockName, sizeof(struct sockaddr_in)) < 0) { putSysErrmsg("DGR can't send shutdown packet", NULL); } } pthread_join(sap->receiver, NULL); /* Now destroy all remaining management and communication * structures. */ cleanUpSAP(sap); } int dgr_send(DgrSAP *sap, unsigned short toPortNbr, unsigned int toIpAddress, int notificationFlags, char *content, int length, DgrRC *rc) { int reclength; DgrRecord rec; DgrDest *dest; int destIdx; int delay; /* microseconds */ static int clockResolution = SYS_CLOCK_RES; int usecToSnooze; int usecSnoozed; LystElt elt; CHKERR(sap); CHKERR(toPortNbr); CHKERR(toIpAddress); CHKERR(notificationFlags >= 0); CHKERR(notificationFlags <= 3); CHKERR(content); CHKERR(length > 0); CHKERR(length <= MAX_DATA_SIZE); CHKERR(rc); if (sap->state == DgrSapDamaged) { writeMemo("[?] DGR access point damaged; close and reopen."); *rc = DgrFailed; return 0; } if (sap->state == DgrSapClosed) { writeMemo("[?] DGR access point is not open."); *rc = DgrFailed; return 0; } /* Construct the outbound DGR record. */ reclength = sizeof(struct dgr_rec) + (length - 1); rec = (DgrRecord) MTAKE(reclength); if (rec == NULL) { putErrmsg("Can't create outbound message record.", NULL); return -1; } memset((char *) rec, 0, reclength); rec->type = DgrMsgOut; rec->portNbr = toPortNbr; rec->ipAddress = toIpAddress; rec->notificationFlags = notificationFlags; rec->contentLength = length; memcpy(rec->segment.content, content, length); /* Apply rate control. First compute delay: multiply * content length by computed "retard" rate for this * destination, the number of microseconds of delay * per byte to impose whenever sending a datagram to * the destination, and update statistics for future * rate control adjustment. */ pthread_mutex_lock(&sap->destsMutex); dest = findDest(sap, toPortNbr, toIpAddress, &destIdx); dest->serviceLoad += length; delay = length * dest->retard; #if DGRDEBUG aggregateDelay += delay; #endif /* Now apply the computed rate control delay. */ dest->pendingDelay += delay; usecToSnooze = dest->pendingDelay; pthread_mutex_unlock(&sap->destsMutex); usecSnoozed = 0; while (usecToSnooze > clockResolution) { #if DGRDEBUG rcSnoozes++; #endif microsnooze(clockResolution); usecToSnooze -= clockResolution; usecSnoozed += clockResolution; } if (usecSnoozed > 0) { pthread_mutex_lock(&sap->destsMutex); dest->pendingDelay -= usecSnoozed; pthread_mutex_unlock(&sap->destsMutex); } /* Safety net: prevent volume of in-process messages * from getting out of hand. */ pthread_mutex_lock(&sap->sapMutex); while (sap->backlog > MAX_BACKLOG) { pthread_cond_wait(&sap->sapCV, &sap->sapMutex); } /* Now proceed with transmission. */ sap->backlog += (rec->contentLength + sizeof(SegmentId)); sap->sessionNbr++; rec->segment.id.engineId = sap->engineId; rec->segment.id.sessionNbr = sap->sessionNbr; pthread_mutex_unlock(&sap->sapMutex); /* Store in a bucket of the DGR ARQ (record) database. * Select bucket by computing sessionNbr modulo the * number of buckets - 1. */ rec->bucket = sap->buckets + (rec->segment.id.sessionNbr & DGR_SESNBR_MASK); /* Insert the new record in the selected database bucket. */ pthread_mutex_lock(&rec->bucket->mutex); elt = lyst_insert_last(rec->bucket->msgs, rec); pthread_mutex_unlock(&rec->bucket->mutex); if (elt == NULL) /* Bail. */ { putErrmsg("Can't append outbound record.", NULL); MRELEASE(rec); pthread_mutex_lock(&sap->sapMutex); sap->backlog -= (length + sizeof(SegmentId)); pthread_cond_signal(&sap->sapCV); pthread_mutex_unlock(&sap->sapMutex); pthread_mutex_lock(&sap->destsMutex); dest = findDest(sap, toPortNbr, toIpAddress, &destIdx); dest->serviceLoad -= length; pthread_mutex_unlock(&sap->destsMutex); return -1; } /* Insert transmission request for the sender thread to * act on. */ if (insertSendReq(sap, rec) < 0) { putErrmsg("Can't append transmission request.", NULL); lyst_delete(elt); MRELEASE(rec); pthread_mutex_lock(&sap->sapMutex); sap->backlog -= (length + sizeof(SegmentId)); pthread_cond_signal(&sap->sapCV); pthread_mutex_unlock(&sap->sapMutex); pthread_mutex_lock(&sap->destsMutex); dest = findDest(sap, toPortNbr, toIpAddress, &destIdx); dest->serviceLoad -= length; pthread_mutex_unlock(&sap->destsMutex); return -1; } if (_watching()) { putchar('e'); putchar('f'); fflush(stdout); } *rc = DgrDatagramSent; return 0; } int dgr_receive(DgrSAP *sap, unsigned short *fromPortNbr, unsigned int *fromIpAddress, char *content, int *length, int *errnbr, int timeoutSeconds, DgrRC *rc) { int timeoutUsec; LystElt elt; DgrRecord rec; CHKERR(sap); CHKERR(fromPortNbr); CHKERR(fromIpAddress); CHKERR(content); CHKERR(length); CHKERR(errnbr); CHKERR(rc); if (sap->state == DgrSapDamaged) { writeMemo("[?] DGR access point damaged; close and reopen."); *rc = DgrFailed; return 0; } if (sap->state == DgrSapClosed) { writeMemo("[?] DGR access point is not open."); *rc = DgrFailed; return 0; } if (timeoutSeconds == DGR_BLOCKING) { timeoutUsec = LLCV_BLOCKING; } else { timeoutUsec = timeoutSeconds * 1000000; } while (1) { if (llcv_wait(sap->inboundCV, llcv_lyst_not_empty, timeoutUsec)) { if (errno == ETIMEDOUT) { *rc = DgrTimedOut; return 0; } putErrmsg("DGR reception failed in wait.", NULL); return -1; } /* Lyst is no longer empty, or SAP is now closed. */ break; /* Out of loop. */ } /* SAP might have been closed while we were sleeping. */ if (sap->state == DgrSapDamaged) { writeMemo("[?] DGR access point no longer usable."); *rc = DgrFailed; return 0; } if (sap->state == DgrSapClosed) { writeMemo("[i] DGR access point has been closed."); *rc = DgrFailed; return 0; } llcv_lock(sap->inboundCV); elt = lyst_first(sap->inboundEvents); rec = (DgrRecord) lyst_data(elt); lyst_delete(elt); llcv_unlock(sap->inboundCV); if (rec == NULL) /* Interrupted. */ { *rc = DgrInterrupted; return 0; } *length = rec->contentLength; memcpy(content, rec->segment.content, rec->contentLength); switch (rec->type) { case DgrMsgIn: *fromPortNbr = rec->portNbr; *fromIpAddress = rec->ipAddress; *rc = DgrDatagramReceived; break; case DgrDeliverySuccess: *rc = DgrDatagramAcknowledged; break; default: *errnbr = rec->errnbr; *rc = DgrDatagramNotAcknowledged; } /* Reclaim memory occupied by the inbound message * or delivery failure. */ MRELEASE(rec); return 0; } void dgr_interrupt(DgrSAP *sap) { CHKVOID(sap); CHKVOID(insertEvent(sap, NULL) == 0); } ion-3.2.0~dfsg1.orig/dgr/include/0000755000175000017500000000000012260400056015065 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/include/dgr.h0000644000175000017500000001276312260400056016023 0ustar l3onl3on/* dgr.h: definitions supporting the implementation of DGR applications. Author: Scott Burleigh, JPL Modification History: Date Who What 4 July 2010 Scott Revise to align with LTP spec. Copyright (c) 2003, California Institute of Technology. ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. */ #ifndef _DGR_H_ #define _DGR_H_ #include "platform.h" #include "lyst.h" #include "llcv.h" #ifdef __cplusplus extern "C" { #endif /* dgr_send notification flags (to be OR'd together in flags parm) */ #define DGR_NOTE_NONE (0) /* No notification. */ #define DGR_NOTE_FAILED (1) /* Note delivery failure. */ #define DGR_NOTE_ACKED (2) /* Note delivery success. */ #define DGR_NOTE_ALL (DGR_NOTE_FAILED | DGR_NOTE_ACKED) /* dgr_receive timeout values */ #define DGR_POLL (0) /* Return immediately. */ #define DGR_BLOCKING (-1) /* Wait forever. */ typedef enum { DgrFailed = 1, DgrOpened, DgrDatagramSent, DgrDatagramReceived, DgrTimedOut, DgrInterrupted, DgrDatagramAcknowledged, DgrDatagramNotAcknowledged } DgrRC; typedef struct dgrsapst *Dgr; extern int dgr_open( uvast ownEngineId, unsigned int clientSvcId, unsigned short ownPortNbr, unsigned int ownIpAddress, char *memmgrName, Dgr *dgr, DgrRC *rc); /* Arguments are: * port number to use for DGR * service (if 0, defaults * to system-assigned UDP * port number) * Internet address of IP interface * to use for DGR service; * if 0, defaults to the * address of the interface * identified by the local * machine's host name * name of memory manager to use * for dynamic memory * management; if NULL, * defaults to standard * system malloc/free * location in which to store * service access pointer * location in which to store * return code * * Returns 0 on success, -1 on failure. */ extern void dgr_getsockname(Dgr dgr, unsigned short *portNbr, unsigned int *ipAddress); /* States the port number and IP address * of the UDP socket used for this DGR * service access point. */ extern void dgr_close(Dgr dgr); /* Reverses dgr_open, releasing resources * where possible. */ extern int dgr_send( Dgr dgr, unsigned short toPortNbr, unsigned int toIpAddress, int notificationFlags, char *content, int length, DgrRC *rc); /* Sends the indicated content, of length * as indicated, to the indicated remote * DGR service access point. The message * will be retransmitted as necessary * until either it is acknowledged or * DGR determines that it cannot be * delivered. Length of content must be * greater than zero and may be as great * as 65535, but lengths greater than * 8192 may not be supported by the local * underlying UDP implementation; to * minimize the chance of data loss when * transmitting over the internet, length * should not exceed 512. Returns 0 on * success (setting *rc as appropriate), * -1 on failure. */ extern int dgr_receive( Dgr dgr, unsigned short *fromPortNbr, unsigned int *fromIpAddress, char *content, int *length, int *errnbr, int timeoutSeconds, DgrRC *rc); /* Delivers the oldest undelivered DGR * event queued for delivery. * * DGR events are of two type: (a) a * message received from a remote DGR * service access point and (b) a notice * of a previously sent message that * DGR has determined either has been * or cannot be delivered, as requested * in the notificationFlags parm of the * dgr_send call that sent the message. * * In the former case, dgr_receive will * place the content of the inbound * message in "content", its length in * "length", and the IP address and port * number of the sender in "fromIpAddress" * and "fromPortNbr", and will set *rc to * DgrDatagramReceived. * * In the latter case, dgr_receive will * place the content of the outbound * message in "content" and its length * in "length", will place the relevant * errno (if any) in errnbr, and will set * *rc to either DgrDatagramAcknowledged * or DgrDatagramNotAcknowledged. * * The "content" buffer should be at least * 65535 bytes in length to enable delivery * of the content of the received or * delivered/undeliverable message. * * The "timeoutSeconds" argument controls * blocking behavior. If timeoutSeconds * is DGR_BLOCKING, dgr_receive will not * return until there is either an inbound * message to deliver or an outbound * message delivery result to report * (or an I/O error). If timeoutSeconds * is DGR_POLL, dgr_receive returns * immediately; if there is currently no * inbound message to deliver and no * outbound message delivery result to * report, the function sets *rc to * DgrTimedOut. For any other positive * value of timeoutSeconds, dgr_receive * returns after the indicated number of * seconds have lapsed, or there is a * message to deliver or a delivery * result to report, whichever occurs * first; in the former case, it sets * *rc to DgrTimedOut. * * Returns 0 on success, -1 on failure. */ extern void dgr_interrupt(Dgr dgr); /* Interrupts a dgr_receive invocation * that is currently blocked. Designed * to be called from a signal handler. */ #ifdef __cplusplus } #endif #endif /* _DGR_H */ ion-3.2.0~dfsg1.orig/dgr/README.txt0000644000175000017500000000277512260400056015153 0ustar l3onl3on******************************************************************* NO WARRANTY: DISCLAIMER THE SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET FORTH IN UCC 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE LICENSED PRODUCT, HOWEVER USED. IN NO EVENT SHALL CALTECH/JPL BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN FACT SHALL KNOW OF THE POSSIBILITY. USER BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED MATERIALS. ******************************************************************* Copyright 2002-2011, by the California Institute of Technology. ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. This software and/or related materials may be subject to U.S. export control laws. By accepting this software and related materials, the user agrees to comply with all applicable U.S. export laws and regulations. User has the responsibility to obtain export licenses or other export authority as may be required before exporting the software or related materials to foreign countries or providing access to foreign persons. ******************************************************************* ion-3.2.0~dfsg1.orig/dgr/i86-freebsd/0000755000175000017500000000000012260400056015460 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/i86-freebsd/Makefile0000644000175000017500000000322212260400056017117 0ustar l3onl3onINCL = ../include API = ../library TEST = ../test # OPT = -O -Dfreebsd # OPT = -g -Wall -Dfreebsd -DINITIAL_RETARD=2 OPT = -g -Wall -Werror -Dfreebsd CC = gcc $(OPT) -I$(API) -I$(TEST) -I$(INCL) -I$(ROOT)/include LDFLAGS = -fPIC -shared LD = gcc $(LDFLAGS) LIBDGROBJS = \ libdgr.o PUBINCLS = \ $(INCL)/dgr.h RUNTIMES = file2dgr dgr2file file2tcp tcp2file file2udp udp2file ALL = check libdgr.so $(RUNTIMES) all: $(ALL) check: $(PUBINCLS) rm -f *.o touch check clean: rm -f *.o rm -f $(ALL) rm -f ./lib/* rm -f ./bin/* install: cp ../include/* $(ROOT)/include cp lib/* $(ROOT)/lib cp bin/* $(ROOT)/bin # - - Test executables - - - - file2dgr: file2dgr.o libdgr.so $(TEST)/file2dgr.h $(CC) -o file2dgr file2dgr.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread cp file2dgr ./bin dgr2file: dgr2file.o libdgr.so $(TEST)/file2dgr.h $(CC) -o dgr2file dgr2file.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread cp dgr2file ./bin tcp2file: tcp2file.o $(TEST)/file2tcp.h $(CC) -o tcp2file tcp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread cp tcp2file ./bin file2tcp: file2tcp.o $(TEST)/file2tcp.h $(CC) -o file2tcp file2tcp.o -L$(ROOT)/lib -L./lib -lici -lpthread cp file2tcp ./bin udp2file: udp2file.o $(TEST)/file2udp.h $(CC) -o udp2file udp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread cp udp2file ./bin file2udp: file2udp.o $(TEST)/file2udp.h $(CC) -o file2udp file2udp.o -L$(ROOT)/lib -L./lib -lici -lpthread cp file2udp ./bin # - - Libraries - - - - - libdgr.so: $(LIBDGROBJS) $(LD) -o libdgr.so $(LIBDGROBJS) cp libdgr.so ./lib # - - Object modules - - - - - %.o: $(API)/%.c $(CC) -c $< %.o: $(TEST)/%.c $(CC) -c $< ion-3.2.0~dfsg1.orig/dgr/test/0000755000175000017500000000000012260400056014421 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/test/file2udp.h0000644000175000017500000000246212260400056016310 0ustar l3onl3on/* * * file2udp.h: definitions used for the file2tcp benchmark * system. * * */ #include "platform.h" #define TEST_PORT_NBR 2101 #define EOF_LINE_TEXT "*** End of the file ***" /* * Structure to contain everything needed for RTT timing. * One of these required per socket being timed. * The caller allocates this structure, then passes its address to * all the rtt_XXX() functions. */ struct rtt_struct { float rtt_rtt; /* most recent round-trip time (RTT), seconds */ float rtt_srtt; /* smoothed round-trip time (SRTT), seconds */ float rtt_rttdev; /* smoothed mean deviation, seconds */ short rtt_nrexmt; /* #times retransmitted: 0, 1, 2, ... */ short rtt_currto; /* current retransmit timeout (RTO), seconds */ short rtt_nxtrto; /* retransmit timeout for next packet, if nonzero */ struct timeval time_start; /* for elapsed time */ struct timeval time_stop; /* for elapsed time */ }; #if 0 #define RTT_RXTMIN 2 /* min retransmit timeout value, seconds */ #define RTT_RXTMAX 120 /* max retransmit timeout value, seconds */ #endif #define RTT_RXTMIN 1 /* min retransmit timeout value, seconds */ #define RTT_RXTMAX 3 /* max retransmit timeout value, seconds */ #define RTT_MAXNREXMT 4 /* max #times to retransmit: must also change exp_backoff[] if this changes */ ion-3.2.0~dfsg1.orig/dgr/test/file2dgr.c0000644000175000017500000001200212260400056016256 0ustar l3onl3on/* file2dgr.c: a test producer of DGR activity. */ /* */ /* Copyright (c) 2003, California Institute of Technology. */ /* All rights reserved. */ /* Author: Scott Burleigh, Jet Propulsion Laboratory */ /* */ #include #include #include #include static int wmSize = 10000000; static char *wmPtr; static PsmView dgrPartition; static PsmPartition dgrwm = &dgrPartition; static char *eofLine = EOF_LINE_TEXT; static int eofLineLen; static int cyclesRequested = 1; static Dgr dgr; static void *allocFromDgrMemory(char *fileName, int lineNbr, size_t length) { PsmAddress address; void *block; address = Psm_zalloc(fileName, lineNbr, dgrwm, length); if (address == 0) { return NULL; } block = psp(dgrwm, address); memset(block, 0, length); return block; } static void releaseToDgrMemory(char *fileName, int lineNbr, void *block) { Psm_free(fileName, lineNbr, dgrwm, psa(dgrwm, (char *) block)); } static void *dgrAtoP(unsigned long address) { return (void *) psp(dgrwm, address); } static unsigned long dgrPtoA(void *pointer) { return (unsigned long) psa(dgrwm, pointer); } static void report(struct timeval *startTime, unsigned long bytesSent) { struct timeval endTime; unsigned long usec; float rate; getCurrentTime(&endTime); if (endTime.tv_usec < startTime->tv_usec) { endTime.tv_sec--; endTime.tv_usec += 1000000; } usec = ((endTime.tv_sec - startTime->tv_sec) * 1000000) + (endTime.tv_usec - startTime->tv_usec); printf("Bytes sent = %lu, usec elapsed = %lu.\n", bytesSent, usec); rate = (float) (8 * bytesSent) / (float) (usec / 1000000); printf("Sending %7.2f bits per second.\n", rate); } static int run_file2dgr(char *remoteHostName, char *fileName) { int cyclesLeft; char ownHostName[MAXHOSTNAMELEN + 1]; unsigned int ownIpAddress; unsigned int remoteIpAddress; unsigned short remotePortNbr = TEST_PORT_NBR; PsmMgtOutcome outcome; DgrRC rc; FILE *inputFile; char line[256]; int lineLen; struct timeval startTime; unsigned long bytesSent; cyclesLeft = cyclesRequested; getNameOfHost(ownHostName, sizeof ownHostName); ownIpAddress = getInternetAddress(ownHostName); remoteIpAddress = getInternetAddress(remoteHostName); sm_ipc_init(); wmPtr = malloc(wmSize); if (wmPtr == NULL || psm_manage(wmPtr, wmSize, "dgr", &dgrwm, &outcome) < 0 || outcome == Refused) { putErrmsg("Can't acquire DGR working memory.", NULL); writeErrmsgMemos(); return 0; } #if 0 psm_start_trace(dgrwm, 10000000, NULL); #endif memmgr_add("dgr", allocFromDgrMemory, releaseToDgrMemory, dgrAtoP, dgrPtoA); if (dgr_open(ownIpAddress, 2, 0, ownIpAddress, "dgr", &dgr, &rc) < 0 || rc != DgrOpened) { putErrmsg("Can't open dgr service.", NULL); writeErrmsgMemos(); return 0; } inputFile = fopen(fileName, "r"); if (inputFile == NULL) { putSysErrmsg("Can't open input file", fileName); writeErrmsgMemos(); return 0; } eofLineLen = strlen(eofLine); getCurrentTime(&startTime); bytesSent = 0; /* Copy text lines from file to SDR. */ while (cyclesLeft > 0) { if (fgets(line, 256, inputFile) == NULL) { if (feof(inputFile)) { if (dgr_send(dgr, remotePortNbr, remoteIpAddress, DGR_NOTE_FAILED, eofLine, eofLineLen, &rc) < 0) { putErrmsg("dgr_send failed.", NULL); writeErrmsgMemos(); fclose(inputFile); return 0; } bytesSent += eofLineLen; fclose(inputFile); cyclesLeft--; if (cyclesLeft == 0) { inputFile = NULL; break; } inputFile = fopen(fileName, "r"); if (inputFile == NULL) { putSysErrmsg("Can't reopen input file", NULL); writeErrmsgMemos(); return 0; } continue; } else { putSysErrmsg("Can't read from input file", NULL); writeErrmsgMemos(); fclose(inputFile); return 0; } } lineLen = strlen(line); if (dgr_send(dgr, remotePortNbr, remoteIpAddress, DGR_NOTE_FAILED, line, lineLen, &rc) < 0) { putErrmsg("dgr_send failed", NULL); writeErrmsgMemos(); fclose(inputFile); return 0; } bytesSent += lineLen; } report(&startTime, bytesSent); writeMemo("[i] file2dgr waiting 10 sec for retransmission to stop."); snooze(10); dgr_close(dgr); #if 0 psm_print_trace(dgrwm, 0); psm_stop_trace(dgrwm); #endif if (inputFile) { fclose(inputFile); } return 0; } #if defined (VXWORKS) || defined (RTEMS) int file2dgr(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { char *remoteHostName = (char *) a1; char *fileName = (char *) a2; if (a3 > 0) { cyclesRequested = a3; } #else int main(int argc, char **argv) { char *remoteHostName; char *fileName; if (argc < 3) { writeMemo("Usage: file2dgr []"); return 0; } remoteHostName = argv[1]; fileName = argv[2]; if (argc > 3) { cyclesRequested = atoi(argv[3]); if (cyclesRequested < 1) { cyclesRequested = 1; } } #endif return run_file2dgr(remoteHostName, fileName); } ion-3.2.0~dfsg1.orig/dgr/test/file2udp.c0000644000175000017500000002735712260400056016315 0ustar l3onl3on/* file2udp.c: a UDP benchmark sender. */ /* */ /* Copyright (c) 2003, California Institute of Technology. */ /* All rights reserved. */ #include static char *eofLine = EOF_LINE_TEXT; static int eofLineLen; static int cyclesRequested = 1; static struct sockaddr socketName; static struct sockaddr_in *inetName; static struct rtt_struct rttinfo; /* used by rtt_XXX() */ static int rttfirst = 1; static int tout_flag; /* used in this file only */ /* * Timer routines for round-trip timing of datagrams. * * rtt_init() Called to initialize everything for a given * "connection." * rtt_newpack() Called before each new packet is transmitted on * a "connection." Initializes retransmit counter to 0. * rtt_start() Called before each packet either transmitted or * retransmitted. Calculates the timeout value for * the packet and starts the timer to calculate the RTT. * rtt_stop() Called after a packet has been received. * rtt_timeout() Called after a timeout has occurred. Tells you * if you should retransmit again, or give up. * * The difference between rtt_init() and rtt_newpack() is that the former * knows nothing about the "connection," while the latter makes use of * previous RTT information for a given "connection." */ static int exp_backoff[ RTT_MAXNREXMT + 1 ] = { 1, 2, 4, 8, 16 }; /* indexed by rtt_nrexmt: 0, 1, 2, ..., RTT_MAXNREXMT. [0] entry (==1) is not used; [1] entry (==2) is used the second time a packet is sent; ... */ /* * Initialize an RTT structure. * This function is called before the first packet is transmitted. */ static void rtt_init(register struct rtt_struct *ptr) { ptr->rtt_rtt = 0; ptr->rtt_srtt = 0; ptr->rtt_rttdev = 1.5; /* first timeout at (srtt + (2 * rttdev)) = 3 seconds */ ptr->rtt_nxtrto = 0; } /* * Initialize the retransmit counter before a packet is transmitted * the first time. */ static void rtt_newpack(register struct rtt_struct *ptr) { ptr->rtt_nrexmt = 0; } /* * Start our RTT timer. * This should be called right before the alarm() call before a packet * is received. We calculate the integer alarm() value to use for the * timeout (RTO) and return it as the value of the function. */ static int rtt_start(register struct rtt_struct *ptr) { register int rexmt; if (ptr->rtt_nrexmt > 0) { /* * This is a retransmission. No need to obtain the * starting time, as we won't use the RTT for anything. * Just apply the exponential back off and return. */ ptr->rtt_currto *= exp_backoff[ ptr->rtt_nrexmt ]; return(ptr->rtt_currto); } if (gettimeofday(&ptr->time_start, (struct timezone *) 0) < 0) perror("rtt_start: gettimeofday() error"); if (ptr->rtt_nxtrto > 0) { /* * This is the first transmission of a packet *and* the * last packet had to be retransmitted. Therefore, we'll * use the final RTO for the previous packet as the * starting RTO for this packet. If that RTO is OK for * this packet, then we'll start updating the RTT estimators. */ ptr->rtt_currto = ptr->rtt_nxtrto; ptr->rtt_nxtrto = 0; return(ptr->rtt_currto); } /* * Calculate the timeout value based on current estimators: * smoothed RTT plus twice the deviation. */ rexmt = (int) (ptr->rtt_srtt + (2.0 * ptr->rtt_rttdev) + 0.5); if (rexmt < RTT_RXTMIN) rexmt = RTT_RXTMIN; else if (rexmt > RTT_RXTMAX) rexmt = RTT_RXTMAX; return( ptr->rtt_currto = rexmt ); } /* * A response was received. * Stop the timer and update the appropriate values in the structure * based on this packet's RTT. We calculate the RTT, then update the * smoothed RTT and the RTT variance. * This function should be called right after turning off the * timer with alarm(0), or right after a timeout occurs. */ static void rtt_stop(register struct rtt_struct *ptr) { double start, stop, err; if (ptr->rtt_nrexmt > 0) { /* * The response was for a packet that has been retransmitted. * We don't know which transmission the response corresponds to. * We didn't record the start time in rtt_start(), so there's * no need to record the stop time here. We also don't * update our estimators. * We do, however, save the RTO corresponding to this * response, and it'll be used for the next packet. */ ptr->rtt_nxtrto = ptr->rtt_currto; return; } ptr->rtt_nxtrto = 0; /* for next call to rtt_start() */ if (gettimeofday(&ptr->time_stop, (struct timezone *) 0) < 0) perror("rtt_stop: gettimeofday() error"); start = ((double) ptr->time_start.tv_sec) * 1000000.0 + ptr->time_start.tv_usec; stop = ((double) ptr->time_stop.tv_sec) * 1000000.0 + ptr->time_stop.tv_usec; ptr->rtt_rtt = (stop - start) / 1000000.0; /* in seconds */ /* * Update our estimators of RTT and mean deviation of RTT. * See Jacobson's SIGCOMM '88 paper, Appendix A, for the details. * This appendix also contains a fixed-point, integer implementation * (that is actually used in all the post-4.3 TCP code). * We'll use floating point here for simplicity. * * First * err = (rtt - old_srtt) = difference between this measured value * and current estimator. * and * new_srtt = old_srtt*7/8 + rtt/8. * Then * new_srtt = old_srtt + err/8. * * Also * new_rttdev = old_rttdev + (|err| - old_rttdev)/4. */ err = ptr->rtt_rtt - ptr->rtt_srtt; ptr->rtt_srtt += err / 8; if (err < 0.0) err = -err; /* |err| */ ptr->rtt_rttdev += (err - ptr->rtt_rttdev) / 4; } /* * A timeout has occurred. * This function should be called right after the timeout alarm occurs. * Return -1 if it's time to give up, else return 0. */ static int rtt_timeout(register struct rtt_struct *ptr) { rtt_stop(ptr); if (++ptr->rtt_nrexmt > RTT_MAXNREXMT) return (-1); /* time to give up for this packet */ return (0); } #if 0 /* * Print debugging information on stderr, if the "rtt_d_flag" is nonzero. */ static void rtt_debug(register struct rtt_struct *ptr) { if (rtt_d_flag == 0) return; fprintf(stderr, "rtt = %.5f, srtt = %.3f, rttdev = %.3f, currto = %d\n", ptr->rtt_rtt, ptr->rtt_srtt, ptr->rtt_rttdev, ptr->rtt_currto); fflush(stderr); } #endif /* * Signal handler for timeouts (SIGALRM). * This function is called when the alarm() value that was set counts * down to zero. This indicates that we haven't received a response * from the server to the last datagram we sent. * All we do is set a flag and return from the signal handler. * The occurrence of the signal interrupts the recvfrom() system call * (errno = EINTR) above, and we then check the tout_flag flag. */ static void to_alarm() { printf("!"); fflush(stdout); tout_flag = 1; /* set flag for function above */ } /* * Send a datagram to a server, and read a response. * Establish a timer and resend as necessary. * This function is intended for those applications that send a datagram * and expect a response. * Returns actual size of received datagram, or -1 if error or no response. */ static int dgsendrecv(int fd, /* datagram socket */ char *outbuff, /* pointer to buffer to send */ int outbytes, /* #bytes to send */ char *inbuff, /* pointer to buffer to receive into */ int inbytes, /* max #bytes to receive */ struct sockaddr *destaddr, /* destination address */ /* can be 0, if datagram socket is connect'ed */ int destlen) /* sizeof(destaddr) */ { int n; int interval; if (rttfirst == 1) { rtt_init(&rttinfo); /* initialize first time we're called */ rttfirst = 0; } rtt_newpack(&rttinfo); /* initialize for new packet */ while (1) { /* Send the datagram. */ if (sendto(fd, outbuff, outbytes, 0, destaddr, destlen) != outbytes) { perror("dgsendrecv: sendto error on socket"); return -1; } signal(SIGALRM, to_alarm); tout_flag = 0; /* for signal handler */ interval = rtt_start(&rttinfo); /* calc timeout value */ printf("%d ", interval); fflush(stdout); alarm(interval); /* start timer */ n = recvfrom(fd, inbuff, inbytes, 0, (struct sockaddr *) 0, (socklen_t *) 0); if (n < 0) { if (tout_flag) { /* The recvfrom() above timed out. See if * we've retransmitted enough, and if so * quit, otherwise try again. */ if (rtt_timeout(&rttinfo) < 0) { perror("dgsendrecv: no response from \ server"); rttfirst = 1; /* reinit for next */ return -1; /* errno will be EINTR */ } /* Must send the datagram again. */ errno = 0; /* clear the error flag */ #ifdef DEBUG perror("dgsendrecv: timeout, retransmitting"); rtt_d_flag = 1; rtt_debug(&rttinfo); #endif continue; } perror("dgsendrecv: recvfrom error"); return -1; } break; /* Out of while(1) loop. */ } alarm(0); /* stop signal timer */ rtt_stop(&rttinfo); /* stop RTT timer, calc & store new values */ #ifdef DEBUG rtt_debug(&rttinfo); #endif return(n); /* return size of received datagram */ } static int rsend(int sock, char *line, int lineLen) { static long seqCounter; char buffer[256]; long ack; seqCounter++; memcpy(buffer, (char *) &seqCounter, 40); memcpy(buffer + 4, line, lineLen); while (1) { if (dgsendrecv(sock, buffer, lineLen + 4, (char *) &ack, sizeof ack, &socketName, sizeof socketName) < 0) { perror("dgsendrecv failed"); return -1; } if (ack == seqCounter) { return 0; } } } static void report(struct timeval *startTime, unsigned long bytesSent) { struct timeval endTime; unsigned long usec; float rate; getCurrentTime(&endTime); if (endTime.tv_usec < startTime->tv_usec) { endTime.tv_sec--; endTime.tv_usec += 1000000; } usec = ((endTime.tv_sec - startTime->tv_sec) * 1000000) + (endTime.tv_usec - startTime->tv_usec); printf("Bytes sent = %lu, usec elapsed = %lu.\n", bytesSent, usec); rate = (float) (8 * bytesSent) / (float) (usec / 1000000); printf("Sending %7.2f bits per second.\n", rate); } int main(int argc, char **argv) { int cyclesLeft; char *remoteHostName; unsigned long remoteIpAddress; unsigned short portNbr = TEST_PORT_NBR; unsigned long hostNbr; int sock; char *fileName; FILE *inputFile; char line[256]; int lineLen; struct timeval startTime; unsigned long bytesSent; if (argc < 3) { puts("Usage: file2udp \ []"); exit(0); } if (argc > 3) { cyclesRequested = atoi(argv[3]); if (cyclesRequested < 1) { cyclesRequested = 1; } } cyclesLeft = cyclesRequested; /* Prepare for UDP transmissions. */ remoteHostName = argv[1]; remoteIpAddress = getInternetAddress(remoteHostName); hostNbr = htonl(remoteIpAddress); memset((char *) &socketName, 0, sizeof socketName); inetName = (struct sockaddr_in *) &socketName; inetName->sin_family = AF_INET; inetName->sin_port = htons(portNbr); memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &hostNbr, 4); sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { perror("Can't open udp socket"); exit(0); } /* Open file to send. */ fileName = argv[2]; inputFile = fopen(fileName, "r"); if (inputFile == NULL) { perror("Can't open input file"); exit(0); } eofLineLen = strlen(eofLine); getCurrentTime(&startTime); bytesSent = 0; /* Copy text lines from file to SDR. */ while (cyclesLeft > 0) { if (fgets(line, 256, inputFile) == NULL) { if (feof(inputFile)) { if (rsend(sock, eofLine, eofLineLen) < 0) { exit(0); } bytesSent += eofLineLen; fclose(inputFile); inputFile = fopen(fileName, "r"); if (inputFile == NULL) { perror("Can't reopen input file"); exit(0); } cyclesLeft--; continue; } else { perror("Can't read from input file"); exit(0); } } lineLen = strlen(line); if (rsend(sock, line, lineLen) < 0) { exit(0); } bytesSent += lineLen; } report(&startTime, bytesSent); close(sock); return 0; } ion-3.2.0~dfsg1.orig/dgr/test/file2tcp.c0000644000175000017500000001351112260400056016276 0ustar l3onl3on/* file2tcp.c: a TCP benchmark sender. */ /* */ /* Copyright (c) 2003, California Institute of Technology. */ /* All rights reserved. */ /* Author: Scott Burleigh, Jet Propulsion Laboratory */ /* */ #include static unsigned short portNbr = TEST_PORT_NBR; static char *eofLine = EOF_LINE_TEXT; static int eofLineLen; static int cyclesRequested = 1; static int nbrOfConnections = 0; static int connectToRecvr(struct sockaddr *sn, int *sock) { *sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (*sock < 0) { perror("Can't open TCP socket"); return -1; } if (connect(*sock, sn, sizeof(struct sockaddr)) < 0) { close(*sock); *sock = -1; perror("Can't TCP-connect to receiver"); return -1; } nbrOfConnections++; return 0; } static int sendBytesByTCP(int *contactSocket, char *from, int length) { int bytesWritten; while (1) { bytesWritten = write(*contactSocket, from, length); if (bytesWritten < 0) { switch (errno) { case EINTR: /* Interrupted; retry. */ continue; case EPIPE: /* Lost connection. */ case EBADF: case ECONNRESET: close(*contactSocket); *contactSocket = -1; } perror("write() error on socket"); } return bytesWritten; } } static int sendBufferByTCP(struct sockaddr *socketName, int *contactSocket, unsigned char *buffer, int length, int *totalBytesSent) { int result; unsigned long preamble; int bytesToSend; char *from; int bytesSent; *totalBytesSent = 0; if (*contactSocket < 0) { result = connectToRecvr(socketName, contactSocket); if (result) { /* Treat I/O error as a transient anomaly, * note incomplete transmission. */ return 0; } } /* Send preamble (length), telling Recvr how much to read. */ preamble = htonl(length); bytesToSend = sizeof(preamble); from = (char *) &preamble; while (bytesToSend > 0) { bytesSent = sendBytesByTCP(contactSocket, from, bytesToSend); if (bytesSent < 0) { if (*contactSocket == -1) { /* Just lost connection; treat * as a transient anomaly, note * incomplete transmission. */ return 0; } /* Big problem; shut down. */ return -1; } from += bytesSent; bytesToSend -= bytesSent; } /* Send the buffer itself. */ bytesToSend = length; from = (char *) buffer; while (bytesToSend > 0) { bytesSent = sendBytesByTCP(contactSocket, from, bytesToSend); if (bytesSent < 0) { if (*contactSocket == -1) { /* Just lost connection; treat * as a transient anomaly, note * incomplete transmission. */ return 0; } /* Big problem; shut down. */ return -1; } from += bytesSent; bytesToSend -= bytesSent; *totalBytesSent += bytesSent; } return 0; } static void report(struct timeval *startTime, unsigned long bytesSent) { struct timeval endTime; unsigned long usec; float rate; getCurrentTime(&endTime); if (endTime.tv_usec < startTime->tv_usec) { endTime.tv_sec--; endTime.tv_usec += 1000000; } printf("Made %d connections.\n", nbrOfConnections); usec = ((endTime.tv_sec - startTime->tv_sec) * 1000000) + (endTime.tv_usec - startTime->tv_usec); printf("Bytes sent = %lu, usec elapsed = %lu.\n", bytesSent, usec); rate = (float) (8 * bytesSent) / (float) (usec / 1000000); printf("Sending %7.2f bits per second.\n", rate); } int main(int argc, char **argv) { int nbrOfPeers; int fdPoolSize = 250; int cyclesLeft; char *remoteHostName; unsigned long remoteIpAddress; unsigned long hostNbr; struct sockaddr socketName; struct sockaddr_in *inetName; int contactSocket = -1; char *fileName; FILE *inputFile; char line[256]; int lineLen; int result; struct timeval startTime; unsigned long bytesSent; if (argc < 4) { puts("Usage: file2tcp \ []"); exit(0); } nbrOfPeers = atoi(argv[3]); if (nbrOfPeers < 1) { nbrOfPeers = 1; } if (argc > 4) { cyclesRequested = atoi(argv[4]); if (cyclesRequested < 1) { cyclesRequested = 1; } } cyclesLeft = cyclesRequested; /* Prepare for TCP connections. */ remoteHostName = argv[1]; remoteIpAddress = getInternetAddress(remoteHostName); hostNbr = htonl(remoteIpAddress); memset((char *) &socketName, 0, sizeof socketName); inetName = (struct sockaddr_in *) &socketName; inetName->sin_family = AF_INET; inetName->sin_port = htons(portNbr); memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &hostNbr, 4); /* Get file to copy. */ fileName = argv[2]; inputFile = fopen(fileName, "r"); if (inputFile == NULL) { perror("Can't open input file"); exit(0); } eofLineLen = strlen(eofLine); getCurrentTime(&startTime); bytesSent = 0; /* Copy text lines from file to receiver. */ while (cyclesLeft > 0) { if (fgets(line, 256, inputFile) == NULL) { if (feof(inputFile)) { if (sendBufferByTCP(&socketName, &contactSocket, (unsigned char *) eofLine, eofLineLen, &result)) { perror("tcp send failed"); exit(0); } bytesSent += eofLineLen; if ((rand() % nbrOfPeers) >= fdPoolSize) { close(contactSocket); contactSocket = -1; } fclose(inputFile); inputFile = fopen(fileName, "r"); if (inputFile == NULL) { perror("Can't reopen input file"); exit(0); } cyclesLeft--; continue; } else { perror("Can't read from input file"); exit(0); } } lineLen = strlen(line); if (sendBufferByTCP(&socketName, &contactSocket, (unsigned char *) line, lineLen, &result)) { perror("tcp send failed"); exit(0); } bytesSent += lineLen; if ((rand() % nbrOfPeers) >= fdPoolSize) { close(contactSocket); contactSocket = -1; } } report(&startTime, bytesSent); if (contactSocket >= 0) { close(contactSocket); } return 0; } ion-3.2.0~dfsg1.orig/dgr/test/dgr2file.c0000644000175000017500000000461612260400056016272 0ustar l3onl3on/* dgr2file.c: a test consumer of DGR activity. */ /* */ /* Copyright (c) 2003, California Institute of Technology. */ /* All rights reserved. */ /* Author: Scott Burleigh, Jet Propulsion Laboratory */ /* */ #include static int dgr2file_stopped = 0; static Dgr dgr2file_dgr; static int cycleNbr = 0; static void handleQuit() { dgr2file_stopped = 1; dgr_interrupt(dgr2file_dgr); } static FILE *openFile() { char fileName[256]; FILE *outputFile; cycleNbr++; isprintf(fileName, sizeof fileName, "file_copy_%d", cycleNbr); outputFile = fopen(fileName, "a"); if (outputFile == NULL) { perror("can't open output file"); } return outputFile; } #if defined (VXWORKS) || defined (RTEMS) int dgr2file(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) #else int main(int argc, char **argv) #endif { char ownHostName[MAXHOSTNAMELEN + 1]; unsigned int ownIpAddress; unsigned short portNbr = TEST_PORT_NBR; DgrRC rc; FILE *outputFile; unsigned int remoteIpAddress; unsigned short remotePortNbr; char line[256]; int lineSize; int errnbr; getNameOfHost(ownHostName, sizeof ownHostName); ownIpAddress = getInternetAddress(ownHostName); if (dgr_open(ownIpAddress, 2, portNbr, ownIpAddress, NULL, &dgr2file_dgr, &rc) < 0) { perror("can't open dgr service"); return 0; } outputFile = openFile(); if (outputFile == NULL) return 0; printf("working on cycle %d.\n", cycleNbr); signal(SIGINT, handleQuit); while (1) { if (dgr2file_stopped) { break; } lineSize = sizeof line; if (dgr_receive(dgr2file_dgr, &remotePortNbr, &remoteIpAddress, line, &lineSize, &errnbr, DGR_BLOCKING, &rc) < 0) { putErrmsg("dg_receive failed.", NULL); return 0; } switch (rc) { case DgrDatagramReceived: break; case DgrInterrupted: dgr2file_stopped = 1; continue; default: putErrmsg("dgr_receive got unrecognized result.", itoa(rc)); return 0; } /* Process text of line. */ line[lineSize] = '\0'; if (strcmp(line, EOF_LINE_TEXT) == 0) { fclose(outputFile); outputFile = openFile(); if (outputFile == NULL) return 0; printf("working on cycle %d.\n", cycleNbr); } else /* Just write line to output file. */ { if (fputs(line, outputFile) < 0) { perror("can't write to output file"); return 0; } } } dgr_close(dgr2file_dgr); return 0; } ion-3.2.0~dfsg1.orig/dgr/test/udp2file.c0000644000175000017500000000503512260400056016302 0ustar l3onl3on/* udp2file.c: a test consumer of DGR activity. */ /* */ /* Copyright (c) 2003, California Institute of Technology. */ /* All rights reserved. */ /* Author: Scott Burleigh, Jet Propulsion Laboratory */ /* */ #include static int stopped = 0; static void handleQuit() { stopped = 1; } static int cycleNbr = 0; static FILE *openFile() { char fileName[256]; FILE *outputFile; cycleNbr++; isprintf(fileName, sizeof fileName, "file_copy_%d", cycleNbr); outputFile = fopen(fileName, "a"); if (outputFile == NULL) { perror("Can't open output file"); } return outputFile; } int main(int argc, char **argv) { char ownHostName[MAXHOSTNAMELEN + 1]; unsigned long ownIpAddress; unsigned short portNbr = TEST_PORT_NBR; unsigned long hostNbr; struct sockaddr socketName; struct sockaddr_in *inetName; struct sockaddr remoteSocknm; socklen_t remoteSocknmSize; int sock; FILE *outputFile; char line[256]; int lineSize; /* Prepare for UDP reception. */ getNameOfHost(ownHostName, sizeof ownHostName); ownIpAddress = getInternetAddress(ownHostName); hostNbr = htonl(ownIpAddress); memset((char *) &socketName, 0, sizeof socketName); inetName = (struct sockaddr_in *) &socketName; inetName->sin_family = AF_INET; inetName->sin_port = htons(portNbr); memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &hostNbr, 4); sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { perror("Can't open udp socket"); exit(0); } if (bind(sock, &socketName, sizeof(socketName)) < 0) { perror("Can't bind udp socket"); } outputFile = openFile(); if (outputFile == NULL) exit(0); signal(SIGINT, handleQuit); while (1) { if (stopped) { break; } lineSize = sizeof line; remoteSocknmSize = sizeof remoteSocknm; lineSize = recvfrom(sock, line, lineSize, 0, &remoteSocknm, &remoteSocknmSize); if (lineSize < 0) { perror("udp receive failed"); exit(0); } /* Acknowledge the transmission. */ if (sendto(sock, line, 4, 0, &remoteSocknm, remoteSocknmSize) != 4) { perror("udp send failed"); exit(0); } /* Process text of line. */ line[lineSize] = '\0'; if (strcmp(line + 4, EOF_LINE_TEXT) == 0) { fclose(outputFile); outputFile = openFile(); if (outputFile == NULL) exit(0); printf("working on cycle %d.\n", cycleNbr); } else /* Just write line to output file. */ { if (fputs(line + 4, outputFile) < 0) { perror("Can't write to output file"); exit(0); } } } close(sock); return 0; } ion-3.2.0~dfsg1.orig/dgr/test/file2dgr.h0000644000175000017500000000030412260400056016265 0ustar l3onl3on/* * * file2dgr.h: definitions used for the file2dgr DGR * benchmark system. * * */ #include "dgr.h" #define TEST_PORT_NBR 2101 #define EOF_LINE_TEXT "*** End of the file ***" ion-3.2.0~dfsg1.orig/dgr/test/tcp2file.c0000644000175000017500000001064212260400056016300 0ustar l3onl3on/* tcp2file.c: a TCP benchmark receiver. */ /* */ /* Copyright (c) 2003, California Institute of Technology. */ /* All rights reserved. */ /* Author: Scott Burleigh, Jet Propulsion Laboratory */ /* */ #include static int stopped = 0; static int cycleNbr = 0; static int accessSocket = -1; static void handleQuit() { stopped = 1; } static int receiveBytesByTCP(int *sock, char *into, int length) { int bytesRead; struct sockaddr newSocketName; socklen_t nameLength = sizeof(newSocketName); while (1) { bytesRead = read(*sock, into, length); switch (bytesRead) { case -1: if (errno == EINTR) { continue; } perror("read() error on socket"); return -1; /* Intentional fall-through to next case. */ case 0: /* Connection closed. */ close(*sock); while (1) { *sock = accept(accessSocket, &newSocketName, &nameLength); if (*sock < 0) { if (errno == EINTR) { continue; } perror("accept() failed"); exit(0); } break; /* Out of accept() loop. */ } continue; /* read() loop. */ default: return bytesRead; } } } static int receiveData(int *sock, char *buffer, int *bufferLength) { unsigned long preamble; int bytesToReceive; char *into; int bytesReceived; int length; /* Receive length of transmitted data buffer. */ length = sizeof preamble; bytesToReceive = length; into = (char *) &preamble; while (bytesToReceive > 0) { bytesReceived = receiveBytesByTCP(sock, into, bytesToReceive); if (bytesReceived < 0) { return -1; } into += bytesReceived; bytesToReceive -= bytesReceived; } /* Receive the data buffer itself. */ length = ntohl(preamble); *bufferLength = bytesToReceive = length; into = buffer; while (bytesToReceive > 0) { bytesReceived = receiveBytesByTCP(sock, into, bytesToReceive); if (bytesReceived < 0) { return -1; } into += bytesReceived; bytesToReceive -= bytesReceived; } return 0; } static FILE *openFile() { char fileName[256]; FILE *outputFile; cycleNbr++; isprintf(fileName, sizeof fileName, "file_copy_%d", cycleNbr); outputFile = fopen(fileName, "a"); if (outputFile == NULL) { perror("Can't open output file"); } return outputFile; } int main(int argc, char **argv) { char ownHostName[MAXHOSTNAMELEN + 1]; unsigned long ownIpAddress; unsigned short portNbr = TEST_PORT_NBR; unsigned long hostNbr; struct sockaddr socketName; struct sockaddr_in *inetName; socklen_t nameLength; int newSocket = -1; struct sockaddr newSocketName; FILE *outputFile; char line[256]; int lineSize; getNameOfHost(ownHostName, sizeof ownHostName); ownIpAddress = getInternetAddress(ownHostName); /* Open dial-up socket to accept connections on. */ hostNbr = htonl(ownIpAddress); memset((char *) &socketName, 0, sizeof socketName); inetName = (struct sockaddr_in *) &socketName; inetName->sin_family = AF_INET; inetName->sin_port = htons(portNbr); memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &hostNbr, 4); accessSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (accessSocket < 0) { perror("Can't open TCP socket"); exit(0); } nameLength = sizeof(struct sockaddr); if (reUseAddress(accessSocket) || bind(accessSocket, &socketName, nameLength) < 0 || listen(accessSocket, 5) < 0 || getsockname(accessSocket, &socketName, &nameLength) < 0) { close(accessSocket); perror("Can't initialize socket"); exit(0); } signal(SIGINT, handleQuit); /* Open first output file copy. */ outputFile = openFile(); if (outputFile == NULL) exit(0); /* Accept initial connection. */ while (1) { newSocket = accept(accessSocket, &newSocketName, &nameLength); if (newSocket < 0) { if (errno == EINTR) { continue; } perror("accept() failed"); exit(0); } break; } /* Begin reception loop. */ while (1) { if (stopped) { break; } lineSize = sizeof line - 1; if (receiveData(&newSocket, line, &lineSize)) { exit(0); } /* Process text of line. */ line[lineSize] = '\0'; if (strcmp(line, EOF_LINE_TEXT) == 0) { fclose(outputFile); outputFile = openFile(); if (outputFile == NULL) exit(0); printf("working on cycle %d.\n", cycleNbr); } else /* Just write line to output file. */ { if (fputs(line, outputFile) < 0) { perror("Can't write to output file"); exit(0); } } } return 0; } ion-3.2.0~dfsg1.orig/dgr/test/file2tcp.h0000644000175000017500000000030512260400056016300 0ustar l3onl3on/* * * file2tcp.h: definitions used for the file2tcp benchmark * system. * * */ #include "platform.h" #define TEST_PORT_NBR 2101 #define EOF_LINE_TEXT "*** End of the file ***" ion-3.2.0~dfsg1.orig/dgr/i86-redhat/0000755000175000017500000000000012260400056015315 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/i86-redhat/Makefile0000644000175000017500000000322612260400056016760 0ustar l3onl3onINCL = ../include API = ../library TEST = ../test # OPT = -O -Dlinux # OPT = -g -Wall -Dlinux -DINITIAL_RETARD=2 OPT = -g -Wall -Werror -Dlinux CC = gcc $(OPT) -I$(API) -I$(TEST) -I$(INCL) -I$(ROOT)/include LDFLAGS = -fPIC -shared -rdynamic LD = gcc $(LDFLAGS) LIBDGROBJS = \ libdgr.o PUBINCLS = \ $(INCL)/dgr.h RUNTIMES = file2dgr dgr2file file2tcp tcp2file file2udp udp2file ALL = check libdgr.so $(RUNTIMES) all: $(ALL) check: $(PUBINCLS) rm -f *.o touch check clean: rm -f *.o rm -f $(ALL) rm -f ./lib/* rm -f ./bin/* install: cp ../include/* $(ROOT)/include cp lib/* $(ROOT)/lib cp bin/* $(ROOT)/bin # - - Test executables - - - - file2dgr: file2dgr.o libdgr.so $(TEST)/file2dgr.h $(CC) -o file2dgr file2dgr.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread cp file2dgr ./bin dgr2file: dgr2file.o libdgr.so $(TEST)/file2dgr.h $(CC) -o dgr2file dgr2file.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread cp dgr2file ./bin tcp2file: tcp2file.o $(TEST)/file2tcp.h $(CC) -o tcp2file tcp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread cp tcp2file ./bin file2tcp: file2tcp.o $(TEST)/file2tcp.h $(CC) -o file2tcp file2tcp.o -L$(ROOT)/lib -L./lib -lici -lpthread cp file2tcp ./bin udp2file: udp2file.o $(TEST)/file2udp.h $(CC) -o udp2file udp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread cp udp2file ./bin file2udp: file2udp.o $(TEST)/file2udp.h $(CC) -o file2udp file2udp.o -L$(ROOT)/lib -L./lib -lici -lpthread cp file2udp ./bin # - - Libraries - - - - - libdgr.so: $(LIBDGROBJS) $(LD) -o libdgr.so $(LIBDGROBJS) cp libdgr.so ./lib # - - Object modules - - - - - %.o: $(API)/%.c $(CC) -c $< %.o: $(TEST)/%.c $(CC) -c $< ion-3.2.0~dfsg1.orig/dgr/arm-uClibc/0000755000175000017500000000000012260400056015420 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/arm-uClibc/Makefile0000644000175000017500000000327112260400056017063 0ustar l3onl3onINCL = ../include API = ../library TEST = ../test # OPT = -O -DuClibc # OPT = -g -Wall -DuClibc -DINITIAL_RETARD=2 OPT = -g -fPIC -Wall -Werror -DuClibc CC = $(TCC) $(OPT) -I$(API) -I$(TEST) -I$(INCL) -I$(ROOT)/include LDFLAGS = -fPIC -shared LD = $(TLD) $(LDFLAGS) LIBDGROBJS = \ libdgr.o PUBINCLS = \ $(INCL)/dgr.h RUNTIMES = file2dgr dgr2file file2tcp tcp2file file2udp udp2file ALL = check libdgr.so $(RUNTIMES) all: $(ALL) check: $(PUBINCLS) rm -f *.o touch check mkdir -p lib mkdir -p bin clean: rm -f *.o rm -f $(ALL) rm -f ./lib/* rm -f ./bin/* install: cp ../include/* $(ROOT)/include cp lib/* $(ROOT)/lib cp bin/* $(ROOT)/bin # - - Test executables - - - - file2dgr: file2dgr.o libdgr.so $(TEST)/file2dgr.h $(CC) -o file2dgr file2dgr.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread cp file2dgr ./bin dgr2file: dgr2file.o libdgr.so $(TEST)/file2dgr.h $(CC) -o dgr2file dgr2file.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread cp dgr2file ./bin tcp2file: tcp2file.o $(TEST)/file2tcp.h $(CC) -o tcp2file tcp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread cp tcp2file ./bin file2tcp: file2tcp.o $(TEST)/file2tcp.h $(CC) -o file2tcp file2tcp.o -L$(ROOT)/lib -L./lib -lici -lpthread cp file2tcp ./bin udp2file: udp2file.o $(TEST)/file2udp.h $(CC) -o udp2file udp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread cp udp2file ./bin file2udp: file2udp.o $(TEST)/file2udp.h $(CC) -o file2udp file2udp.o -L$(ROOT)/lib -L./lib -lici -lpthread cp file2udp ./bin # - - Libraries - - - - - libdgr.so: $(LIBDGROBJS) $(LD) -o libdgr.so $(LIBDGROBJS) cp libdgr.so ./lib # - - Object modules - - - - - %.o: $(API)/%.c $(CC) -c $< %.o: $(TEST)/%.c $(CC) -c $< ion-3.2.0~dfsg1.orig/dgr/sparc-sol9/0000755000175000017500000000000012260400056015436 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/sparc-sol9/Makefile0000644000175000017500000000330312260400056017075 0ustar l3onl3onINCL = ../include API = ../library TEST = ../test OPT = -g -Wall -Werror -Dsol5 -Dunix -D__SVR4 -D_REENTRANT -fPIC CC = gcc $(OPT) -I$(API) -I$(TEST) -I$(INCL) -I$(ROOT)/include LDFLAGS = -fPIC -shared LD = gcc $(LDFLAGS) LIBDGROBJS = \ libdgr.o PUBINCLS = \ $(INCL)/dgr.h RUNTIMES = file2dgr dgr2file file2tcp tcp2file file2udp udp2file ALL = check libdgr.so $(RUNTIMES) all: $(ALL) check: $(PUBINCLS) rm -f *.o touch check clean: rm -f *.o rm -f $(ALL) rm -f ./lib/* rm -f ./bin/* install: cp ../include/* $(ROOT)/include cp lib/* $(ROOT)/lib cp bin/* $(ROOT)/bin # - - Test executables - - - - file2dgr: file2dgr.o libdgr.so $(TEST)/file2dgr.h $(CC) -o file2dgr file2dgr.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread -lrt -lsocket cp file2dgr ./bin dgr2file: dgr2file.o libdgr.so $(TEST)/file2dgr.h $(CC) -o dgr2file dgr2file.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread -lrt -lsocket cp dgr2file ./bin tcp2file: tcp2file.o $(TEST)/file2tcp.h $(CC) -o tcp2file tcp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread -lrt -lsocket cp tcp2file ./bin file2tcp: file2tcp.o $(TEST)/file2tcp.h $(CC) -o file2tcp file2tcp.o -L$(ROOT)/lib -L./lib -lici -lpthread -lrt -lsocket cp file2tcp ./bin udp2file: udp2file.o $(TEST)/file2udp.h $(CC) -o udp2file udp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread -lrt -lsocket cp udp2file ./bin file2udp: file2udp.o $(TEST)/file2udp.h $(CC) -o file2udp file2udp.o -L$(ROOT)/lib -L./lib -lici -lpthread -lrt -lsocket cp file2udp ./bin # - - Libraries - - - - - libdgr.so: $(LIBDGROBJS) $(LD) -o libdgr.so $(LIBDGROBJS) cp libdgr.so ./lib # - - Object modules - - - - - %.o: $(API)/%.c $(CC) -c $< %.o: $(TEST)/%.c $(CC) -c $< ion-3.2.0~dfsg1.orig/dgr/Makefile0000644000175000017500000000124712260400056015106 0ustar l3onl3onOPT = /opt PLATFORMS = i86-redhat # i86_64-fedora # sparc-sol9 # i86-freebsd all: cd doc; \ mkdir -p man; \ mkdir -p man/man1; \ mkdir -p man/man3; \ mkdir -p html; \ mkdir -p html/man1; \ mkdir -p html/man3; \ gmake all ROOT=$(OPT); \ cd ..; \ for PF in $(PLATFORMS); \ do \ cd $$PF; \ mkdir -p bin; \ mkdir -p lib; \ gmake all ROOT=$(OPT); \ cd ..; \ done clean: cd doc; \ gmake -i clean; \ cd ..; \ for PF in $(PLATFORMS); \ do cd $$PF; gmake -i clean; cd ..; done install: cd doc; \ gmake -i install ROOT=$(OPT); \ cd ..; \ for PF in $(PLATFORMS); \ do cd $$PF; gmake -i install ROOT=$(OPT); cd ..; done ion-3.2.0~dfsg1.orig/dgr/i86-darwin/0000755000175000017500000000000012260400056015332 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/i86-darwin/Makefile0000644000175000017500000000325412260400056016776 0ustar l3onl3onINCL = ../include API = ../library TEST = ../test # OPT = -O -Dlinux # OPT = -g -Wall -Dlinux -DINITIAL_RETARD=2 OPT = -g -Wall -Werror -Dunix -Ddarwin CC = gcc $(OPT) -I$(API) -I$(TEST) -I$(INCL) -I$(ROOT)/include LDFLAGS = -dynamiclib -undefined dynamic_lookup LD = gcc $(LDFLAGS) LIBDGROBJS = \ libdgr.o PUBINCLS = \ $(INCL)/dgr.h RUNTIMES = file2dgr dgr2file file2tcp tcp2file file2udp udp2file ALL = check libdgr.so $(RUNTIMES) all: $(ALL) check: $(PUBINCLS) rm -f *.o touch check clean: rm -f *.o rm -f $(ALL) rm -f ./lib/* rm -f ./bin/* install: cp ../include/* $(ROOT)/include cp lib/* $(ROOT)/lib cp bin/* $(ROOT)/bin # - - Test executables - - - - file2dgr: file2dgr.o libdgr.so $(TEST)/file2dgr.h $(CC) -o file2dgr file2dgr.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread cp file2dgr ./bin dgr2file: dgr2file.o libdgr.so $(TEST)/file2dgr.h $(CC) -o dgr2file dgr2file.o -L./lib -L$(ROOT)/lib -ldgr -lici -lpthread cp dgr2file ./bin tcp2file: tcp2file.o $(TEST)/file2tcp.h $(CC) -o tcp2file tcp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread cp tcp2file ./bin file2tcp: file2tcp.o $(TEST)/file2tcp.h $(CC) -o file2tcp file2tcp.o -L$(ROOT)/lib -L./lib -lici -lpthread cp file2tcp ./bin udp2file: udp2file.o $(TEST)/file2udp.h $(CC) -o udp2file udp2file.o -L$(ROOT)/lib -L./lib -lici -lpthread cp udp2file ./bin file2udp: file2udp.o $(TEST)/file2udp.h $(CC) -o file2udp file2udp.o -L$(ROOT)/lib -L./lib -lici -lpthread cp file2udp ./bin # - - Libraries - - - - - libdgr.so: $(LIBDGROBJS) $(LD) -o libdgr.so $(LIBDGROBJS) cp libdgr.so ./lib # - - Object modules - - - - - %.o: $(API)/%.c $(CC) -c $< %.o: $(TEST)/%.c $(CC) -c $< ion-3.2.0~dfsg1.orig/dgr/i86_64-fedora/0000755000175000017500000000000012260400056015617 5ustar l3onl3onion-3.2.0~dfsg1.orig/dgr/i86_64-fedora/Makefile0000644000175000017500000000324212260400056017260 0ustar l3onl3onINCL = ../include API = ../library TEST = ../test # OPT = -O -Dlinux # OPT = -g -Wall -Dlinux -DINITIAL_RETARD=2 OPT = -g -Wall -Werror -Dlinux -fPIC -DSPACE_ORDER=3 CC = gcc $(OPT) -I$(API) -I$(TEST) -I$(INCL) -I${ROOT}/include LDFLAGS = -fPIC -shared LD = gcc $(LDFLAGS) LIBDGROBJS = \ libdgr.o PUBINCLS = \ $(INCL)/dgr.h RUNTIMES = file2dgr dgr2file file2tcp tcp2file file2udp udp2file ALL = check libdgr.so $(RUNTIMES) all: $(ALL) check: $(PUBINCLS) rm -f *.o touch check clean: rm -f *.o rm -f $(ALL) rm -f ./lib/* rm -f ./bin/* install: cp ../include/* $(ROOT)/include cp lib/* $(ROOT)/lib cp bin/* $(ROOT)/bin # - - Test executables - - - - file2dgr: file2dgr.o libdgr.so $(TEST)/file2dgr.h $(CC) -o file2dgr file2dgr.o -L./lib -L${ROOT}/lib -ldgr -lici -lpthread cp file2dgr ./bin dgr2file: dgr2file.o libdgr.so $(TEST)/file2dgr.h $(CC) -o dgr2file dgr2file.o -L./lib -L${ROOT}/lib -ldgr -lici -lpthread cp dgr2file ./bin tcp2file: tcp2file.o $(TEST)/file2tcp.h $(CC) -o tcp2file tcp2file.o -L${ROOT}/lib -L./lib -lici -lpthread cp tcp2file ./bin file2tcp: file2tcp.o $(TEST)/file2tcp.h $(CC) -o file2tcp file2tcp.o -L${ROOT}/lib -L./lib -lici -lpthread cp file2tcp ./bin udp2file: udp2file.o $(TEST)/file2udp.h $(CC) -o udp2file udp2file.o -L${ROOT}/lib -L./lib -lici -lpthread cp udp2file ./bin file2udp: file2udp.o $(TEST)/file2udp.h $(CC) -o file2udp file2udp.o -L${ROOT}/lib -L./lib -lici -lpthread cp file2udp ./bin # - - Libraries - - - - - libdgr.so: $(LIBDGROBJS) $(LD) -o libdgr.so $(LIBDGROBJS) cp libdgr.so ./lib # - - Object modules - - - - - %.o: $(API)/%.c $(CC) -c $< %.o: $(TEST)/%.c $(CC) -c $< ion-3.2.0~dfsg1.orig/README.txt0000644000175000017500000000575612260400055014400 0ustar l3onl3on******************************************************************* NO WARRANTY: DISCLAIMER THE SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET FORTH IN UCC 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE LICENSED PRODUCT, HOWEVER USED. IN NO EVENT SHALL CALTECH/JPL BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN FACT SHALL KNOW OF THE POSSIBILITY. USER BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED MATERIALS. ******************************************************************* Copyright 2002-2013, by the California Institute of Technology. ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. This software and/or related materials may be subject to U.S. export control laws. By accepting this software and related materials, the user agrees to comply with all applicable U.S. export laws and regulations. User has the responsibility to obtain export licenses or other export authority as may be required before exporting the software or related materials to foreign countries or providing access to foreign persons. ******************************************************************* To build the entire ION system on a Linux, OS/X, or Solaris platform, just cd into ion-open-source and enter two commands: ./configure ./make To build ION for Android, cd into ion-open-source/arch-android and see the instructions in the README.bionic text file. To build ION for RTEMS, cd into ion-open-source/arch-rtems and see the instructions in the README text file. To build ION for Windows, see the instructions in the winion.pdf document. To build ION for the ARM-based AT91SAM9G20 board, cd into ion-open-source/arch-uClibc and see the instructions in the "ARM build.pdf" file. It's also possible to build the individual packages of ION, using platform-specific Makefiles in the package subdirectories. If you choose this option, be aware of the dependencies among the packages: The "ici" package must be built ("make" and "make install") before any other package. The "bp" package is dependent on "dgr" and "ltp" as well as "ici". The "cfdp", "ams", and "bss" packages are dependent on "bp". The "restart" package is dependent on "cfdp", "bp", "ltp", and "ici". Additional details are provided in the README.txt files in the root directories of some of the subsystems. Note that the default individual build of the ams package requires that the "expat" library be installed; this can be overridden at compile time. Also note that all Makefiles are for gmake; on a freebsd platform, be sure to install gmake before trying to build ION. Scott Burleigh, JPL scott.c.burleigh@jpl.nasa.gov ion-3.2.0~dfsg1.orig/arch-rtems/0000755000175000017500000000000012260400055014732 5ustar l3onl3onion-3.2.0~dfsg1.orig/arch-rtems/pmqlsi.c0000644000175000017500000000646212260400055016413 0ustar l3onl3on/* pmqlsi.c: LTP PMQ-based link service daemon. Receives LTP segments via a POSIX message queue. Author: Scott Burleigh, JPL Copyright (c) 2010, California Institute of Technology. ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. */ #include "pmqlsa.h" static void interruptThread() { isignal(SIGTERM, interruptThread); } /* * * Receiver thread functions * * */ typedef struct { mqd_t mq; pthread_t mainThread; int running; } ReceiverThreadParms; static void *handleMessages(void *parm) { /* Main loop for message reception and handling. */ ReceiverThreadParms *rtp = (ReceiverThreadParms *) parm; int segLength; char msgbuf[PMQLSA_MSGSIZE]; unsigned int mqp; /* Priority of rec'd msg. */ iblock(SIGTERM); while (rtp->running) { segLength = mq_receive(rtp->mq, msgbuf, sizeof msgbuf, &mqp); switch (segLength) { case 1: /* Normal stop. */ continue; case -1: putSysErrmsg("pmqlsi failed receiving msg", NULL); pthread_kill(rtp->mainThread, SIGTERM); rtp->running = 0; continue; } if (ltpHandleInboundSegment(msgbuf, segLength) < 0) { putErrmsg("Can't handle inbound segment.", NULL); pthread_kill(rtp->mainThread, SIGTERM); rtp->running = 0; continue; } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } writeErrmsgMemos(); writeMemo("[i] pmqlsi receiver thread has ended."); return NULL; } /* * * Main thread functions * * * */ #if defined (VXWORKS) || defined (RTEMS) int pmqlsi(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { char *mqName = (char *) a1; #else int main(int argc, char *argv[]) { char *mqName = (argc > 1 ? argv[1] : NULL); #endif LtpVdb *vdb; struct mq_attr mqAttributes = { 0, PMQLSA_MAXMSG, PMQLSA_MSGSIZE, 0 }; ReceiverThreadParms rtp; pthread_t receiverThread; char stop = '0'; if (mqName == NULL) { puts("Usage: pmqlsi "); return 0; } /* Note that ltpadmin must be run before the first * invocation of ltplsi, to initialize the LTP database * (as necessary) and dynamic database. */ if (ltpInit(0) < 0) { putErrmsg("pmqlsi can't initialize LTP.", NULL); return 1; } vdb = getLtpVdb(); if (vdb->lsiPid > 0 && vdb->lsiPid != sm_TaskIdSelf()) { putErrmsg("LSI task is already started.", itoa(vdb->lsiPid)); return 1; } /* All command-line arguments are now validated. */ rtp.mq = mq_open(mqName, O_RDWR | O_CREAT, 0777, &mqAttributes); if (rtp.mq == (mqd_t) -1) { putSysErrmsg("pmglsi can't open message queue", mqName); return 1; } /* Set up signal handling; SIGTERM is shutdown signal. */ isignal(SIGTERM, interruptThread); /* Start the receiver thread. */ rtp.running = 1; rtp.mainThread = pthread_self(); if (pthread_create(&receiverThread, NULL, handleMessages, &rtp)) { mq_close(rtp.mq); putSysErrmsg("pmqlsi can't create receiver thread", NULL); return 1; } /* Now sleep until interrupted by SIGTERM, at which point * it's time to stop the link service. */ writeMemo("[i] pmqlsi is running"); snooze(2000000000); /* Time to shut down. */ rtp.running = 0; mq_send(rtp.mq, &stop, 1, 0); /* Tell receiver to stop. */ pthread_join(receiverThread, NULL); mq_close(rtp.mq); writeErrmsgMemos(); writeMemo("[i] pmqlsi duct has ended."); return 0; } ion-3.2.0~dfsg1.orig/arch-rtems/ionrtems.c0000644000175000017500000002476612260400055016755 0ustar l3onl3on/* * ION runtime image initialization and driver. */ #include #include #include #include #include #include "platform.h" #include "ion.h" #include "rfx.h" #include "ltp.h" #include "bp.h" #ifndef NASA_PROTECTED_FLIGHT_CODE #include "cfdp.h" #endif #define ION_NODE_NBR 19 static void createIonConfigFiles() { uvast nodenbr = ION_NODE_NBR; char filenamebuf[80]; int fd; char *ionconfigLines[] = { "wmSize 300000\n", "configFlags 1\n", "heapWords 75000\n", "pathName /ion\n", }; int ionconfigLineCount = sizeof ionconfigLines / sizeof (char *); char *globalLines[] = { "a contact +0 +7200 19 19 100000\n" }; int globalLineCount = sizeof globalLines / sizeof (char *); char *ionsecrcLines[] = { "1\n", "a bspbabrule ipn:19.* ipn:19.* '' ''\n" }; int ionsecrcLineCount = sizeof ionsecrcLines / sizeof (char *); char *ltprcLines[] = { "1 20 64000\n", "a span 19 4 4000 4 4000 1084 2048 1 'pmqlso /ionpmq.19'\n", "w 1\n", "s 'pmqlsi /ionpmq.19'\n" }; int ltprcLineCount = sizeof ltprcLines / sizeof (char *); char *bprcLines[] = { "1\n", "a scheme ipn 'ipnfw' 'ipnadminep'\n", "a endpoint ipn:19.0 x\n", "a endpoint ipn:19.1 x\n", "a endpoint ipn:19.2 x\n", "a endpoint ipn:19.64 x\n", "a endpoint ipn:19.65 x\n", "a endpoint ipn:19.126 x\n", "a endpoint ipn:19.127 x\n", "a protocol ltp 1400 100\n", "a induct ltp 19 ltpcli\n", "a outduct ltp 19 ltpclo\n", "w 1\n" }; int bprcLineCount = sizeof bprcLines / sizeof (char *); char *ipnrcLines[] = { "a plan 19 ltp/19\n" }; int ipnrcLineCount = sizeof ipnrcLines / sizeof (char *); char linebuf[255]; char **line; int i; /* Keep all ION configuration files in one directory. */ if (mkdir("/ion", 0777) < 0) { perror("Can't create directory for config files"); return; } /* Create ionconfig file. */ isprintf(filenamebuf, sizeof filenamebuf, "/ion/node" UVAST_FIELDSPEC ".ionconfig", nodenbr); fd = iopen(filenamebuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { printf("Can't create .ionconfig file '%s'.\n", filenamebuf); return; } for (i = 0, line = ionconfigLines; i < ionconfigLineCount; line++, i++) { oK(iputs(fd, *line)); } close(fd); /* Create ionrc file. */ isprintf(filenamebuf, sizeof filenamebuf, "/ion/node" UVAST_FIELDSPEC ".ionrc", nodenbr); fd = iopen(filenamebuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { printf("Can't create .ionrc file '%s'.\n", filenamebuf); return; } isprintf(linebuf, sizeof linebuf, "1 " UVAST_FIELDSPEC " /ion/node" UVAST_FIELDSPEC ".ionconfig\ns\n", nodenbr, nodenbr); oK(iputs(fd, linebuf)); close(fd); /* Create global.ionrc file. */ istrcpy(filenamebuf, "/ion/global.ionrc", sizeof filenamebuf); fd = iopen(filenamebuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { printf("Can't create global.ionrc file '%s'.\n", filenamebuf); return; } for (i = 0, line = globalLines; i < globalLineCount; line++, i++) { oK(iputs(fd, *line)); } close(fd); /* Create ionsecrc file. */ isprintf(filenamebuf, sizeof filenamebuf, "/ion/node" UVAST_FIELDSPEC ".ionsecrc", nodenbr); fd = iopen(filenamebuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { printf("Can't create .ionsecrc file '%s'.\n", filenamebuf); return; } for (i = 0, line = ionsecrcLines; i < ionsecrcLineCount; line++, i++) { oK(iputs(fd, *line)); } close(fd); /* Create ltprc file. */ isprintf(filenamebuf, sizeof filenamebuf, "/ion/node" UVAST_FIELDSPEC ".ltprc", nodenbr); fd = iopen(filenamebuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { printf("Can't create .ltprc file '%s'.\n", filenamebuf); return; } for (i = 0, line = ltprcLines; i < ltprcLineCount; line++, i++) { oK(iputs(fd, *line)); } close(fd); /* Create ipnrc file. */ isprintf(filenamebuf, sizeof filenamebuf, "/ion/node" UVAST_FIELDSPEC ".ipnrc", nodenbr); fd = iopen(filenamebuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { printf("Can't create .ipnrc file '%s'.\n", filenamebuf); return; } for (i = 0, line = ipnrcLines; i < ipnrcLineCount; line++, i++) { oK(iputs(fd, *line)); } close(fd); /* Create bprc file. */ isprintf(filenamebuf, sizeof filenamebuf, "/ion/node" UVAST_FIELDSPEC ".bprc", nodenbr); fd = iopen(filenamebuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { printf("Can't create .bprc file '%s'.\n", filenamebuf); return; } for (i = 0, line = bprcLines; i < bprcLineCount; line++, i++) { oK(iputs(fd, *line)); } isprintf(linebuf, sizeof linebuf, "r 'ipnadmin /ion/node" UVAST_FIELDSPEC ".ipnrc'\ns\n", nodenbr); oK(iputs(fd, linebuf)); close(fd); #ifndef NASA_PROTECTED_FLIGHT_CODE /* Create cfdprc file. */ isprintf(filenamebuf, sizeof filenamebuf, "/ion/node" UVAST_FIELDSPEC ".cfdprc", nodenbr); fd = iopen(filenamebuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { printf("Can't create .cfdprc file '%s'.\n", filenamebuf); return; } oK(iputs(fd, "1\ns bputa\n")); close(fd); #endif } static int startDTN() { uvast nodenbr = ION_NODE_NBR; char cmd[80]; int count; sm_ipc_init(); isprintf(cmd, sizeof cmd, "ionadmin /ion/node" UVAST_FIELDSPEC ".ionrc", nodenbr); pseudoshell(cmd); count = 5; while (rfx_system_is_started() == 0) { snooze(1); count--; if (count == 0) { writeMemo("[?] RFX start hung up, abandoned."); return -1; } } pseudoshell("ionadmin /ion/global.ionrc"); snooze(1); isprintf(cmd, sizeof cmd, "ionsecadmin /ion/node" UVAST_FIELDSPEC ".ionsecrc", nodenbr); pseudoshell(cmd); snooze(1); /* Now start the higher layers of the DTN stack. */ isprintf(cmd, sizeof cmd, "ltpadmin /ion/node" UVAST_FIELDSPEC ".ltprc", nodenbr); pseudoshell(cmd); count = 5; while (ltp_engine_is_started() == 0) { snooze(1); count--; if (count == 0) { writeMemo("[?] LTP start hung up, abandoned."); return -1; } } isprintf(cmd, sizeof cmd, "bpadmin /ion/node" UVAST_FIELDSPEC ".bprc", nodenbr); pseudoshell(cmd); count = 5; while (bp_agent_is_started() == 0) { snooze(1); count--; if (count == 0) { writeMemo("[?] BP start hung up, abandoned."); return -1; } } isprintf(cmd, sizeof cmd, "lgagent ipn:" UVAST_FIELDSPEC ".127", nodenbr); pseudoshell(cmd); snooze(1); #ifndef NASA_PROTECTED_FLIGHT_CODE /* Now start CFDP. */ isprintf(cmd, sizeof cmd, "cfdpadmin /ion/node" UVAST_FIELDSPEC ".cfdprc", nodenbr); pseudoshell(cmd); count = 5; while (cfdp_entity_is_started() == 0) { snooze(1); count--; if (count == 0) { writeMemo("[?] CFDP start hung up, abandoned."); return -1; } } #endif return 0; } static void testLoopback() { char cmd[80]; puts("Starting loopback test."); isprintf(cmd, sizeof cmd, "bpsink ipn:" UVAST_FIELDSPEC ".1", ION_NODE_NBR); pseudoshell(cmd); snooze(1); isprintf(cmd, sizeof cmd, "bpsource ipn:" UVAST_FIELDSPEC ".1 'Hello, world.'", ION_NODE_NBR); pseudoshell(cmd); snooze(1); puts("Loopback test ended."); } static int stopDTN(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { #ifndef NASA_PROTECTED_FLIGHT_CODE /* Stop CFDP. */ pseudoshell("cfdpadmin ."); while (cfdp_entity_is_started()) { snooze(1); } #endif /* Stop BP. */ pseudoshell("bpadmin ."); while (bp_agent_is_started()) { snooze(1); } /* Stop LTP. */ pseudoshell("ltpadmin ."); while (ltp_engine_is_started()) { snooze(1); } /* Stop rfxclock. */ pseudoshell("ionadmin ."); while (rfx_system_is_started()) { snooze(1); } /* Erase all ION data in DRAM. */ ionTerminate(); return 0; } rtems_task Init(rtems_task_argument ignored) { puts("Inside Init(), creating configuration files."); createIonConfigFiles(); puts("Inside Init(), spawning ION startup tasks."); if (startDTN() < 0) { writeMemo("[?] Can't start ION."); } testLoopback(); snooze(1); puts("Stopping ION."); oK(stopDTN(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); puts("ION stopped."); exit(0); } void inferUtcDelta(char *correctUtcTimeStamp) { IonVdb *ionvdb = getIonVdb(); time_t correctUtcTime = readTimestampUTC(correctUtcTimeStamp, 0); time_t clocktime = getUTCTime() + ionvdb->deltaFromUTC; int delta = clocktime - correctUtcTime; char buffer[80]; CHKVOID(setDeltaFromUTC(delta) == 0); sprintf(buffer, "[i] Delta from UTC revised, is now %d.", delta); writeMemo(buffer); } void showUtcDelta() { IonVdb *ionvdb = getIonVdb(); char buffer[80]; sprintf(buffer, "[i] Delta from UTC is %d.", ionvdb->deltaFromUTC); writeMemo(buffer); } /* * * RTEMS configuration * * * */ #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER #define CONFIGURE_RTEMS_INIT_TASKS_TABLE #define CONFIGURE_MAXIMUM_SEMAPHORES 20 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 10 #define CONFIGURE_MAXIMUM_TASKS 40 #ifndef CONFIGURE_MICROSECONDS_PER_TICK #define CONFIGURE_MICROSECONDS_PER_TICK 10000 #endif #ifndef CONFIGURE_TICKS_PER_TIMESLICE #define CONFIGURE_TICKS_PER_TIMESLICE 10 #endif #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 40 #define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM #define CONFIGURE_MAXIMUM_POSIX_THREADS 40 #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 10 #define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 10 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 100 #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 10 #define CONFIGURE_STACK_CHECKER_ON #define CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY TRUE #define CONFIGURE_DISABLE_CLASSIC_NOTEPADS #define CONFIGURE_INIT #undef Object #include /* Loopback Network Configuration needed to prevent linking with dummy.o */ extern int rtems_bsdnet_loopattach(struct rtems_bsdnet_ifconfig *, int); static struct rtems_bsdnet_ifconfig loopback_config = { "lo0", /* name */ rtems_bsdnet_loopattach, /* attach function */ NULL, /* link to next interface */ "127.0.0.1", /* IP address */ "255.0.0.0", /* IP net mask */ }; struct rtems_bsdnet_config rtems_bsdnet_config = { &loopback_config, /* Network interface */ NULL, /* Use fixed network configuration */ 0, /* Default network task priority */ 0, /* Default mbuf capacity */ 0, /* Default mbuf cluster capacity */ "127.0.0.1", /* Host name */ "localdomain", /* Domain name */ "127.0.0.1", /* Gateway */ "127.0.0.1", /* Log host */ {"127.0.0.1" }, /* Name server(s) */ {"127.0.0.1" }, /* NTP server(s) */ 2, /* sb_efficiency */ 8192, /* udp_tx_buf_size */ 8192, /* udp_rx_buf_size */ 8192, /* tcp_tx_buf_size */ 8192 /* tcp_rx_buf_size */ }; ion-3.2.0~dfsg1.orig/arch-rtems/srclinks0000755000175000017500000000721412260400055016514 0ustar l3onl3on# shell script to populate RTEMS build directory with sym links to source files. #!/bin/bash ION_OPEN_SOURCE=1 CRYPTO=NULL_SUITES ln -s ../ici/library/platform.c ln -s ../ici/library/platform_sm.c ln -s ../ici/library/memmgr.c ln -s ../ici/library/llcv.c ln -s ../ici/library/lyst.c ln -s ../ici/library/lystP.h ln -s ../ici/library/psm.c ln -s ../ici/library/smlist.c ln -s ../ici/library/smrbt.c ln -s ../ici/library/ion.c ln -s ../ici/library/ionsec.c ln -s ../ici/library/rfx.c ln -s ../ici/library/zco.c ln -s ../ici/sdr/sdrtable.c ln -s ../ici/sdr/sdrhash.c ln -s ../ici/sdr/sdrxn.c ln -s ../ici/sdr/sdrP.h ln -s ../ici/sdr/sdrmgt.c ln -s ../ici/sdr/sdrstring.c ln -s ../ici/sdr/sdrlist.c ln -s ../ici/sdr/sdrcatlg.c ln -s ../ici/daemon/rfxclock.c ln -s ../ici/utils/ionadmin.c ln -s ../ici/utils/ionsecadmin.c ln -s ../ici/utils/sdrmend.c ln -s ../ici/utils/ionexit.c ln -s ../ici/utils/ionwarn.c ln -s ../bp/library/libbp.c ln -s ../bp/library/libbpP.c ln -s ../bp/library/bpP.h ln -s ../bp/library/cgr.h ln -s ../bp/library/bei.c ln -s ../bp/library/bei.h ln -s ../bp/library/ext/bpextensions.c ln -s ../bp/library/ext/ecos/ecos.c ln -s ../bp/library/ext/ecos/ecos.h ln -s ../bp/library/ext/bae/bae.c ln -s ../bp/library/ext/bae/bae.h ln -s ../bp/library/ext/bsp/extbspbab.c ln -s ../bp/library/ext/bsp/extbspbab.h ln -s ../bp/library/ext/bsp/extbsppib.c ln -s ../bp/library/ext/bsp/extbsppib.h ln -s ../bp/library/ext/bsp/extbsppcb.c ln -s ../bp/library/ext/bsp/extbsppcb.h ln -s ../bp/library/ext/bsp/extbsputil.c ln -s ../bp/library/ext/bsp/extbsputil.h ln -s ../bp/library/crypto/crypto.h ln -s ../bp/library/crypto/sample_crypto.h ln -s ../bp/library/crypto/$CRYPTO/crypto.c ln -s ../bp/daemon/bpclock.c ln -s ../bp/utils/bpadmin.c ln -s ../bp/utils/bpstats.c ln -s ../bp/utils/bptrace.c ln -s ../bp/utils/bplist.c ln -s ../bp/utils/lgagent.c ln -s ../bp/test/bpsource.c ln -s ../bp/test/bpsink.c ln -s ../bp/ipn/ipnadmin.c ln -s ../bp/ipn/libipnfw.c ln -s ../bp/ipn/ipnfw.c ln -s ../bp/ipn/ipnfw.h ln -s ../bp/dtn2/libdtn2fw.c ln -s ../bp/dtn2/dtn2fw.h ln -s ../bp/ipn/ipnadminep.c ln -s ../bp/cgr/libcgr.c ln -s ../bp/ltp/ltpcli.c ln -s ../bp/ltp/ltpclo.c ln -s ../bp/ltp/ltpcla.h ln -s ../ltp/library/libltp.c ln -s ../ltp/library/libltpP.c ln -s ../ltp/library/ltpP.h ln -s ../ltp/daemon/ltpclock.c ln -s ../ltp/daemon/ltpmeter.c ln -s ../ltp/utils/ltpadmin.c ln -s ../restart/utils/ionrestart.c if [ "$ION_OPEN_SOURCE" == "1" ];then ln -s ../cfdp/library/libcfdp.c ln -s ../cfdp/library/libcfdpops.c ln -s ../cfdp/library/libcfdpP.c ln -s ../cfdp/library/cfdpP.h ln -s ../cfdp/bp/bputa.c ln -s ../cfdp/daemon/cfdpclock.c ln -s ../cfdp/utils/cfdpadmin.c fi # Optional features: multicast, aggregate custody signaling, previous-hop node # # ln -s ../bp/imc/imcadmin.c # ln -s ../bp/imc/libimcfw.c # ln -s ../bp/imc/imcfw.c # ln -s ../bp/imc/imcfw.h # ln -s ../bp/imc/imcP.h # # ln -s ../bp/library/acs/acsappend.c # ln -s ../bp/library/acs/acsid.c # ln -s ../bp/library/acs/acstx.c # ln -s ../bp/library/acs/acsrx.c # ln -s ../bp/library/acs/acsserialize.c # ln -s ../bp/library/acs/acs.h # ln -s ../bp/library/acs/acsP.h # ln -s ../bp/utils/acsadmin.c # ln -s ../bp/utils/acslist.c # ln -s ../bp/library/ext/cteb/cteb.c # ln -s ../bp/library/ext/cteb/cteb.h # # ln -s ../bp/library/ext/phn/phn.c # ln -s ../bp/library/ext/phn/phn.h # Optional extra stuff for testing. # # ln -s ../ici/library/sptrace.c # ln -s ../bp/utils/bpstats2.c # ln -s ../bp/utils/bping.c # ln -s ../bp/utils/bpchat.c # ln -s ../bp/test/bpdriver.c # ln -s ../bp/test/bpecho.c # ln -s ../bp/test/bpcounter.c # ln -s ../bp/test/bpsource.c # ln -s ../bp/test/bpsink.c # ln -s ../bp/utils/bpsendfile.c # ln -s ../bp/utils/bprecvfile.c ion-3.2.0~dfsg1.orig/arch-rtems/mysymtab.c0000644000175000017500000001110212260400055016736 0ustar l3onl3on/* mysymtab.c: template private symbol table for RTEMS port of the ION stack, with definition of sm_FindFunction(), which accesses this table. Author: Scott Burleigh, JPL Copyright (c) 2010, California Institute of Technology. ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. */ extern int ionadmin(int, int, int, int, int, int, int, int, int, int); extern int ionexit(int, int, int, int, int, int, int, int, int, int); extern int rfxclock(int, int, int, int, int, int, int, int, int, int); extern int ionsecadmin(int, int, int, int, int, int, int, int, int, int); extern int ionwarn(int, int, int, int, int, int, int, int, int, int); extern int ionrestart(int, int, int, int, int, int, int, int, int, int); extern int ltpadmin(int, int, int, int, int, int, int, int, int, int); extern int ltpclock(int, int, int, int, int, int, int, int, int, int); extern int ltpmeter(int, int, int, int, int, int, int, int, int, int); extern int pmqlsi(int, int, int, int, int, int, int, int, int, int); extern int pmqlso(int, int, int, int, int, int, int, int, int, int); extern int bpadmin(int, int, int, int, int, int, int, int, int, int); extern int bpclock(int, int, int, int, int, int, int, int, int, int); extern int ltpcli(int, int, int, int, int, int, int, int, int, int); extern int ltpclo(int, int, int, int, int, int, int, int, int, int); extern int ipnadmin(int, int, int, int, int, int, int, int, int, int); extern int ipnfw(int, int, int, int, int, int, int, int, int, int); extern int ipnadminep(int, int, int, int, int, int, int, int, int, int); extern int lgagent(int, int, int, int, int, int, int, int, int, int); extern int bpsource(int, int, int, int, int, int, int, int, int, int); extern int bpsink(int, int, int, int, int, int, int, int, int, int); #ifndef NASA_PROTECTED_FLIGHT_CODE extern int cfdpadmin(int, int, int, int, int, int, int, int, int, int); extern int cfdpclock(int, int, int, int, int, int, int, int, int, int); extern int bputa(int, int, int, int, int, int, int, int, int, int); #endif #if 0 extern int imcadmin(int, int, int, int, int, int, int, int, int, int); extern int imcfw(int, int, int, int, int, int, int, int, int, int); extern int acsadmin(int, int, int, int, int, int, int, int, int, int); extern int acslist(int, int, int, int, int, int, int, int, int, int); #endif typedef struct { char *name; FUNCPTR funcPtr; int priority; int stackSize; } SymTabEntry; FUNCPTR sm_FindFunction(char *name, int *priority, int *stackSize) { static SymTabEntry symbols[] = { { "ionadmin", (FUNCPTR) ionadmin, ICI_PRIORITY, 32768 }, { "ionexit", (FUNCPTR) ionexit, ICI_PRIORITY, 32768 }, { "rfxclock", (FUNCPTR) rfxclock, ICI_PRIORITY, 32768 }, { "ionsecadmin",(FUNCPTR) ionsecadmin, ICI_PRIORITY, 32768 }, { "ionwarn", (FUNCPTR) ionwarn, ICI_PRIORITY, 32768 }, { "ionrestart", (FUNCPTR) ionrestart, ICI_PRIORITY, 32768 }, { "ltpadmin", (FUNCPTR) ltpadmin, ICI_PRIORITY, 32768 }, { "ltpclock", (FUNCPTR) ltpclock, ICI_PRIORITY, 32768 }, { "ltpmeter", (FUNCPTR) ltpmeter, ICI_PRIORITY, 32768 }, { "pmqlsi", (FUNCPTR) pmqlsi, ICI_PRIORITY, 32768 }, { "pmqlso", (FUNCPTR) pmqlso, ICI_PRIORITY, 32768 }, { "bpadmin", (FUNCPTR) bpadmin, ICI_PRIORITY, 32768 }, { "bpclock", (FUNCPTR) bpclock, ICI_PRIORITY, 4096 }, { "ltpcli", (FUNCPTR) ltpcli, ICI_PRIORITY, 32768 }, { "ltpclo", (FUNCPTR) ltpclo, ICI_PRIORITY, 32768 }, { "ipnadmin", (FUNCPTR) ipnadmin, ICI_PRIORITY, 32768 }, { "ipnfw", (FUNCPTR) ipnfw, ICI_PRIORITY, 65536 }, { "ipnadminep", (FUNCPTR) ipnadminep, ICI_PRIORITY, 24576 }, { "lgagent", (FUNCPTR) lgagent, ICI_PRIORITY, 24576 }, { "bpsource", (FUNCPTR) bpsource, ICI_PRIORITY, 4096 }, { "bpsink", (FUNCPTR) bpsink, ICI_PRIORITY, 4096 } #ifndef NASA_PROTECTED_FLIGHT_CODE ,{ "cfdpadmin", (FUNCPTR) cfdpadmin, ICI_PRIORITY, 24576 }, { "cfdpclock", (FUNCPTR) cfdpclock, ICI_PRIORITY, 24576 }, { "bputa", (FUNCPTR) bputa, ICI_PRIORITY, 24576 } #endif #if 0 ,{ "imcadmin", (FUNCPTR) imcadmin, ICI_PRIORITY, 32768 }, { "imcfw", (FUNCPTR) imcfw, ICI_PRIORITY, 65536 } ,{ "acsadmin", (FUNCPTR) acsadmin, ICI_PRIORITY, 32768 }, { "acslist", (FUNCPTR) acslist, ICI_PRIORITY, 32768 } #endif }; static int numSymbols = sizeof symbols / sizeof(SymTabEntry); int i; CHKNULL(name); CHKNULL(priority); CHKNULL(stackSize); for (i = 0; i < numSymbols; i++) { if (strcmp(name, symbols[i].name) == 0) { if (*priority == 0) /* Use default. */ { *priority = symbols[i].priority; } if (*stackSize == 0) /* Use default. */ { *stackSize = symbols[i].stackSize; } return symbols[i].funcPtr; } } return NULL; } ion-3.2.0~dfsg1.orig/arch-rtems/gdslogger.c0000644000175000017500000000051312260400055017052 0ustar l3onl3onstatic void writeMemoToStdout(char *text) { time_t currentTime = getUTCTime(); char timestampBuffer[20]; char msgbuf[256]; writeTimestampLocal(currentTime, timestampBuffer); isprintf(msgbuf, sizeof msgbuf, "[%s] %s", timestampBuffer, text); puts(msgbuf); } static void ionRedirectMemos() { setLogger(writeMemoToStdout); } ion-3.2.0~dfsg1.orig/arch-rtems/Makefile0000755000175000017500000000531112260400055016375 0ustar l3onl3onIONFLAGS_T = -DRTEMS -DBP_EXTENDED -DGDSSYMTAB -DGDSLOGGER \ -DUSING_SDR_POINTERS -DION_NO_DNS -DNO_SDR_TRACE -DNO_PSM_TRACE \ -DNO_PROXY -DNO_DIRLIST # -DENABLE_IMC -DENABLE_BPACS PGM=${ARCH}/ion.exe ION_OPEN_SOURCE = 1 # optional managers required MANAGERS = io semaphore ICISOURCES = \ platform.c \ platform_sm.c \ memmgr.c \ llcv.c \ lyst.c \ psm.c \ smlist.c \ smrbt.c \ ion.c \ rfx.c \ zco.c \ sdrtable.c \ sdrhash.c \ sdrxn.c \ sdrmgt.c \ sdrstring.c \ sdrlist.c \ sdrcatlg.c \ rfxclock.c \ ionadmin.c \ sdrmend.c \ ionsec.c \ ionsecadmin.c \ ionwarn.c \ ionrestart.c \ ionexit.c LTPSOURCES = \ libltp.c \ libltpP.c \ ltpclock.c \ ltpmeter.c \ pmqlsi.c \ pmqlso.c \ ltpadmin.c BPSOURCES = \ libbp.c \ libbpP.c \ bpclock.c \ bpadmin.c \ bpstats.c \ bptrace.c \ bplist.c \ lgagent.c \ ipnadmin.c \ ipnfw.c \ libcgr.c \ ipnadminep.c \ libipnfw.c \ ltpcli.c \ ltpclo.c \ bei.c \ ecos.c \ bae.c # imcadmin.c \ # imcfw.c \ # libimcfw.c \ # cteb.c \ # acsappend.c \ # acsid.c \ # acstx.c \ # acsrx.c \ # acsserialize.c \ # acsadmin.c \ # acslist.c \ # phn.c \ BSPSOURCES = \ extbsputil.c \ extbspbab.c \ extbsppib.c \ extbsppcb.c \ crypto.c DTN2SOURCES = \ libdtn2fw.c CFDPSOURCES = \ bputa.c \ cfdpclock.c \ cfdpadmin.c \ libcfdp.c \ libcfdpP.c \ libcfdpops.c TESTSOURCES = \ bpsource.c \ bpsink.c # sptrace.c \ # bpstats2.c \ # bping.c \ # bpchat.c \ # bpcounter.c \ # bpdriver.c \ # bpecho.c \ # bpsendfile.c \ # bprecvfile.c CSRCS_I = ionrtems.c $(ICISOURCES) $(LTPSOURCES) $(BPSOURCES) $(BSPSOURCES) $(DTN2SOURCES) $(PXSOURCES) $(TESTSOURCES) ifeq "$(ION_OPEN_SOURCE)" "1" CSRCS = $(CSRCS_I) $(CFDPSOURCES) IONFLAGS = $(IONFLAGS_T) else CSRCS = $(CSRCS_I) IONFLAGS = $(IONFLAGS_T) -DNASA_PROTECTED_FLIGHT_CODE endif COBJS = $(CSRCS:%.c=${ARCH}/%.o) include $(RTEMS_MAKEFILE_PATH)/Makefile.inc include $(RTEMS_CUSTOM) include $(PROJECT_ROOT)/make/leaf.cfg OBJS = $(COBJS) $(CXXOBJS) $(ASOBJS) INCLUDES_T= -I. -I../ici/include -I../dgr/include -I../ltp/include -I../bp/include ifeq "$(ION_OPEN_SOURCE)" "1" INCLUDES = $(INCLUDES_T) -I../cfdp/include -I../ams/include else INCLUDES = $(INCLUDES_T) endif #CFLAGS = -g -Wall -Werror $(IONFLAGS) $(INCLUDES) -O2 CFLAGS = -g -Wall -Werror $(IONFLAGS) $(INCLUDES) all: ${ARCH} $(PGM) $(PGM): $(OBJS) $(make-exe) clean: rm -f $(COBJS) $(PGM) ion-3.2.0~dfsg1.orig/arch-rtems/pmqlsa.h0000644000175000017500000000072112260400055016400 0ustar l3onl3on/* pmqlsa.h: common definitions for PMQ link service adapter modules. Author: Scott Burleigh, JPL Copyright (c) 2010, California Institute of Technology. ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. */ #ifndef _PMQLSA_H_ #define _PMQLSA_H_ #include "ltpP.h" #include #ifdef __cplusplus extern "C" { #endif #define PMQLSA_MSGSIZE 1024 #define PMQLSA_MAXMSG 2 #ifdef __cplusplus } #endif #endif /* _PMQLSA_H */ ion-3.2.0~dfsg1.orig/arch-rtems/README0000644000175000017500000000743412260400055015622 0ustar l3onl3onThe RTEMS port of ION in this directory is just a demo template from which real RTEMS ION-based systems can be cloned and adapted. To develop an RTEMS ION-based system modeled on this template you will want to modify the RTEMS linkcmds file to reflect the actual memory resources provided, modify ionrtems.c considerably (or develop an entirely new Init module that does the same general things; in particular, upgrade the RTEMS configuration definitions as needed), develop new software that uses ION for communications, modify the Makefile accordingly (possibly adding to the list of MANAGERS), etc. A step-by-step procedure for demo'ing ION on RTEMS follows. First construct the RTEMS development environment: 1. Use the Yum Instructions at http://www.rtems.com/wiki/index.php/APT/Yum_Repository to download and install the pre-built RTEMS development tools. Install the appropriate rpm, then use yum install to install the tools. The ION RTEMS port was done on a 32-bit Fedora 10 host system using rtems branch 4.9.3, selecting the SPARC "sis" simulator as the target system; this is similar to the approach taken in the Quick Start example at http://www.rtems.com/wiki/index.php/Quick_Start For the balance of this README, SPARC "sis" for RTEMS 4.9.3 will be assumed; substitute other version, system, or bsp as appropriate. 2. Make development directories: $(HOME)/rtems $(HOME)/rtems/archive $(HOME)/rtems/tools $(HOME)/rtems/tools/build 3. Use the links in the Getting Started manual from the appropriate online documentation library (http://www.rtems.com/onlinedocs/releases) to download the RTEMS source code and the examples into $(HOME)/rtems/archive. 4. Continue following the instructions in the on-line manual for installing the operating system. This entails adding export PATH=/opt/rtems-4.9/bin:${PATH} to ~/.bash_profile before doing anything. Test the tools as shown in section 5.4 of the online manual. Then, in rtems/tools/build, enter the following commands to build RTEMS: ../rtems-4.9.3/configure --target=sparc-rtems4.9 --enable-rtemsbsp=sis --prefix=/opt/rtems-4.9/ make all install 5. Test the RTEMS development environment. First add export RTEMS_MAKEFILE_PATH=/opt/rtems-4.9/sparc-rtems4.9/sis to ~/.bash_profile (and be sure (!) to source ~/.bash_profile in any window in which you plan to build any RTEMS application). Then unpack the sample applications and build hello_world_c described in 6.3 of the online manual. The compiled application can be run from the Linux command line by entering sparc-rtems4.9-run `find . -name hello.exe` Alternatively, to run and debug the application within gdb, enter sparc-rtems4.9-gdb `find . -name hello.exe` and enter the following commands at the gdb prompt: tar sim load r 6. Now build and run the ION RTEMS demo application. First cd into ion/arch-rtems and enter the following commands to populate the directory with symbolic links to the ION C source files and build the ion.exe executable: ./srclinks make Then use the following command to run the demo. sparc-rtems4.9-run `find . -name ion.exe` The ION daemons will start running and a test execution of bpsource will send a loopback bundle via LTP to bpsink, which will print the text in the bundle payload. The ION RTEMS Makefile is configured to optimize the resulting executable. To see the actual size of the executable (with the debugging information inserted by the compiler removed): $ cd o-optimize $ cp ion.exe stripped.ion.exe $ sparc-rtems4.9-strip stripped.ion.exe $ ls -l stripped.ion.exe $ sparc-rtems4.9-size stripped.ion.exe Optimization can make source-level debugging more difficult, because key variables may be held in registers rather than in memory. To disable optimization, remove the "-O2" parameter from the CFLAGS variable in the Makefile and rebuild. ion-3.2.0~dfsg1.orig/arch-rtems/pmqlso.c0000644000175000017500000000715012260400055016414 0ustar l3onl3on/* pmqlso.c: LTP PMQ-based link service output daemon. Transmits LTP segments via a POSIX message queue. Author: Scott Burleigh, JPL Copyright (c) 2010, California Institute of Technology. ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. */ #include "pmqlsa.h" static sm_SemId _pmqlsoSemaphore(sm_SemId *semptr) { long temp; void *value; sm_SemId sem; if (semptr) /* Add task variable. */ { temp = *semptr; value = (void *) temp; sem = (sm_SemId) sm_TaskVar(&value); } else /* Retrieve task variable. */ { sem = (sm_SemId) sm_TaskVar(NULL); } return sem; } static void interruptThread() /* Shuts down LSO. */ { void *erase = NULL; sm_SemEnd(_pmqlsoSemaphore(NULL)); oK(sm_TaskVar(&erase)); } int sendSegmentByPMQ(mqd_t mq, char *from, int length) { int result; while (1) /* Continue until not interrupted. */ { result = mq_send(mq, from, length, 0); if (result < 0) { if (errno == EINTR) /* Interrupted. */ { continue; /* Retry. */ } } return result; } } /* * * Main thread functions * * * */ #if defined (VXWORKS) || defined (RTEMS) int pmqlso(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { char *mqName = (char *) a1; uvast remoteEngineId = a2 != 0 ? strtouvast((char *) a2) : 0; #else int main(int argc, char *argv[]) { char *mqName = argc > 1 ? argv[1] : NULL; uvast remoteEngineId = argc > 2 ? strtouvast(argv[2]) : 0; #endif Sdr sdr; LtpVspan *vspan; PsmAddress vspanElt; struct mq_attr mqAttributes = { 0, PMQLSA_MAXMSG, PMQLSA_MSGSIZE, 0 }; mqd_t mq; int running; int segmentLength; char *segment; if (remoteEngineId == 0 || mqName == NULL) { puts("Usage: pmqlso "); return 0; } /* Note that ltpadmin must be run before the first * invocation of ltplso, to initialize the LTP database * (as necessary) and dynamic database. */ if (ltpInit(0) < 0) { putErrmsg("pmqlso can't initialize LTP.", NULL); return 1; } sdr = getIonsdr(); CHKERR(sdr_begin_xn(sdr)); /* Just to lock memory. */ findSpan(remoteEngineId, &vspan, &vspanElt); if (vspanElt == 0) { sdr_exit_xn(sdr); putErrmsg("No such engine in database.", itoa(remoteEngineId)); return 1; } if (vspan->lsoPid > 0 && vspan->lsoPid != sm_TaskIdSelf()) { sdr_exit_xn(sdr); putErrmsg("LSO task is already started for this span.", itoa(vspan->lsoPid)); return 1; } /* All command-line arguments are now validated. */ sdr_exit_xn(sdr); mq = mq_open(mqName, O_RDWR | O_CREAT, 0777, &mqAttributes); if (mq == (mqd_t) -1) { putSysErrmsg("pmqlso can't open message queue", mqName); return 1; } oK(_pmqlsoSemaphore(&vspan->segSemaphore)); isignal(SIGTERM, interruptThread); /* Can now begin transmitting to remote engine. */ writeMemo("[i] pmqlso is running."); running = 1; while (running && !(sm_SemEnded(_pmqlsoSemaphore(NULL)))) { segmentLength = ltpDequeueOutboundSegment(vspan, &segment); if (segmentLength < 0) { running = 0; /* Terminate LSO. */ continue; } if (segmentLength == 0) /* Interrupted. */ { continue; } if (segmentLength > PMQLSA_MSGSIZE) { putErrmsg("Segment is too big for PMQ LSO.", itoa(segmentLength)); running = 0; /* Terminate LSO. */ continue; } if (sendSegmentByPMQ(mq, segment, segmentLength) < 0) { putSysErrmsg("pmqlso failed sending segment", mqName); running = 0; /* Terminate LSO. */ continue; } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } mq_close(mq); writeErrmsgMemos(); writeMemo("[i] pmqlso duct has ended."); return 0; } ion-3.2.0~dfsg1.orig/configure.ac0000644000175000017500000002616312260400056015164 0ustar l3onl3on# configure.ac for ION # Samuel Jero # June 14, 2013 # Process this file with autoconf to produce a configure script. AC_PREREQ(2.60) AC_INIT(ion, open source 3.2.0, http://korgano.eecs.ohiou.edu/mailman/listinfo/ion-bugs) IS_NASA_B=0 # Josh Schendel removed the -Werror on 05/15/2012 per issue #355 to deal with # all of the portability warnings introduced by autoconf v2.69 and # automake v1.12. #AM_INIT_AUTOMAKE([subdir-objects -Wall -Werror foreign]) AM_INIT_AUTOMAKE([subdir-objects -Wall foreign]) # some source file that will ensure that you are in the right directory. AC_CONFIG_SRCDIR([ici/include/ion.h]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([m4]) # Checks for programs. AC_PROG_CC AM_PROG_CC_C_O #Automake v1.12 wants AM_PROG_AR, but it doesn't exist =3.2.0])], []) # # Control building /contrib utlities # AC_ARG_ENABLE( contrib, [AC_HELP_STRING([--disable-contrib],[Disable building third-party contributed utilities])], [case "${enableval}" in yes) BUILD_CONTRIB=yes;; no) BUILD_CONTRIB=no;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-contrib]);; esac], [BUILD_CONTRIB=yes]) AM_CONDITIONAL(BUILD_CONTRIB, test "x$BUILD_CONTRIB" = "xyes") # # Allow user to disable crypto... if crypto is even enabled # if test "$IS_NASA_B" = "1"; then # To Disable crypto, use "./configure --disable-crypto" AC_ARG_ENABLE([crypto], [ --disable-crypto Turn off cryptography], [case "${enableval}" in yes) crypto=true ;; no) crypto=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --disable-crypto]) ;; esac],[crypto=true]) AM_CONDITIONAL([CRYPTO], [test x$crypto = xtrue]) if test x$crypto = xtrue; then echo "" #DoStuff else AC_SUBST( [CRYPTO_LIBS], [""] ) fi AC_DEFINE([NASA_PROTECTED_FLIGHT_CODE],[1],[Build ION NASA protected flight code]) else AM_CONDITIONAL([CRYPTO], [false]) AC_SUBST( [CRYPTO_LIBS], [""] ) fi # # Control whether AMS debugging info is printed. # if test "$IS_NASA_B" = "0"; then AC_ARG_ENABLE([ams-debug], [ --enable-ams-debug Enable AMS debugging info], [ AC_DEFINE([AMSDEBUG], 1, [Enable AMS debugging info]) ]) fi # # Dynamically choose whether or not to instrument code for gcov code coverage # Default is not to instrument the code for gcov code coverage. # AC_ARG_WITH([gcov], [AS_HELP_STRING([--with-gcov], [Turn on code coverage instrumentation])], [gcov=yes;], []) if test "x$gcov" = "xyes" ; then echo "Instrument code for gcov coverage analysis... yes" CFLAGS="$CFLAGS -g -O0 -fprofile-arcs -ftest-coverage" LDFLAGS="$LDFLAGS -fprofile-arcs -ftest-coverage -lgcov" else echo "Instrument code for gcov coverage analysis... no" fi AM_CONDITIONAL([ENABLE_GCOV], [test "x$gcov" = "xyes"]) # # If valgrind is present, allow special MTAKE/MRELEASE valgrind tutors. # AC_ARG_ENABLE([valgrind], AC_HELP_STRING([--disable-valgrind],[Do not enable valgrind debugging [default=check]]), [ ], [ enable_valgrind=check ]) if test "x$enable_valgrind" != xno; then AC_CHECK_HEADER(valgrind/valgrind.h, [AC_DEFINE([HAVE_VALGRIND_VALGRIND_H], [1], [enable valgrind macros]) valgrind_present=yes], [valgrind_present=no]) if test "x$enable_valgrind" == xyes && test "x$valgrind_present" == xno; then # User specifically requested valgrind but we can't find it. AC_MSG_ERROR([valgrind/valgrind.h not found but --enable-valgrind requested]) fi if test "x$valgrind_present" == xyes; then # Valgrind < 3.6.1-1 (Debian/Ubuntu) and gcc >= 4.6 triggers "unused-but-set-variable" # warnings in the valgrind macros. This version is present in debian unstable # 10/11, and Ubuntu 11.10. AC_MSG_CHECKING([if valgrind is compatible with -Wunused-but-set]) ORIGCFLAGS=$CFLAGS CFLAGS="$CFLAGS -Wall -Werror" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include ]], [[VALGRIND_MALLOCLIKE_BLOCK(1, 100, 0, 1); VALGRIND_FREELIKE_BLOCK(1, 0);]])], [AC_MSG_RESULT([yes]); valgrind_wunused_but_set_compat=yes], [AC_MSG_RESULT([no]); valgrind_wunused_but_set_compat=no]) CFLAGS="$ORIGCFLAGS" # If not compatible with -Wset-but-not-used, then disable this warning. if test "x$valgrind_wunused_but_set_compat" == "xno"; then AC_MSG_NOTICE([adding -Wno-unused-but-set-variable to VALGRIND_COMPAT_CFLAGS]) AC_SUBST([VALGRIND_COMPAT_CFLAGS], [-Wno-unused-but-set-variable]) fi fi fi # Check for libraries. ORIGCFLAGS="$CFLAGS" CFLAGS="$AM_CFLAGS $CFLAGS" AC_CHECK_LIB( [expat], [XML_GetCurrentLineNumber], [ AC_SUBST( [EXPAT_LIBS], ["-lexpat"] ) ], [AC_MSG_ERROR([You need to have the Expat XML development library, libexpat1-dev])] ) AC_CHECK_LIB( [pthread], [pthread_create], [ AM_LDFLAGS="$AM_LDFLAGS -lpthread" ], [AC_MSG_ERROR([You need pthread library.]) ] ) CFLAGS="$ORIGCFLAGS" # Check for programs to build documentation AC_CHECK_PROGS([POD_DOCUMENTATION], [pod2man pod2html], [1] ) if test "$POD_DOCUMENTATION" = 1; then echo "ERROR: You need to have pod2man for documentation." exit -1 fi # Check for tools to compile documentation into ION.pdf AC_PATH_PROG([PS2PDF], [ps2pdf]) AC_PATH_PROG([PDF2PS], [pdf2ps]) AC_PATH_PROG([PSJOIN], [psjoin]) AC_MSG_CHECKING([for fallback included psjoin]) if test -x "$PWD/doc/psjoin"; then PSJOIN="$PWD/doc/psjoin" AC_MSG_RESULT($PSJOIN) else AC_MSG_RESULT([not found]) fi AC_PATH_PROG([GROFF], [groff]) AC_MSG_CHECKING([if groff suports -ms]) if test "$GROFF" && echo | $GROFF -ms - >/dev/null 2>/dev/null; then AC_MSG_RESULT($GROFF) GROFFMS="$GROFF" else AC_MSG_RESULT([not found]) AC_MSG_NOTICE([try installing groff and the ms plugin]) fi AC_SUBST([GROFFMS], $GROFFMS) AC_PATH_PROG([MANOPTS], [man]) AC_MSG_CHECKING([if man supports -l]) if test "$MANOPTS" && echo | $MANOPTS -l - >/dev/null 2>/dev/null; then AC_MSG_RESULT($MANOPTS) else MANOPTS="" AC_MSG_RESULT([not found]) AC_MSG_NOTICE([try installing a version of man that supports -l]) fi AC_SUBST([MANOPTS], $MANOPTS) AC_MSG_CHECKING([for tools to build autodoc]) if test "$PS2PDF" && test "$PDF2PS" && test "$PSJOIN" && test "$GROFFMS" && test -n "$MANOPTS"; then AC_MSG_RESULT([found]) buildautodoc="yes" else AC_MSG_RESULT([not found (skipping autodoc)]) AC_MSG_NOTICE([Ensure the ghostscript, psutils, groff-base and groff packages are installed.]) fi AM_CONDITIONAL([ENABLE_AUTODOC], [ test "$buildautodoc" ]) # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS([fcntl.h malloc.h netdb.h netinet/in.h stddef.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h]) AC_C_CONST AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM AC_TYPE_UID_T # Checks for library functions. # commented out library functions that should exist everywhere. # otherwise, autoconf insisted that malloc.c, mktime.c were included in distro... AC_FUNC_FORK AC_PROG_GCC_TRADITIONAL #AC_FUNC_MALLOC #AC_FUNC_MEMCMP #AC_FUNC_MKTIME #AC_FUNC_SELECT_ARGTYPES AC_TYPE_SIGNAL #AC_FUNC_STAT #AC_FUNC_STRFTIME AC_CHECK_FUNCS([alarm ftruncate getcwd gethostbyaddr gethostbyname gethostname gettimeofday memset mkdir mkfifo rmdir select socket strcasecmp strchr strerror strncasecmp strstr strtoul uname]) #Write AM_* flag variables AC_SUBST([AM_LDFLAGS],"$AM_LDFLAGS") AC_SUBST([AM_CFLAGS],"$AM_CFLAGS") AC_SUBST([AM_LIBTOOLFLAGS],"$AM_LIBTOOLFLAGS") AM_CONDITIONAL([ION_NASA_B],[test "$IS_NASA_B" = "1"]) AM_CONDITIONAL([LINUX_BUILD], [test "x$PLATFORM" = "xlinux"]) #Output! AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([contrib/Makefile]) AC_OUTPUT ion-3.2.0~dfsg1.orig/.stamp_extracted0000644000175000017500000000000012260400055016043 0ustar l3onl3onion-3.2.0~dfsg1.orig/nm/0000755000175000017500000000000012260400057013301 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/agent/0000755000175000017500000000000012260400056014376 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/agent/lcc.h0000644000175000017500000000244712260400056015317 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: lcc.h ** ** Description: This implements the NM Agent Local Command and Control (LDC). ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/22/13 E. Birrane Update to latest version of DTNMP. Cleanup. *****************************************************************************/ #ifndef _LCC_H_ #define _LCC_H_ #include "shared/adm/adm.h" int lcc_run_ctrl_mid(mid_t *id); int lcc_run_ctrl(ctrl_exec_t *id); #endif // _LCC_H_ ion-3.2.0~dfsg1.orig/nm/agent/adm_ltp_priv.h0000644000175000017500000000777712260400056017251 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ #ifdef _HAVE_LTP_ADM_ /***************************************************************************** ** ** File Name: adm_ltp_priv.h ** ** Description: This implements the private aspects of a LTP ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/16/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef ADM_LTP_PRIV_H_ #define ADM_LTP_PRIV_H_ #include "lyst.h" #include "ltpnm.h" #include "shared/adm/adm_ltp.h" #include "shared/utils/expr.h" void agent_adm_init_ltp(); /* Get Functions */ expr_result_t ltp_get_node_resources_all(Lyst params); expr_result_t ltp_get_heap_bytes_reserved(Lyst params); expr_result_t ltp_get_heap_bytes_used(Lyst params); expr_result_t ltp_get_engines(Lyst params); expr_result_t ltp_get_eng_all(Lyst params); expr_result_t ltp_get_eng_num(Lyst params); expr_result_t ltp_get_eng_exp_sess(Lyst params); expr_result_t ltp_get_eng_cur_out_seg(Lyst params); expr_result_t ltp_get_eng_cur_imp_sess(Lyst params); expr_result_t ltp_get_eng_cur_in_seg(Lyst params); expr_result_t ltp_get_eng_last_reset_time(Lyst params); expr_result_t ltp_get_eng_out_seg_q_cnt(Lyst params); expr_result_t ltp_get_eng_out_seg_q_byte(Lyst params); expr_result_t ltp_get_eng_out_seg_pop_cnt(Lyst params); expr_result_t ltp_get_eng_out_seg_pop_byte(Lyst params); expr_result_t ltp_get_eng_out_ckp_xmit_cnt(Lyst params); expr_result_t ltp_get_eng_out_pos_ack_rcv_cnt(Lyst params); expr_result_t ltp_get_eng_out_neg_ack_rcv_cnt(Lyst params); expr_result_t ltp_get_eng_out_canc_rcv_cnt(Lyst params); expr_result_t ltp_get_eng_out_ckp_rexmt_cnt(Lyst params); expr_result_t ltp_get_eng_out_canc_xmit_cnt(Lyst params); expr_result_t ltp_get_eng_out_compl_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_rcv_red_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_rcv_red_byte(Lyst params); expr_result_t ltp_get_eng_in_seg_rcv_grn_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_rcv_grn_byte(Lyst params); expr_result_t ltp_get_eng_in_seg_rdndt_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_rdndt_byte(Lyst params); expr_result_t ltp_get_eng_in_seg_mal_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_mal_byte(Lyst params); expr_result_t ltp_get_eng_in_seg_unk_snd_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_unk_snd_byte(Lyst params); expr_result_t ltp_get_eng_in_seg_unk_cli_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_unk_cli_byte(Lyst params); expr_result_t ltp_get_eng_in_seg_stray_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_stray_byte(Lyst params); expr_result_t ltp_get_eng_in_seg_miscol_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_miscol_byte(Lyst params); expr_result_t ltp_get_eng_in_seg_clsd_cnt(Lyst params); expr_result_t ltp_get_eng_in_seg_clsd_byte(Lyst params); expr_result_t ltp_get_eng_in_ckp_rcv_cnt(Lyst params); expr_result_t ltp_get_eng_in_pos_ack_xmit_cnt(Lyst params); expr_result_t ltp_get_eng_in_neg_ack_xmit_cnt(Lyst params); expr_result_t ltp_get_eng_in_canc_xmit_cnt(Lyst params); expr_result_t ltp_get_eng_in_ack_rexmt_cnt(Lyst params); expr_result_t ltp_get_eng_in_canc_rcv_cnt(Lyst params); expr_result_t ltp_get_eng_in_compl_cnt(Lyst params); uint32_t ltp_engine_reset(Lyst params); #endif //ADM_LTP_PRIV_H_ #endif /* _HAVE_LTP_ADM_ */ ion-3.2.0~dfsg1.orig/nm/agent/ingest.h0000644000175000017500000000342012260400056016037 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: ingest.h ** ** Description: This implements the data ingest thread to receive DTNMP msgs. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/10/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef _INGEST_H_ #define _INGEST_H_ /* Validation function */ int rx_validate_mid_mc(Lyst mids, int passEmpty); int rx_validate_rule(rule_time_prod_t *rule); void *rx_thread(void *threadId); /* Message Handling Functions. */ void rx_handle_rpt_def(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used); void rx_handle_exec(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used); void rx_handle_time_prod(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used); void rx_handle_macro_def(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used); #endif /* _INGEST_H_ */ ion-3.2.0~dfsg1.orig/nm/agent/rda.h0000644000175000017500000000342312260400056015317 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: rda.h ** ** Description: This implements the Remote Data Aggregator (RDA) ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/10/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef RDA_H_ #define RDA_H_ void rda_cleanup(Lyst rules_pending, Lyst built_reports); rpt_data_t* rda_find_report(Lyst built_reports, char *recipient); int rda_scan_rules(Lyst rules_pending); int rda_scan_ctrls(Lyst exec_defs); rpt_data_entry_t* rda_build_report_entry(mid_t *mid); int rda_eval_rule(rule_time_prod_t *rule_p, rpt_data_t *report_p); int rda_eval_pending_rules(Lyst rules_pending, Lyst built_reports); int rda_send_reports(Lyst built_reports); int rda_eval_cleanup(Lyst rules_pending); void* rda_thread(void* threadId); #endif /* RDA_H_ */ ion-3.2.0~dfsg1.orig/nm/agent/adm_agent_priv.c0000644000175000017500000002162512260400056017527 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: adm_agent_priv.c ** ** Description: This implements the private aspects of a DTNMP agent ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/04/13 E. Birrane Initial Implementation ** 07/28/13 E. Birrane Updated to new ADM design. *****************************************************************************/ #include "shared/adm/adm.h" #include "adm_agent_priv.h" /****************************************************************************** * * \par Function Name: agent_adm_init_agent * * \par Initializes the collect/run functions for agent ADM support. Both the * manager and agent share functions for sizing and printing items. However, * only the agent needs to implement the functions for collecting data and * running controls. * * \par Notes: * * - We build a string representation of the MID rather than storing one * statically to save on static space. Please see the DTNMP AGENT ADM * for specifics on the information added here. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/04/13 E. Birrane Initial implementation. *****************************************************************************/ void agent_adm_init_agent() { /* Register Nicknames */ uint8_t mid_str[ADM_MID_ALLOC]; /* DTNMP Agent Data */ adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 0, mid_str); adm_add_datadef_collect(mid_str, agent_get_all); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 1, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_rpt_defs); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 2, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_sent_rpts); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 3, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_time_rules); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 4, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_time_rules_run); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 5, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_prod_rules); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 6, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_prod_rules_run); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 7, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_consts); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 8, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_data_defs); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 9, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_macros); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 10, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_macros_run); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 11, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_ctrls); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 12, mid_str); adm_add_datadef_collect(mid_str, agent_get_num_ctrls_run); /* DTNMP Agent Controls */ adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 0, mid_str); adm_add_ctrl_run(mid_str, agent_list_rpt_defs); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 1, mid_str); adm_add_ctrl_run(mid_str, agent_list_time_rules); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 2, mid_str); adm_add_ctrl_run(mid_str, agent_list_prod_rules); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 3, mid_str); adm_add_ctrl_run(mid_str, agent_list_consts); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 4, mid_str); adm_add_ctrl_run(mid_str, agent_list_data_defs); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 5, mid_str); adm_add_ctrl_run(mid_str, agent_list_macros); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 6, mid_str); adm_add_ctrl_run(mid_str, agent_list_ctrls); } /* Retrieval Functions. */ expr_result_t agent_get_all(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_BLOB; result.length = sizeof(gAgentInstr); result.value = (uint8_t*) MTAKE(result.length); memcpy(result.value, &gAgentInstr, result.length); return result; } expr_result_t agent_get_num_rpt_defs(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_rpt_defs), sizeof(gAgentInstr.num_rpt_defs), &(result.length)); return result; } expr_result_t agent_get_num_sent_rpts(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_sent_rpts), sizeof(gAgentInstr.num_sent_rpts), &(result.length)); return result; } expr_result_t agent_get_num_time_rules(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_time_rules), sizeof(gAgentInstr.num_time_rules), &(result.length)); return result; } expr_result_t agent_get_num_time_rules_run(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_time_rules_run), sizeof(gAgentInstr.num_time_rules_run), &(result.length)); return result; } expr_result_t agent_get_num_prod_rules(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_prod_rules), sizeof(gAgentInstr.num_prod_rules), &(result.length)); return result; } expr_result_t agent_get_num_prod_rules_run(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_prod_rules_run), sizeof(gAgentInstr.num_prod_rules_run), &(result.length)); return result; } expr_result_t agent_get_num_consts(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_consts), sizeof(gAgentInstr.num_consts), &(result.length)); return result; } expr_result_t agent_get_num_data_defs(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_data_defs), sizeof(gAgentInstr.num_data_defs), &(result.length)); return result; } expr_result_t agent_get_num_macros(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_macros), sizeof(gAgentInstr.num_macros), &(result.length)); return result; } expr_result_t agent_get_num_macros_run(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_macros_run), sizeof(gAgentInstr.num_macros_run), &(result.length)); return result; } expr_result_t agent_get_num_ctrls(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_ctrls), sizeof(gAgentInstr.num_ctrls), &(result.length)); return result; } expr_result_t agent_get_num_ctrls_run(Lyst params) { expr_result_t result; result.type = EXPR_TYPE_UINT32; result.value = adm_copy_integer((uint8_t*)&(gAgentInstr.num_ctrls_run), sizeof(gAgentInstr.num_ctrls_run), &(result.length)); return result; } /* Control Functions */ /* \todo: Controls for the AGENT are not yet implemented. */ uint32_t agent_list_rpt_defs(Lyst params) { return 0; } uint32_t agent_list_time_rules(Lyst params) { return 0; } uint32_t agent_list_prod_rules(Lyst params) { return 0; } uint32_t agent_list_consts(Lyst params) { return 0; } uint32_t agent_list_data_defs(Lyst params) { return 0; } uint32_t agent_list_macros(Lyst params) { return 0; } uint32_t agent_list_ctrls(Lyst params) { return 0; } uint32_t agent_remove_item(Lyst params) { return 0; } ion-3.2.0~dfsg1.orig/nm/agent/nmagent.c0000644000175000017500000007074612260400056016211 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: nmagent.c ** ** Description: This implements NM Agent main processing. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 01/10/13 E. Birrane Update to lasted DTNMP Spec. ** 06/10/13 E. Birrane Added SDR data persistence. *****************************************************************************/ // System headers. #include "unistd.h" // ION headers. #include "platform.h" #include "lyst.h" // Application headers. #include "shared/adm/adm.h" #include "shared/utils/db.h" #include "nmagent.h" #include "ingest.h" #include "rda.h" #include "adm_agent_priv.h" #include "adm_bp_priv.h" #include "adm_ltp_priv.h" #include "adm_ion_priv.h" static void agent_signal_handler(); // Definitions of global data. iif_t ion_ptr; uint8_t g_running; eid_t manager_eid; eid_t agent_eid; AgentDB gAgentDB; AgentVDB gAgentVDB; void agent_db_compdata_init(Sdr sdr) { /* \todo Implement. */ } int agent_db_compdata_persist(ctrl_exec_t* ctrl) { /* \todo Implement. */ return -1; } void agent_db_const_init(Sdr sdr) { /* \todo Implement. */ } int agent_db_const_persist(ctrl_exec_t* ctrl) { /* \todo Implement. */ return -1; } /****************************************************************************** * * \par Function Name: agent_db_ctrl_persist * * \par Persist a control to the agent SDR database. * * \param[in] item The control to persist. * * \par Notes: * * \return 1 - Success * -1 - Failure * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ int agent_db_ctrl_persist(ctrl_exec_t* item) { Sdr sdr = getIonsdr(); /* Step 0: Sanity Checks. */ if((item == NULL) || ((item->desc.itemObj == 0) && (item->desc.descObj != 0)) || ((item->desc.itemObj != 0) && (item->desc.descObj == 0))) { DTNMP_DEBUG_ERR("agent_db_ctrl_persist","bad params.",NULL); return -1; } /* * Step 1: Determine if this is already in the SDR. We will assume * it is in the SDR already if its Object fields are nonzero. */ if(item->desc.itemObj == 0) { uint8_t *data = NULL; int result = 0; /* Step 1.1: Serialize the item to go into the SDR.. */ if((data = ctrl_serialize_exec(item, &(item->desc.size))) == NULL) { DTNMP_DEBUG_ERR("agent_db_ctrl_persist", "Unable to serialize new ctrl.", NULL); return -1; } result = db_persist(data, item->desc.size, &(item->desc.itemObj), &(item->desc), sizeof(ctrl_exec_desc_t), &(item->desc.descObj), gAgentDB.ctrls); MRELEASE(data); if(result != 1) { DTNMP_DEBUG_ERR("agent_db_ctrl_persist","Unable to persist def.",NULL); return -1; } DTNMP_DEBUG_INFO("agent_db_ctrl_persist","Persisted new ctrl", NULL); } else { ctrl_exec_desc_t temp; sdr_begin_xn(sdr); sdr_stage(sdr, (char*) &temp, item->desc.descObj, sizeof(ctrl_exec_desc_t)); temp = item->desc; sdr_write(sdr, item->desc.descObj, (char *) &temp, sizeof(ctrl_exec_desc_t)); DTNMP_DEBUG_INFO("agent_db_ctrl_persist","Updated ctrl", NULL); sdr_end_xn(sdr); } return 1; } /****************************************************************************** * * \par Function Name: agent_db_init * * \par Initialize items from the agent SDR database. * * \par Notes: * * \return 1 - Success * -1 - Failure * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ int agent_db_init() { Sdr sdr; sdr = getIonsdr(); // * Initialize the non-volatile database. * / memset((char*) &gAgentDB, 0, sizeof(AgentDB)); /* Recover the Agent database, creating it if necessary. */ CHKERR(sdr_begin_xn(sdr)); gAgentDB.descObj = sdr_find(sdr, "agentdb", NULL); switch(gAgentDB.descObj) { case -1: // SDR error. * / sdr_cancel_xn(sdr); DTNMP_DEBUG_ERR("agent_db_init", "Can't search for Agent DB in SDR.", NULL); return -1; case 0: // Not found; Must create new DB. * / gAgentDB.descObj = sdr_malloc(sdr, sizeof(AgentDB)); if(gAgentDB.descObj == 0) { sdr_cancel_xn(sdr); DTNMP_DEBUG_ERR("agent_db_init", "No space for agent database.", NULL); return -1; } DTNMP_DEBUG_ALWAYS("agent_db_init", "Creating DB", NULL); gAgentDB.compdata = sdr_list_create(sdr); gAgentDB.consts = sdr_list_create(sdr); gAgentDB.ctrls = sdr_list_create(sdr); gAgentDB.macros = sdr_list_create(sdr); gAgentDB.ops = sdr_list_create(sdr); gAgentDB.reports = sdr_list_create(sdr); gAgentDB.rules = sdr_list_create(sdr); sdr_write(sdr, gAgentDB.descObj, (char *) &gAgentDB, sizeof(AgentDB)); sdr_catlg(sdr, "agentdb", 0, gAgentDB.descObj); break; default: /* Found DB in the SDR */ /* Read in the Database. */ sdr_read(sdr, (char *) &gAgentDB, gAgentDB.descObj, sizeof(AgentDB)); DTNMP_DEBUG_ALWAYS("agent_db_init", "Found DB", NULL); } if(sdr_end_xn(sdr)) { DTNMP_DEBUG_ERR("agent_db_init", "Can't create Agent database.", NULL); return -1; } return 1; } int agent_db_macro_persist(def_gen_t* ctrl) { /* \todo Implement. */ return -1; } int agent_db_op_persist(def_gen_t* ctrl) { /* \todo Implement. */ return -1; } /****************************************************************************** * * \par Function Name: agent_db_report_persist * * \par Persist a custom report definition to the agent SDR database. * * \param[in] item The definition to persist. * * \par Notes: * * \return 1 - Success * -1 - Failure * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ int agent_db_report_persist(def_gen_t* item) { Sdr sdr = getIonsdr(); /* Step 0: Sanity Checks. */ if((item == NULL) || ((item->desc.itemObj == 0) && (item->desc.itemObj != 0)) || ((item->desc.itemObj != 0) && (item->desc.itemObj == 0))) { DTNMP_DEBUG_ERR("agent_db_report_persist","bad params.",NULL); return -1; } /* * Step 1: Determine if this is already in the SDR. We will assume * it is in the SDR already if its Object fields are nonzero. */ if(item->desc.itemObj == 0) { uint8_t *data = NULL; int result = 0; /* Step 1.1: Serialize the item to go into the SDR.. */ if((data = def_serialize_gen(item, &(item->desc.size))) == NULL) { DTNMP_DEBUG_ERR("agent_db_report_persist", "Unable to serialize new item.", NULL); return -1; } result = db_persist(data, item->desc.size, &(item->desc.itemObj), &(item->desc), sizeof(def_gen_desc_t), &(item->desc.descObj), gAgentDB.reports); MRELEASE(data); if(result != 1) { DTNMP_DEBUG_ERR("agent_db_report_persist","Unable to persist def.",NULL); return -1; } } else { def_gen_desc_t temp; sdr_begin_xn(sdr); sdr_stage(sdr, (char*) &temp, item->desc.descObj, sizeof(def_gen_desc_t)); temp = item->desc; sdr_write(sdr, item->desc.descObj, (char *) &temp, sizeof(def_gen_desc_t)); sdr_end_xn(sdr); } return 1; } /****************************************************************************** * * \par Function Name: agent_db_rule_persist * * \par Persist a time-based rule to the agent SDR database. * * \param[in] item The rule to persist. * * \par Notes: * * \return 1 - Success * -1 - Failure * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ int agent_db_rule_persist(rule_time_prod_t *item) { Sdr sdr = getIonsdr(); /* Step 0: Sanity Checks. */ if((item == NULL) || ((item->desc.itemObj == 0) && (item->desc.itemObj != 0)) || ((item->desc.itemObj != 0) && (item->desc.itemObj == 0))) { DTNMP_DEBUG_ERR("agent_db_rule_persist","bad params.",NULL); return -1; } /* * Step 1: Determine if this is already in the SDR. We will assume * it is in the SDR already if its Object fields are nonzero. */ if(item->desc.itemObj == 0) { uint8_t *data = NULL; int result = 0; /* Step 1.1: Serialize the item to go into the SDR.. */ if((data = ctrl_serialize_time_prod_entry(item, &(item->desc.size))) == NULL) { DTNMP_DEBUG_ERR("agent_db_rule_persist", "Unable to serialize new item.", NULL); return -1; } result = db_persist(data, item->desc.size, &(item->desc.itemObj), &(item->desc), sizeof(rule_time_prod_desc_t), &(item->desc.descObj), gAgentDB.rules); MRELEASE(data); if(result != 1) { DTNMP_DEBUG_ERR("agent_db_rule_persist","Unable to persist def.",NULL); return -1; } } else { rule_time_prod_desc_t temp; sdr_begin_xn(sdr); sdr_stage(sdr, (char*) &temp, item->desc.descObj, 0); //sizeof(rule_time_prod_desc_t)); temp = item->desc; sdr_write(sdr, item->desc.descObj, (char *) &temp, sizeof(rule_time_prod_desc_t)); if(sdr_end_xn(sdr)) { DTNMP_DEBUG_ERR("agentDbInit", "Can't create Agent database.", NULL); return -1; } } return 1; } /****************************************************************************** * * \par Function Name: agent_vdb_add * * \par Add an item to a mutex-locked list. * * \param[in] item The item to add * \param[in] list The list to hold the item. * \param[in] mutex The mute protecting the list. * * \par Notes: * - This is a helper function used to add items to various agent * lists. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ void agent_vdb_add(void *item, Lyst list, ResourceLock *mutex) { lockResource(mutex); lyst_insert_last(list, item); unlockResource(mutex); } void agent_vdb_compdata_init(Sdr sdr) { /* \todo: Implement. */ } void agent_vdb_consts_init(Sdr sdr) { /* \todo: Implement. */ } /****************************************************************************** * * \par Function Name: agent_vdb_ctrls_init * * \par Read controls from the SDR database into memory lists. * * \param[in] sdr The SDR containing the controls information. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ void agent_vdb_ctrls_init(Sdr sdr) { Object elt; Object itemObj; Object descObj; ctrl_exec_desc_t cur_desc; ctrl_exec_t *cur_item; uint8_t *data = NULL; uint32_t bytes_used = 0; int num = 0; sdr_begin_xn(sdr); /* Step 1: Read through SDR list.... */ for (elt = sdr_list_first(sdr, gAgentDB.ctrls); elt; elt = sdr_list_next(sdr, elt)) { /* Step 1.1: Grab the descriptor. */ descObj = sdr_list_data(sdr, elt); sdr_read(sdr, (char *) &cur_desc, descObj, sizeof(cur_desc)); /* Step 1.2: Save the descriptor. */ cur_desc.descObj = descObj; /* Step 1.3: Allocate space for the item. */ if((data = (uint8_t*) MTAKE(cur_desc.size)) == NULL) { DTNMP_DEBUG_ERR("agent_vdb_ctrls_init","Can't allocate %d bytes.", cur_desc.size); } else { /* Step 1.4: Grab the serialized item */ sdr_read(sdr, (char *) data, cur_desc.itemObj, cur_desc.size); /* Step 1.5: Deserialize the item. */ if((cur_item = ctrl_deserialize_exec(data,cur_desc.size, &bytes_used)) == NULL) { DTNMP_DEBUG_ERR("agent_vdb_ctrls_init","Failed to deserialize ctrl.",NULL); } else { /* Step 1.6: Copy current descriptor to cur_rule. */ cur_item->desc = cur_desc; /* Step 1.7: Add rule to list of active rules. */ ADD_CTRL(cur_item); } /* Step 1.8: Release the serialized item. */ MRELEASE(data); /* Step 1.9: Note that we have another control. */ num++; } } sdr_end_xn(sdr); /* Step 2: Note to use number of controls read in. */ DTNMP_DEBUG_ALWAYS("", "Added %d Controls from DB.", num); } /****************************************************************************** * * \par Function Name: agent_register * * \par Send a broadcast registration message for this agent. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ void agent_register() { adm_reg_agent_t *reg = NULL; uint8_t *data = NULL; uint32_t len = 0; pdu_msg_t *pdu_msg = NULL; pdu_group_t *pdu_group = NULL; /* Step 0: Build an agent registration message. */ if((reg = msg_create_reg_agent(agent_eid)) == NULL) { DTNMP_DEBUG_ERR("agent_register","Unable to create agent registration.",NULL); return; } /* Step 1: Serialize the message. */ if((data = msg_serialize_reg_agent(reg, &len)) == NULL) { DTNMP_DEBUG_ERR("agent_register","Unable to serialize message.", NULL); msg_release_reg_agent(reg); return; } /* Step 2: Create the DTNMP message. */ if((pdu_msg = pdu_create_msg(MSG_TYPE_ADMIN_REG_AGENT, data, len, NULL)) == NULL) { DTNMP_DEBUG_ERR("agent_register","Unable to create PDU message.", NULL); msg_release_reg_agent(reg); MRELEASE(data); return; } /* Step 3: Create a group for this message. */ if((pdu_group = pdu_create_group(pdu_msg)) == NULL) { DTNMP_DEBUG_ERR("agent_register","Unable to create PDU message.", NULL); msg_release_reg_agent(reg); MRELEASE(data); pdu_release_msg(pdu_msg); return; } /* Step 4: Send the message. */ iif_send(&ion_ptr, pdu_group, manager_eid.name); /* * Step 5: Release resources. Releasing the group releases both the * PDU message as well as the data (which is shallow-copied * into the pdu_msg. */ pdu_release_group(pdu_group); msg_release_reg_agent(reg); } /****************************************************************************** * * \par Function Name: agent_vdb_destroy * * \par Cleans up agent memory lists. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ void agent_vdb_destroy() { /* Step 1: Clear out data in lysts. */ def_lyst_clear(&(gAgentVDB.compdata), &(gAgentVDB.compdata_mutex), 1); def_lyst_clear(&(gAgentVDB.consts), &(gAgentVDB.consts_mutex), 1); ctrl_clear_lyst(&(gAgentVDB.ctrls), &(gAgentVDB.ctrls_mutex), 1); def_lyst_clear(&(gAgentVDB.macros), &(gAgentVDB.macros_mutex), 1); def_lyst_clear(&(gAgentVDB.ops), &(gAgentVDB.ops_mutex), 1); rpt_clear_lyst(&(gAgentVDB.reports), &(gAgentVDB.reports_mutex), 1); rule_time_clear_lyst(&(gAgentVDB.rules),&(gAgentVDB.rules_mutex), 1); /* Step 2: Release resource locks. */ killResourceLock(&(gAgentVDB.compdata_mutex)); killResourceLock(&(gAgentVDB.consts_mutex)); killResourceLock(&(gAgentVDB.ctrls_mutex)); killResourceLock(&(gAgentVDB.macros_mutex)); killResourceLock(&(gAgentVDB.ops_mutex)); killResourceLock(&(gAgentVDB.reports_mutex)); killResourceLock(&(gAgentVDB.rules_mutex)); } /****************************************************************************** * * \par Function Name: agent_vdb_init * * \par Initializes agent memory lists. * * \par Notes: * * \return 1 - Success. * -1 - Failure. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ /* Initialize all of the VDB items. */ int agent_vdb_init() { Sdr sdr = getIonsdr(); int result = 1; DTNMP_DEBUG_ENTRY("agent_vdb_init","()",NULL); /* Step 0: Clean the memory. */ memset(&gAgentVDB, 0, sizeof(gAgentVDB)); /* Step 1: Create lysts and associated resource locks. */ if((gAgentVDB.compdata = lyst_create()) == NULL) result = -1; if(initResourceLock(&(gAgentVDB.compdata_mutex))) result = -1; agent_vdb_compdata_init(sdr); if((gAgentVDB.consts = lyst_create()) == NULL) result = -1; if(initResourceLock(&(gAgentVDB.consts_mutex))) result = -1; agent_vdb_consts_init(sdr); if((gAgentVDB.ctrls = lyst_create()) == NULL) result = -1; if(initResourceLock(&(gAgentVDB.ctrls_mutex))) result = -1; agent_vdb_ctrls_init(sdr); if((gAgentVDB.macros = lyst_create()) == NULL) result = -1; if(initResourceLock(&(gAgentVDB.macros_mutex))) result = -1; agent_vdb_macros_init(sdr); if((gAgentVDB.ops = lyst_create()) == NULL) result = -1; if(initResourceLock(&(gAgentVDB.ops_mutex))) result = -1; agent_vdb_ops_init(sdr); if((gAgentVDB.reports = lyst_create()) == NULL) result = -1; if(initResourceLock(&(gAgentVDB.reports_mutex))) result = -1; agent_vdb_reports_init(sdr); if((gAgentVDB.rules = lyst_create()) == NULL) result = -1; if(initResourceLock(&(gAgentVDB.rules_mutex))) result = -1; agent_vdb_rules_init(sdr); DTNMP_DEBUG_EXIT("agent_vdb_init","-->%d",result); return result; } void agent_vdb_macros_init(Sdr sdr) { /* \todo: implement. */ } void agent_vdb_ops_init(Sdr sdr) { /* \todo: implement. */ } /****************************************************************************** * * \par Function Name: agent_vdb_reports_init * * \par Read report definitions from the SDR database into memory lists. * * \param[in] sdr The SDR containing the report information. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ void agent_vdb_reports_init(Sdr sdr) { Object elt; Object defObj; Object descObj; def_gen_desc_t cur_desc; def_gen_t *cur_item; uint8_t *data; uint32_t bytes_used = 0; int num = 0; sdr_begin_xn(sdr); /* Step 1: Walk through report definitions. */ for (elt = sdr_list_first(sdr, gAgentDB.reports); elt; elt = sdr_list_next(sdr, elt)) { /* Step 1.1: Grab the descriptor. */ descObj = sdr_list_data(sdr, elt); sdr_read(sdr, (char *) &cur_desc, descObj, sizeof(cur_desc)); cur_desc.descObj = descObj; /* Step 1.2: Allocate space for the def. */ if((data = (uint8_t*) MTAKE(cur_desc.size)) == NULL) { DTNMP_DEBUG_ERR("agent_vdb_reports_init","Can't allocate %d bytes.", cur_desc.size); } else { /* Step 1.3: Grab the serialized rule */ sdr_read(sdr, (char *) data, cur_desc.itemObj, cur_desc.size); /* Step 1.4: Deserialize into a rule object. */ if((cur_item = def_deserialize_gen(data, cur_desc.size, &bytes_used)) == NULL) { DTNMP_DEBUG_ERR("agent_vdb_reports_init","Can't deserialize rpt.", NULL); } else { /* Step 1.5: Copy current descriptor to cur_rule. */ cur_item->desc = cur_desc; /* Step 1.6: Add report def to list of report defs. */ ADD_REPORT(cur_item); /* Step 1.7: Note that we have read a new report.*/ num++; } /* Step 1.8: Release serialized rpt, we don't need it. */ MRELEASE(data); } } sdr_end_xn(sdr); /* Step 2: Print to user total number of reports read.*/ DTNMP_DEBUG_ALWAYS("", "Added %d Reports from DB.", num); } /****************************************************************************** * * \par Function Name: agent_vdb_rules_init * * \par Read time-based rule definitions from the SDR database into memory lists. * * \param[in] sdr The SDR containing the rule information. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 06/10/13 E. Birrane Initial implementation. *****************************************************************************/ void agent_vdb_rules_init(Sdr sdr) { Object elt; Object itemObj; Object descObj; rule_time_prod_desc_t cur_descr; rule_time_prod_t *cur_item; uint8_t *data = NULL; uint32_t bytes_used = 0; int num = 0; sdr_begin_xn(sdr); /* Step 1: Read in active rules. */ for (elt = sdr_list_first(sdr, gAgentDB.rules); elt; elt = sdr_list_next(sdr, elt)) { /* Step 1.1: Grab the descriptor. */ descObj = sdr_list_data(sdr, elt); sdr_read(sdr, (char *) &cur_descr, descObj, sizeof(cur_descr)); cur_descr.descObj = descObj; /* Step 1.2: Allocate space for the rule. */ if((data = (uint8_t*) MTAKE(cur_descr.size)) == NULL) { DTNMP_DEBUG_ERR("agent_vdb_reports_init","Can't allocate %d bytes.", cur_descr.size); } else { /* Step 1.3: Grab the serialized rule */ sdr_read(sdr, (char *) data, cur_descr.itemObj, cur_descr.size); /* Step 1.4: Deserialize into a rule object. */ if((cur_item = ctrl_deserialize_time_prod_entry(data, cur_descr.size, &bytes_used)) == NULL) { DTNMP_DEBUG_ERR("agent_vdb_reports_init","Can't deserialize rule.", NULL); } else { /* Step 1.5: Copy current descriptor to cur_rule. */ cur_item->desc = cur_descr; /* Step 1.6: Add rule to list of active rules. */ ADD_RULE(cur_item); /* Step 1.7: Note that another rule has been read. */ num++; } /* Step 1.8: Release serialized rule, we don't need it. */ MRELEASE(data); } } sdr_end_xn(sdr); /* Step 2: Print to user total number of rules read.*/ DTNMP_DEBUG_ALWAYS("", "Added %d Rules from DB.", num); } /****************************************************************************** * * \par Function Name: main * * \par Main agent processing function. * * \param[in] argc # command line arguments. * \param[in] argv[] Command-line arguments. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 01/10/13 E. Birrane Update to lasted DTNMP Spec. ** 06/10/13 E. Birrane Added SDR data persistence. *****************************************************************************/ int main(int argc, char *argv[]) { pthread_t ingest_thr; pthread_t rda_thr; char ingest_thr_name[] = "ingest_thread"; char rda_thr_name[] = "rda_thread"; int rc; errno = 0; DTNMP_DEBUG_ENTRY("agent_main","(%d, 0x%#llx)", argc, (unsigned long)argv); /* Step 0: Sanity check. */ if(argc != 3) { DTNMP_DEBUG_ALWAYS("main","Usage: nmagent \n", NULL); return 1; } DTNMP_DEBUG_INFO("agent main","Agent EID: %s, Mgr EID: %s", argv[1], argv[2]); /* Step 1: Indicate that the threads should run once started. */ g_running = 1; /* Step 2: Note command-line arguments. */ strcpy((char *) manager_eid.name, argv[2]); strcpy((char *) agent_eid.name, argv[1]); /* Step 3: Attach to ION and register. */ if (ionAttach() < 0) { DTNMP_DEBUG_ERR("agentDbInit", "Agent can't attach to ION.", NULL); return -1; } if(iif_register_node(&ion_ptr, agent_eid) != 1) { DTNMP_DEBUG_ERR("agent_main","Unable to regster BP Node. Exiting.", NULL); DTNMP_DEBUG_EXIT("agent_main","->-1",NULL); return -1; } if (iif_is_registered(&ion_ptr)) { DTNMP_DEBUG_INFO("agent_main","Agent registered with ION, EID: %s", iif_get_local_eid(&ion_ptr).name); } else { DTNMP_DEBUG_ERR("agent_main","Failed to register agent with ION, EID %s", iif_get_local_eid(&ion_ptr).name); DTNMP_DEBUG_EXIT("agent_main","->-1",NULL); return -1; } /* Step 4: Read information from SDR and initialize memory lists.*/ agent_db_init(); if(agent_vdb_init() == -1) { agent_vdb_destroy(); DTNMP_DEBUG_ERR("agent_main","Unable to initialize VDB, errno = %s", strerror(errno)); // MRELEASE(ion_ptr); DTNMP_DEBUG_EXIT("agent_main","->-1",NULL); return -1; } /* Step 5: Initialize ADM support. */ adm_init(); agent_adm_init_bp(); #ifdef _HAVE_LTP_ADM_ agent_adm_init_ltp(); #endif #ifdef _HAVE_ION_ADM_ agent_adm_init_ion(); #endif agent_adm_init_agent(); /* Step 6: Register signal handlers. */ isignal(SIGINT, agent_signal_handler); isignal(SIGTERM, agent_signal_handler); /* Step 7: Start agent threads. */ rc = pthread_create(&ingest_thr, NULL, rx_thread, (void *)ingest_thr_name); if (rc) { DTNMP_DEBUG_ERR("agent_main","Unable to create pthread %s, errno = %s", ingest_thr_name, strerror(errno)); adm_destroy(); agent_vdb_destroy(); DTNMP_DEBUG_EXIT("agent_main","->-1",NULL); return -1; } rc = pthread_create(&rda_thr, NULL, rda_thread, (void *)rda_thr_name); if (rc) { DTNMP_DEBUG_ERR("agent_main","Unable to create pthread %s, errno = %s", rda_thr_name, strerror(errno)); adm_destroy(); agent_vdb_destroy(); DTNMP_DEBUG_EXIT("agent_main","->-1",NULL); return -1; } DTNMP_DEBUG_ALWAYS("agent_main","Threads started...", NULL); /* Step 8: Send out agent broadcast message. */ agent_register(); /* Step 9: Join threads and wait for them to complete. */ if (pthread_join(ingest_thr, NULL)) { DTNMP_DEBUG_ERR("agent_main","Unable to join pthread %s, errno = %s", ingest_thr_name, strerror(errno)); adm_destroy(); agent_vdb_destroy(); DTNMP_DEBUG_EXIT("agent_main","->-1",NULL); return -1; } if (pthread_join(rda_thr, NULL)) { DTNMP_DEBUG_ERR("agent_main","Unable to join pthread %s, errno = %s", rda_thr_name, strerror(errno)); adm_destroy(); agent_vdb_destroy(); DTNMP_DEBUG_EXIT("agent_main","->-1",NULL); return -1; } /* Step 10: Cleanup. */ DTNMP_DEBUG_ALWAYS("agent_main","Cleaning Agent Resources.",NULL); adm_destroy(); agent_vdb_destroy(); DTNMP_DEBUG_ALWAYS("agent_main","Stopping Agent.",NULL); DTNMP_DEBUG_INFO("agent_main","Exiting Agent after cleanup.", NULL); return 0; } /****************************************************************************** * * \par Function Name: agent_signal_handler * * \par Catches kill signals and gracefully shuts down the agent. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 08/18/13 E. Birrane Initial Implementation *****************************************************************************/ static void agent_signal_handler() { isignal(SIGINT,agent_signal_handler); isignal(SIGTERM, agent_signal_handler); g_running = 0; } ion-3.2.0~dfsg1.orig/nm/agent/nmagent.h0000644000175000017500000001707512260400056016212 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: nmagent.h ** ** Description: This implements NM Agent main processing. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/10/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef _NM_AGENT_H #define _NM_AGENT_H #define DEBUG 1 // Standard includes #include "stdint.h" #include "pthread.h" // ION includes #include "platform.h" #include "lyst.h" // Application includes #include "shared/utils/nm_types.h" #include "shared/utils/ion_if.h" #include "shared/primitives/mid.h" #include "shared/primitives/rules.h" #include "shared/msg/pdu.h" #include "shared/msg/msg_reports.h" #include "shared/msg/msg_def.h" #include "shared/msg/msg_ctrl.h" #include "shared/msg/msg_admin.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ static const int32_t NM_RECEIVE_TIMEOUT_SEC = 1; /* * +--------------------------------------------------------------------------+ * | MACROS + * +--------------------------------------------------------------------------+ */ #define ADD_COMPDATA(x) agent_vdb_add(x, gAgentVDB.compdata, &(gAgentVDB.compdata_mutex)); #define ADD_CONST(x) agent_vdb_add(x, gAgentVDB.consts, &(gAgentVDB.consts_mutex)); #define ADD_CTRL(x) agent_vdb_add(x, gAgentVDB.ctrls, &(gAgentVDB.ctrls_mutex)); #define ADD_MACRO(x) agent_vdb_add(x, gAgentVDB.macros, &(gAgentVDB.macros_mutex)); #define ADD_OP(x) agent_vdb_add(x, gAgentVDB.ops, &(gAgentVDB.ops_mutex)); #define ADD_REPORT(x) agent_vdb_add(x, gAgentVDB.reports, &(gAgentVDB.reports_mutex)); #define ADD_RULE(x) agent_vdb_add(x, gAgentVDB.rules, &(gAgentVDB.rules_mutex)); /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ /* * This structure implements the DTNMP Agent SDR database which keeps a list * of all agent information that must be persisted across a reset. * * Each object in the database represents an sdr_list. Each list is populated * with a series of pointers to "descriptor" objects. Each descriptor object * captures meta-data associated with the associated DTNMP object and a * pointer to that object. DTNMP objects are stored in the SDR in their * message-serialized form as that comprises the most space-efficient * representation of the object. * * On agent startup, DTNMP object types are deserialized and copied into * associated RAM data types. * * For example, the active_rules Object in the database is an sdr_list. Each * item in the active_rules list is an Object which points to a * rule_time_prod_desc_t object. This descriptor object captures information * such as the execution state of the active rule. One of the entries of the * rule_time_prod_desc_t object is an Object pointer to the serialized * rule in the SDR. On system startup, the agent will grab the descriptor * object and use it to find the serialized rule. The rule will be de-serialized * into a new rule structure. The meta-data associated with the rule will be * populated by additional meta-data in the rule's descriptor object. * * All entities in the DB operate in this way, as follows. * * LIST Descriptor Type Type that we deserialize into * -------------+-----------------------+------------------------------ * active_rules | rule_time_prod_desc_t | rule_time_prod_t * custom_defs | def_gen_desc_t | def_gen_t * macro_defs | def_gen_desc_t | def_gen_t * exec_defs | ctrl_exec_desc_t | ctrl_exec_t * */ typedef struct { Object compdata; /* SDR list: def_gen_descr_t */ Object consts; Object ctrls; /* SDR list: ctrl_exec_descr_t */ Object macros; /* SDR list: def_gen_descr_t */ Object ops; Object reports; Object rules; /* SDR list: rule_time_prod_descr_t */ Object descObj; /**> The pointer to the AgentDB object in the SDR. */ } AgentDB; /* * This structure captures the "volatile" database, which is the set of * information relating to configured items kept in the agent's memory. */ typedef struct { Lyst compdata; Lyst consts; Lyst ctrls; Lyst macros; Lyst ops; Lyst reports; Lyst rules; ResourceLock compdata_mutex; ResourceLock consts_mutex; ResourceLock ctrls_mutex; ResourceLock macros_mutex; ResourceLock ops_mutex; ResourceLock reports_mutex; ResourceLock rules_mutex; } AgentVDB; /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ int agent_db_compdata_persist(ctrl_exec_t* item); int agent_db_const_persist(ctrl_exec_t* item); int agent_db_ctrl_persist(ctrl_exec_t* item); int agent_db_init(); int agent_db_macro_persist(def_gen_t* item); int agent_db_op_persist(def_gen_t* item); int agent_db_report_persist(def_gen_t* item); int agent_db_rule_persist(rule_time_prod_t* item); void agent_register(); void agent_vdb_add(void *item, Lyst list, ResourceLock *mutex); void agent_vdb_compdata_init(Sdr sdr); void agent_vdb_consts_init(Sdr sdr); void agent_vdb_ctrls_init(Sdr sdr); void agent_vdb_destroy(); int agent_vdb_init(); void agent_vdb_macros_init(Sdr sdr); void agent_vdb_ops_init(Sdr sdr); void agent_vdb_reports_init(Sdr sdr); void agent_vdb_rules_init(Sdr sdr); /* * +--------------------------------------------------------------------------+ * | GLOBAL DATA DEFINITIONS + * +--------------------------------------------------------------------------+ */ /** * Indicates if the thread loops should continue to run. This * value is updated by the main() and read by the subordinate * threads. **/ extern uint8_t g_running; /** * Storage list for production rules sent by a manager and received * by the agent. These will be executed at a perscribed time (measured * in ticks) and when ready will be placed in the rules_pending list * for execution. References to this object should be made * within mutexes to make it thread-safe. **/ /** * Holding area for rules that are ready to be evaluated and added * to a pending report. References to this object should be made * within mutexes to make it thread-safe. **/ /** * The endpoint identifier (EID) of the network manager node. **/ extern eid_t manager_eid; /** * The endpoint identifier (EID) of this agent node. **/ extern eid_t agent_eid; /** * The interface object the ION system. **/ extern iif_t ion_ptr; extern AgentVDB gAgentVDB; extern AgentDB gAgentDB; #endif //_NM_AGENT_H_ ion-3.2.0~dfsg1.orig/nm/agent/adm_ion_priv.h0000644000175000017500000000626612260400056017227 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ #ifdef _HAVE_ION_ADM_ /***************************************************************************** ** ** File Name: adm_ion_priv.h ** ** Description: This implements the private aspects of an ION ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/16/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef ADM_ION_PRIV_H_ #define ADM_ION_PRIV_H_ #include "lyst.h" #include "bpnm.h" #include "icinm.h" #include "shared/adm/adm_ion.h" #include "shared/utils/expr.h" void agent_adm_init_ion(); /* Retrieval Functions */ /* ION ICI */ expr_result_t ion_ici_get_sdr_state_all(Lyst params); expr_result_t ion_ici_get_small_pool_size(Lyst params); expr_result_t ion_ici_get_small_pool_free(Lyst params); expr_result_t ion_ici_get_small_pool_alloc(Lyst params); expr_result_t ion_ici_get_large_pool_size(Lyst params); expr_result_t ion_ici_get_large_pool_free(Lyst params); expr_result_t ion_ici_get_large_pool_alloc(Lyst params); expr_result_t ion_ici_get_unused_size(Lyst params); /* ION INDUCT */ expr_result_t ion_induct_get_all(Lyst params); expr_result_t ion_induct_get_name(Lyst params); expr_result_t ion_induct_get_last_reset(Lyst params); expr_result_t ion_induct_get_rx_bndl(Lyst params); expr_result_t ion_induct_get_rx_byte(Lyst params); expr_result_t ion_induct_get_mal_bndl(Lyst params); expr_result_t ion_induct_get_mal_byte(Lyst params); expr_result_t ion_induct_get_inauth_bndl(Lyst params); expr_result_t ion_induct_get_inauth_byte(Lyst params); expr_result_t ion_induct_get_over_bndl(Lyst params); expr_result_t ion_induct_get_over_byte(Lyst params); /* ION OUTDUCT */ expr_result_t ion_outduct_get_all(Lyst params); expr_result_t ion_outduct_get_name(Lyst params); expr_result_t ion_outduct_get_cur_q_bdnl(Lyst params); expr_result_t ion_outduct_get_cur_q_byte(Lyst params); expr_result_t ion_outduct_get_last_reset(Lyst params); expr_result_t ion_outduct_get_enq_bndl(Lyst params); expr_result_t ion_outduct_get_enq_byte(Lyst params); expr_result_t ion_outduct_get_deq_bndl(Lyst params); expr_result_t ion_outduct_get_deq_byte(Lyst params); /* ION NODE */ expr_result_t ion_node_get_all(Lyst params); expr_result_t ion_node_get_inducts(Lyst params); expr_result_t ion_node_get_outducts(Lyst params); /* ION Controls */ uint32_t ion_ctrl_induct_reset(Lyst params); uint32_t ion_ctrl_outduct_reset(Lyst params); #endif //ADM_ION_PRIV_H_ #endif // _HAVE_ION_ADM_ ion-3.2.0~dfsg1.orig/nm/agent/rda.c0000644000175000017500000007175412260400056015326 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2011 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** \file rda.cpp ** ** File Name: rda.cpp ** ** ** Subsystem: ** Network Management Utilities: DTNMP Agent ** ** Description: This file implements the DTNMP Agent's Remote Data ** Aggregator thread. Periodically, this thread runs to evaluate ** what production rules are queued for execution, runs these ** rules, constructs the appropriate data reports, and queues ** them for transmission. ** ** Notes: ** ** Assumptions: ** 1. We assume that this code is not under such tight profiling ** constraints that sanity checks are too expensive. ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/06/11 M. Reid Initial Implementation ** 10/21/11 E. Birrane Code comments and functional updates. ** 06/27/13 E. Birrane Support persisted rules. *****************************************************************************/ #include "platform.h" #include "lyst.h" #include "shared/utils/utils.h" #include "shared/primitives/mid.h" #include "shared/primitives/instr.h" #include "shared/msg/msg_reports.h" #include "shared/utils/db.h" #include "nmagent.h" #include "ldc.h" #include "lcc.h" /****************************************************************************** * * \par Function Name: rda_cleanup * * \par Purpose: Cleans up any resources left over by the RDA when it exits. * * \retval void * * \param[in,out] rules_pending - List of rules RDA has been evaluating. * \param[in,out] built_reports - List of reports built during an RDA run. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/21/11 E. Birrane Initial implementation, *****************************************************************************/ void rda_cleanup(Lyst rules_pending, Lyst built_reports) { /* rules_pending only holds pointers. Nothing to free. */ lyst_destroy(rules_pending); rpt_clear_lyst(&built_reports, NULL, 0); lyst_destroy(built_reports); } /****************************************************************************** * * \par Function Name: rda_find_report * * \par Purpose: Find the data report intended for a given recipient. The * agent will, when possible, combine reports for a single * recipient. * * \param[in] built_reports - List of reports built during an RDA run. * \param[in] recipient - The recipient for which we are searching for * a report. * * \par Notes: * * \return !NULL - Report for this recipient. * NULL - Error. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/21/11 E. Birrane Initial implementation, *****************************************************************************/ rpt_data_t *rda_find_report(Lyst built_reports, char *recipient) { LystElt elt; rpt_data_t *cur_report = NULL; rpt_data_t *result = NULL; DTNMP_DEBUG_ENTRY("rda_find_report","(0x%#llx, %s)", (unsigned long) built_reports, recipient); /* Step 0: Sanity check. */ if(recipient == NULL) { DTNMP_DEBUG_ERR("rda_find_report","Bad parms.",NULL); return NULL; } /* Step 1: Search the list of reports identified so far. */ for (elt = lyst_first(built_reports); elt; elt = lyst_next(elt)) { /* Step 1.1: Grab the current report */ cur_report = (rpt_data_t*) lyst_data(elt); /* Step 1.2: Check if this report is destined for our recipient. */ if(strcmp(cur_report->recipient.name, recipient) == 0) { DTNMP_DEBUG_INFO("rda_find_report", "Found existing report for recipient %s", recipient); /* Step 1.2.1: Remeber report if it is a match. */ result = cur_report; /* Step 1.2.3: Currently, we only match on 1 recipient, so, break.*/ break; } } /* * Step 2: If there is no matching report, we will need to create a new * one for this recipient. */ if(result == NULL) { eid_t rx; strcpy(rx.name,recipient); result = rpt_create_data((uint32_t)getUTCTime(), lyst_create(), rx); DTNMP_DEBUG_INFO("rda_find_report","New report for recipient %s", recipient); lyst_insert_first(built_reports, result); } DTNMP_DEBUG_EXIT("rda_find_report","->0x%x", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: rda_scan_rules * * \par Purpose: Walks the list of rules defined by this agent, determines * which rules are to be executed, and updates housekeeping * information for each rule. * * \retval int - 0 : Success * -1 : Failure * * \param[in,out] rules_pending - List of rules that should be executed during * this execution period. * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/21/11 E. Birrane Initial implementation, *****************************************************************************/ int rda_scan_rules(Lyst rules_pending) { LystElt elt; rule_time_prod_t *rule_p = NULL; DTNMP_DEBUG_ENTRY("rda_scan_rules","(0x%#llx)", (unsigned long)rules_pending); /* Step 0: Start with a fresh list for pending rules */ lyst_clear(rules_pending); /* * Step 1: Walk through each defined rule and see if it should be * included in the current evaluation scan. */ for (elt = lyst_first(gAgentVDB.rules); elt; elt = lyst_next(elt)) { /* Step 1.1: Grab the next rule...*/ if((rule_p = (rule_time_prod_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("rda_scan_rules","Found NULL rule. Exiting", NULL); DTNMP_DEBUG_EXIT("rda_scan_rules","->-1.", NULL); return -1; } /* Step 1.2: Determine if this rule is ready for possible evaluation. */ if(rule_p->countdown_ticks == 0) { /* * Step 1.2.1: Determine if this rule has been evaluated more than * its maximum number of evaluations */ if((rule_p->desc.num_evals > 0) || (rule_p->desc.num_evals == DTNMP_RULE_EXEC_ALWAYS)) { /* Step 1.2.2: If ready, add rule to list of rules pending * evaluation in this current tick. */ lyst_insert_first(rules_pending, rule_p); DTNMP_DEBUG_INFO("rda_scan_rules","Added rule to evaluate list.", NULL); } } else { /* Step 1.2.2: If not ready, note that another tick has elapsed. */ rule_p->countdown_ticks--; } } DTNMP_DEBUG_EXIT("rda_scan_rules","->0.", NULL); return 0; } /****************************************************************************** * * \par Function Name: rda_scan_ctrls * * \par Purpose: Walks the list of ctrls defined by this agent, determines * which ctrls are to be executed, and updates housekeeping * information for each ctrl. * * \retval int - 0 : Success * -1 : Failure * * \param[in,out] exec_defs - List of ctrls that should be executed during * this execution period. * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/21/11 E. Birrane Initial implementation, *****************************************************************************/ int rda_scan_ctrls(Lyst exec_defs) { LystElt elt; ctrl_exec_t *ctrl_p = NULL; DTNMP_DEBUG_ENTRY("rda_scan_ctrls","(0x%#llx)", (unsigned long)exec_defs); /* * Step 1: Walk through each defined ctrl and see if it should be included * in the current evaluation scan. */ for (elt = lyst_first(exec_defs); elt; elt = lyst_next(elt)) { /* Step 1.1: Grab the next ctrl...*/ if((ctrl_p = (ctrl_exec_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("rda_scan_ctrls","Found NULL ctrl. Exiting", NULL); DTNMP_DEBUG_EXIT("rda_scan_ctrls","->-1.", NULL); return -1; } /* Step 1.2: Determine if this rule is ready for possible evaluation. */ if(ctrl_p->desc.state == CONTROL_ACTIVE) { /* Step 1.3: If the control is ready to execute, run it. */ if(ctrl_p->countdown_ticks <= 0) { lcc_run_ctrl(ctrl_p); /* Step 1.3.1: controls disable after they fire.*/ ctrl_p->desc.state = CONTROL_INACTIVE; } /* Step 1.4: If the control is not ready, note a tick elapsed. */ else { ctrl_p->countdown_ticks--; } } } DTNMP_DEBUG_EXIT("rda_scan_ctrls","->0.", NULL); return 0; } /****************************************************************************** * * \par Function Name: rda_clean_ctrls * * \par Purpose: Walks the list of ctrls defined by this agent, determines * which ctrls are to be removed based on active status, and * forgets them from the database. * * \retval int - 0 : Success * -1 : Failure * * \param[in,out] exec_defs - List of ctrls * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/22/13 E. Birrane Initial implementation, *****************************************************************************/ int rda_clean_ctrls(Lyst exec_defs) { LystElt elt; LystElt del_elt; ctrl_exec_t *ctrl_p = NULL; DTNMP_DEBUG_ENTRY("rda_clean_ctrls","(0x%#llx)", (unsigned long)exec_defs); /* * Step 1: Walk through each defined ctrl and see if it should be included * in the current evaluation scan. */ for (elt = lyst_first(exec_defs); elt; elt = lyst_next(elt)) { /* Step 1.1: Grab the next ctrl...*/ if((ctrl_p = (ctrl_exec_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("rda_clean_ctrls","Found NULL ctrl. Exiting", NULL); DTNMP_DEBUG_EXIT("rda_clean_ctrls","->-1.", NULL); return -1; } /* Step 1.2: Determine if this rule should be removed. */ if(ctrl_p->desc.state != CONTROL_ACTIVE) { /* Step 1.2.1: Remove control from the memory list. */ del_elt = elt; elt = lyst_prev(elt); lyst_delete(del_elt); /* Step 1.2.2: Remove control from the persistent store. */ db_forget(&(ctrl_p->desc.itemObj), &(ctrl_p->desc.descObj), gAgentDB.ctrls); /* Step 1.2.3: Release the control object. */ ctrl_release_exec(ctrl_p); } } DTNMP_DEBUG_EXIT("rda_clean_ctrls","->0.", NULL); return 0; } /****************************************************************************** * * \par Function Name: rda_build_report_entry * * \par Purpose: Create a report entry containing data for a given report MID * and filled from the agent Local Data Collector. * * \return NULL - Error * !NULL - Constructed report. * * \param[in] mid - The MID identifying the report to populate. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/21/11 E. Birrane Initial implementation, *****************************************************************************/ rpt_data_entry_t *rda_build_report_entry(mid_t *mid) { rpt_data_entry_t *entry = NULL; int result = 0; DTNMP_DEBUG_ENTRY("rda_build_report_entry","(0x%x)", (unsigned long) mid); /* Step 1: Make sure we have an entry structure to populate. */ if((entry = (rpt_data_entry_t *) MTAKE(sizeof(rpt_data_entry_t))) == NULL) { DTNMP_DEBUG_ERR("rda_build_report_entry","Can't allocate %d bytes.", sizeof(rpt_data_entry_t)); DTNMP_DEBUG_EXIT("rda_build_report_entry","->NULL.", NULL); return NULL; } /* Step 2: Fill the report with data. */ if(ldc_fill_report_data(mid,entry) == -1) { DTNMP_DEBUG_ERR("rda_build_report_entry","Can't fill report.",NULL); rpt_release_data_entry(entry); DTNMP_DEBUG_EXIT("rda_build_report_entry","->NULL.", NULL); return NULL; } DTNMP_DEBUG_EXIT("rda_build_report_entry","->0x%x", (unsigned long) entry); return entry; } /* * Returns # rules processed. */ /****************************************************************************** * * \par Function Name: rda_eval_rule * * \par Purpose: Generate a data report by evaluating a time-based production * rule. * * \return -1 - Error * >= 0 - # rules processed. * * \param[in] rule_p - The MID identifying the report to populate. * \param[out] report_p - The constructed report. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/21/11 E. Birrane Initial implementation, *****************************************************************************/ int rda_eval_rule(rule_time_prod_t *rule_p, rpt_data_t *report_p) { rpt_data_entry_t *entry = NULL; LystElt elt; mid_t *cur_mid = NULL; int result = 0; Sdnv tmp; DTNMP_DEBUG_ENTRY("rda_eval_rule","(0x%#llx 0x%#llx)", (unsigned long) rule_p, (unsigned long) report_p); /* Step 0: Sanity check.*/ if((rule_p == NULL) || (report_p == NULL)) { DTNMP_DEBUG_ERR("rda_eval_rule","Bad parms.", NULL); return -1; } /* Step 1: Update statistics. */ gAgentInstr.num_time_rules_run++; /* Step 2: For each MID listed in the evaluating report...*/ for (elt = lyst_first(rule_p->mids); elt; elt = lyst_next(elt)) { if((cur_mid = (mid_t*) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("rda_eval_rule","Bad Rule MID.", NULL); DTNMP_DEBUG_EXIT("rda_eval_rule","->-1", NULL); return -1; } /* Step 2.1: Construct The data entry for this MID. */ if((entry = rda_build_report_entry(cur_mid)) == NULL) { DTNMP_DEBUG_ERR("rda_eval_rule","Can't build report entry.", NULL); DTNMP_DEBUG_EXIT("rda_eval_rule","->-1", NULL); return -1; } /* Step 2.2: Add new entry to the report. */ lyst_insert_last(report_p->reports,entry); result++; } DTNMP_DEBUG_EXIT("rda_eval_rule","-> %d", result); return result; } /****************************************************************************** * * \par Function Name: rda_eval_pending_rules * * \par Purpose: Walks the list of rules flagged for evaluation and evaluates * them, taking the appropriate action for each rule. * * \retval int - 0 : Success * -1 : Failure * * \param[in,out] rules_pending - List of rules that should be executed during * this execution period. * * \param[in,out] built_reports - List of reports being generted by the rda. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/21/11 E. Birrane Initial implementation, *****************************************************************************/ int rda_eval_pending_rules(Lyst rules_pending, Lyst built_reports) { LystElt pending_elt; rule_time_prod_t *rule_p = NULL; DTNMP_DEBUG_ENTRY("rda_eval_pending_rules","(0x%x,0x%x)", (unsigned long) rules_pending, (unsigned long) built_reports); DTNMP_DEBUG_INFO("rda_eval_pending_rules","Preparing to eval%d rules.", lyst_length(rules_pending)); for (pending_elt = lyst_first(rules_pending); pending_elt; pending_elt = lyst_next(pending_elt)) { /* Grab the next rule...*/ if((rule_p = (rule_time_prod_t*) lyst_data(pending_elt)) == NULL) { DTNMP_DEBUG_ERR("rda_eval_pending_rules", "Cannot find pending rule from elt 0x%x.", pending_elt); DTNMP_DEBUG_EXIT("rda_eval_pending_rules","-> -1.", NULL); return -1; } /* Evaluate the rule */ rpt_data_t *rpt = rda_find_report(built_reports, rule_p->desc.sender.name); rda_eval_rule(rule_p, rpt); /* Note that the rule has been evaluated */ if(rule_p->desc.num_evals > 0) { DTNMP_DEBUG_INFO("rda_eval_pending_rules", "Decrementing rule eval count from %d.", rule_p->desc.num_evals); rule_p->desc.num_evals--; } } DTNMP_DEBUG_EXIT("rda_eval_pending_rules","-> 0", NULL); return 0; } /****************************************************************************** * * \par Function Name: rda_send_reports * * \par Purpose: For each report constructed during this evaluation period, * create a message and send it. * * \retval int - 0 : Success * -1 : Failure * * \param[in,out] built_reports - List of reports generated by the rda. * * \par Notes: * - When we construct the reports, we build one compound report * per recipient. By the time we get to this function, we should have * one report per recipient, so making one message per report should * not result in multiple messages to the same recipient. * * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/21/11 E. Birrane Initial implementation, *****************************************************************************/ int rda_send_reports(Lyst built_reports) { LystElt report_elt; rpt_data_t *report = NULL; uint8_t *raw_report = NULL; uint32_t raw_report_len = 0; DTNMP_DEBUG_ENTRY("rda_send_reports","(0x%#llx)", (unsigned long) built_reports); DTNMP_DEBUG_INFO("rda_send_reports","Preparing to send %d reports.", lyst_length(built_reports)); /* Step 1: For each report that has been built... */ for (report_elt = lyst_first(built_reports); report_elt; report_elt = lyst_next(report_elt)) { /* * Step 1.1: Grab the report. Bail if the report is bad. It is better to * send no reports than to send potentially garbled reports. If the * report here is NULL, something has clearly gone wrong on the system. */ if((report = (rpt_data_t*) lyst_data(report_elt)) == NULL) { DTNMP_DEBUG_ERR("rda_send_reports","Can't find report from elt %x.", report_elt); DTNMP_DEBUG_EXIT("rda_send_reports","->-1.", NULL); return -1; } /* Step 1.2: Construct a message for the report. */ pdu_msg_t *pdu_msg = NULL; pdu_group_t *pdu_group = NULL; /* Step 1.3: Serialize the payload. */ if((raw_report = rpt_serialize_data(report, &raw_report_len)) == NULL) { DTNMP_DEBUG_ERR("rda_send_reports","Can't serialize report.",NULL); DTNMP_DEBUG_EXIT("rda_send_reports","->-1.", NULL); return -1; } /* Step 1.4: Construct the containers. */ if((pdu_msg = pdu_create_msg(MSG_TYPE_RPT_DATA_RPT, raw_report, raw_report_len, NULL)) == NULL) { DTNMP_DEBUG_ERR("rda_send_reports","Can't serialize report.",NULL); MRELEASE(raw_report); DTNMP_DEBUG_EXIT("rda_send_reports","->-1.", NULL); return -1; } if((pdu_group = pdu_create_group(pdu_msg)) == NULL) { DTNMP_DEBUG_ERR("rda_send_reports","Can't serialize report.",NULL); /* This will also release the associated raw_report which was * shallow-copied into the message. */ pdu_release_msg(pdu_msg); DTNMP_DEBUG_EXIT("rda_send_reports","->-1.", NULL); return -1; } /* Step 1.5: Send the message. */ iif_send(&ion_ptr, pdu_group, report->recipient.name); /* * Step 1.6: This will also release the raw_report, which is * shallow-copied by the call to pdu_create_msg. */ pdu_release_group(pdu_group); /* Step 1.7: Update statistics. */ gAgentInstr.num_sent_rpts++; } DTNMP_DEBUG_EXIT("rda_send_reports","->0", NULL); return 0; } /****************************************************************************** * * \par Function Name: rda_eval_cleanup * * \par Purpose: Clean up lists and associated structures after an * evaluation period. * * \retval int - 0 : Success * -1 : Failure * * \param[in,out] rules_pending - The list of rules that were pending for * evaluation during this period. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/21/11 E. Birrane Initial implementation, *****************************************************************************/ int rda_eval_cleanup(Lyst rules_pending) { LystElt pending_elt; rule_time_prod_t *rule_p = NULL; DTNMP_DEBUG_ENTRY("rda_eval_cleanup","(0x%#llx)", rules_pending); /* Step 1: For each pending rule...*/ for (pending_elt = lyst_first(rules_pending); pending_elt; pending_elt = lyst_next(pending_elt)) { /* * Step 1.1: Grab the next rule. If it is NULL, we stop processing * as the system is in a potentially unknown state. */ if((rule_p = (rule_time_prod_t*) lyst_data(pending_elt)) == NULL) { DTNMP_DEBUG_ERR("rda_eval_cleanup","Can't find pending rule from elt %x.", pending_elt); DTNMP_DEBUG_EXIT("rda_eval_cleanup","-> -1", NULL); return -1; } /* Step 1.2: If the rule should no longer execute, delete it */ if(rule_p->desc.num_evals == 0) { DTNMP_DEBUG_INFO("rda_eval_cleanup","Removing expired rule.", NULL); /* Step 1.2.1: Find and remove the rule in the memory list. */ LystElt tmp_elt; LystElt del_elt; for(tmp_elt = lyst_first(gAgentVDB.rules); tmp_elt; tmp_elt = lyst_next(tmp_elt)) { rule_time_prod_t *tmp_rule = (rule_time_prod_t*) lyst_data(tmp_elt); if(tmp_rule == rule_p) { del_elt = tmp_elt; tmp_elt = lyst_prev(tmp_elt); lyst_delete(del_elt); } } /* Step 1.2.2: Remove the rule from the SDR storage.. */ db_forget(&(rule_p->desc.itemObj), &(rule_p->desc.descObj), gAgentDB.rules); /* Step 1.2.3: Release the rule. */ rule_release_time_prod_entry(rule_p); rule_p = NULL; /* Step 1.2.4: Correct counters. */ gAgentInstr.num_time_rules--; } /* Step 1.3: If the rule should run again, reset its timer. */ else { rule_p->countdown_ticks = rule_p->desc.interval_ticks; /* Step 1.3.1: Re-persist the rule to update its status in the SDR. */ agent_db_rule_persist(rule_p); } } DTNMP_DEBUG_EXIT("rda_eval_cleanup","->0", NULL); return 0; } /****************************************************************************** * * \par Function Name: rda_thread * * \par Purpose: "Main" function for the remote data aggregator. This thread * performs the following functions: * 1) Collect set of rules that are to be processed * 2) Process the rules (data collection, cmd execution) * 3) Update statistics and capture outgoing reports * 4) Perform rule housekeeping/cleanup. * * \retval void * - pthread_exit(NULL). * * \param[in,out] threadId The thread id for the RDA thread. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 09/06/11 M. Reid Initial Implementation * 10/21/11 E. Birrane Code comments and functional updates. *****************************************************************************/ void* rda_thread(void* threadId) { struct timeval start_time; vast delta = 0; Lyst rules_pending; Lyst built_reports; DTNMP_DEBUG_ENTRY("rda_thread","(0x%x)", threadId); rules_pending = lyst_create(); built_reports = lyst_create(); DTNMP_DEBUG_INFO("rda_thread","Running Remote Data Aggregator Thread.", NULL); /* While the DTNMP Agent is running...*/ while(g_running) { getCurrentTime(&start_time); DTNMP_DEBUG_INFO("rda_thread","Processing %u ctrls.", (unsigned long) lyst_length(gAgentVDB.rules)); lockResource(&(gAgentVDB.ctrls_mutex)); if(rda_scan_ctrls(gAgentVDB.ctrls) == -1) { DTNMP_DEBUG_ERR("rda_thread","Problem scanning ctrls.", NULL); pthread_exit(NULL); } /* For now, remove/forget inactive controls. */ /* \todo: Update this later to keep them in storage for re-enable. */ rda_clean_ctrls(gAgentVDB.ctrls); unlockResource(&(gAgentVDB.ctrls_mutex)); DTNMP_DEBUG_INFO("rda_thread","Processing %u rules.", (unsigned long) lyst_length(gAgentVDB.rules)); /* Lock the rule list while we are scanning and processinf rules */ lockResource(&(gAgentVDB.rules_mutex)); /* Step 1: Collect set of rules to be processed */ if(rda_scan_rules(rules_pending) == -1) { DTNMP_DEBUG_ERR("rda_thread","Problem scanning rule list. Exiting.", NULL); rda_cleanup(rules_pending, built_reports); pthread_exit(NULL); } /* Step 2: Evaluate each rule. */ if(rda_eval_pending_rules(rules_pending, built_reports) == -1) { DTNMP_DEBUG_ERR("rda_thread","Problem evaluating rules. Exiting.", NULL); rda_cleanup(rules_pending, built_reports); pthread_exit(NULL); } /* Step 3: Send out any built reports. */ if(rda_send_reports(built_reports) == -1) { DTNMP_DEBUG_ERR("rda_thread","Problem sending built reports. Exiting.", NULL); rda_cleanup(rules_pending, built_reports); pthread_exit(NULL); } /* Step 4: Perform housekeeping for all evaluated rules. */ if(rda_eval_cleanup(rules_pending) == -1) { DTNMP_DEBUG_ERR("rda_thread","Problem cleaning up after rules eval. Exiting.", NULL); rda_cleanup(rules_pending, built_reports); pthread_exit(NULL); } rpt_clear_lyst(&built_reports, NULL, 0); unlockResource(&(gAgentVDB.rules_mutex)); delta = utils_time_cur_delta(&start_time); // Sleep for 1 second (10^6 microsec) subtracting the processing time. if((delta < 1000000) && (delta > 0)) { microsnooze((unsigned int)(1000000 - delta)); } } // end while rda_cleanup(rules_pending, built_reports); DTNMP_DEBUG_ALWAYS("rda_thread","Shutting Down Agent Data Aggregator Thread.",NULL); DTNMP_DEBUG_EXIT("rda_thread","->NULL.", NULL); pthread_exit(NULL); } ion-3.2.0~dfsg1.orig/nm/agent/adm_ltp_priv.c0000644000175000017500000011100612260400056017221 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ #ifdef _HAVE_LTP_ADM_ /***************************************************************************** ** ** File Name: adm_ltp_priv.c ** ** Description: This implements the private aspects of a LTP ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/16/13 E. Birrane Initial Implementation *****************************************************************************/ #include "platform.h" #include "ion.h" #include "shared/utils/utils.h" #include "shared/adm/adm_ltp.h" #include "adm_ltp_priv.h" void agent_adm_init_ltp() { uint8_t mid_str[ADM_MID_ALLOC]; adm_build_mid_str(0x00, ADM_LTP_NODE_NN, ADM_LTP_NODE_NN_LEN, 0, mid_str); adm_add_datadef_collect(mid_str, ltp_get_node_resources_all); adm_build_mid_str(0x00, ADM_LTP_NODE_NN, ADM_LTP_NODE_NN_LEN, 1, mid_str); adm_add_datadef_collect(mid_str, ltp_get_heap_bytes_reserved); adm_build_mid_str(0x00, ADM_LTP_NODE_NN, ADM_LTP_NODE_NN_LEN, 2, mid_str); adm_add_datadef_collect(mid_str, ltp_get_heap_bytes_used); adm_build_mid_str(0x00, ADM_LTP_NODE_NN, ADM_LTP_NODE_NN_LEN, 3, mid_str); adm_add_datadef_collect(mid_str, ltp_get_engines); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 0, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_all); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 1, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_num); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 2, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_exp_sess); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 3, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_cur_out_seg); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 4, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_cur_imp_sess); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 5, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_cur_in_seg); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 6, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_last_reset_time); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 7, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_seg_q_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 8, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_seg_q_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 9, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_seg_pop_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 10, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_seg_pop_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 11, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_ckp_xmit_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 12, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_pos_ack_rcv_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 13, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_neg_ack_rcv_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 14, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_canc_rcv_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 15, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_ckp_rexmt_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 16, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_canc_xmit_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 17, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_out_compl_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 18, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_rcv_red_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 19, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_rcv_red_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 20, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_rcv_grn_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 21, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_rcv_grn_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 22, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_rdndt_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 23, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_rdndt_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 24, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_mal_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 25, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_mal_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 26, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_unk_snd_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 27, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_unk_snd_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 28, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_unk_cli_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 29, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_unk_cli_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 30, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_stray_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 31, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_stray_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 32, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_miscol_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 33, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_miscol_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 34, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_clsd_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 35, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_seg_clsd_byte); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 36, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_ckp_rcv_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 37, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_pos_ack_xmit_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 38, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_neg_ack_xmit_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 39, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_canc_xmit_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 40, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_ack_rexmt_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 41, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_canc_rcv_cnt); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 42, mid_str); adm_add_datadef_collect(mid_str, ltp_get_eng_in_compl_cnt); adm_build_mid_str(0x41, ADM_LTP_CTRL_NN, ADM_LTP_CTRL_NN_LEN, 0, mid_str); adm_add_ctrl_run(mid_str, ltp_engine_reset); } /* Get Functions */ expr_result_t ltp_get_node_resources_all(Lyst params) { unsigned long bytes_reserved = 0; unsigned long bytes_used = 0; expr_result_t result; result.type = EXPR_TYPE_BLOB; ltpnm_resources(&bytes_reserved, &bytes_used); result.length = sizeof(unsigned long) * 2; result.value = (uint8_t*) MTAKE(result.length); memcpy(result.value, &bytes_reserved, sizeof(bytes_reserved)); memcpy(&(result.value[sizeof(bytes_reserved)]), &bytes_used, sizeof(bytes_used)); return result; } expr_result_t ltp_get_heap_bytes_reserved(Lyst params) { unsigned long bytes_reserved = 0; unsigned long bytes_used = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; ltpnm_resources(&bytes_reserved, &bytes_used); result.length = sizeof(unsigned long); result.value = (uint8_t*) MTAKE(result.length); memcpy(result.value, &bytes_reserved, sizeof(bytes_reserved)); return result; } expr_result_t ltp_get_heap_bytes_used(Lyst params) { unsigned long bytes_reserved = 0; unsigned long bytes_used = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; ltpnm_resources(&bytes_reserved, &bytes_used); result.length = sizeof(unsigned long); result.value = (uint8_t*) MTAKE(result.length); memcpy(result.value, &bytes_used, sizeof(bytes_used)); return result; } expr_result_t ltp_get_engines(Lyst params) { unsigned int ids[32]; uint8_t *cursor = NULL; int num = 0; unsigned long val = 0; Sdnv num_sdnv; expr_result_t result; result.type = EXPR_TYPE_BLOB; ltpnm_spanEngineIds_get(ids, &num); if(num > 32) { fprintf(stderr,"We do not support more than 32 engines. Aborting.\n"); exit(1); } encodeSdnv(&num_sdnv, num); result.length = num_sdnv.length + /* NUM as SDNV length */ (num * sizeof(unsigned long)); result.value = (uint8_t *) MTAKE(result.length); cursor = result.value; memcpy(cursor,num_sdnv.text, num_sdnv.length); cursor += num_sdnv.length; for(int i = 0; i < num; i++) { val = ids[i]; memcpy(cursor,&val, sizeof(val)); cursor += sizeof(val); } return result; } expr_result_t ltp_get_eng_all(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { result.value = (uint8_t*) MTAKE(sizeof(span)); memcpy(result.value, &span, sizeof(span)); result.length = sizeof(span); } return result; } expr_result_t ltp_get_eng_num(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.remoteEngineNbr; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_exp_sess(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.currentExportSessions; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_cur_out_seg(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.currentOutboundSegments; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_cur_imp_sess(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.currentImportSessions; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_cur_in_seg(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.currentInboundSegments; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_last_reset_time(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.lastResetTime; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_seg_q_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputSegQueuedCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_seg_q_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputSegQueuedBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_seg_pop_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputSegPoppedCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_seg_pop_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputSegPoppedBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_ckp_xmit_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputCkptXmitCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_pos_ack_rcv_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputPosAckRecvCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_neg_ack_rcv_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputNegAckRecvCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_canc_rcv_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputCancelRecvCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_ckp_rexmt_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputCkptReXmitCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_canc_xmit_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputCancelXmitCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_out_compl_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.outputCompleteCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_rcv_red_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegRecvRedCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_rcv_red_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegRecvRedBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_rcv_grn_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; result.length = 0; result.value = NULL; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegRecvGreenCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_rcv_grn_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegRecvGreenBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_rdndt_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegRedundantCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_rdndt_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegRedundantBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_mal_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegMalformedCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_mal_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegMalformedBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_unk_snd_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegUnkSenderCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_unk_snd_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegUnkSenderBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_unk_cli_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegUnkClientCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_unk_cli_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegUnkClientBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_stray_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegStrayCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_stray_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegStrayBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_miscol_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegMiscolorCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_miscol_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegMiscolorBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_clsd_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegClosedCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_seg_clsd_byte(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputSegClosedBytes; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_ckp_rcv_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputCkptRecvCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_pos_ack_xmit_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputPosAckXmitCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_neg_ack_xmit_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputNegAckXmitCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_canc_xmit_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputCancelXmitCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_ack_rexmt_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputAckReXmitCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_canc_rcv_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputCancelRecvCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } expr_result_t ltp_get_eng_in_compl_cnt(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; unsigned int engineId = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; /* \todo: Check for NULL entry here. */ NmltpSpan span; int success = 0; memcpy(&val, entry->value, sizeof(val)); engineId = val; ltpnm_span_get(engineId, &span, &success); if(success != 0) { val = span.inputCompleteCount; result.value = adm_copy_integer((uint8_t*)&val, sizeof(val), &(result.length)); } return result; } /* Controls */ uint32_t ltp_engine_reset(Lyst params) { return 0; } #endif /* _HAVE_LTP_ADM_*/ ion-3.2.0~dfsg1.orig/nm/agent/adm_agent_priv.h0000644000175000017500000000537612260400056017541 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: adm_agent_priv.h ** ** Description: This implements the private aspects of a DTNMP agent ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/04/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef ADM_AGENT_PRIV_H_ #define ADM_AGENT_PRIV_H_ #include "shared/adm/adm_agent.h" #include "shared/adm/adm_bp.h" #include "shared/adm/adm_ion.h" #include "shared/adm/adm_ltp.h" #include "shared/primitives/instr.h" #include "shared/utils/expr.h" void agent_adm_init_agent(); /****************************************************************************** * Retrieval Functions * ******************************************************************************/ /* Retrieval Functions */ /* DTNMP AGENT */ /* Collect Functions */ expr_result_t agent_get_all(Lyst params); expr_result_t agent_get_num_rpt_defs(Lyst params); expr_result_t agent_get_num_sent_rpts(Lyst params); expr_result_t agent_get_num_time_rules(Lyst params); expr_result_t agent_get_num_time_rules_run(Lyst params); expr_result_t agent_get_num_prod_rules(Lyst params); expr_result_t agent_get_num_prod_rules_run(Lyst params); expr_result_t agent_get_num_consts(Lyst params); expr_result_t agent_get_num_data_defs(Lyst params); expr_result_t agent_get_num_macros(Lyst params); expr_result_t agent_get_num_macros_run(Lyst params); expr_result_t agent_get_num_ctrls(Lyst params); expr_result_t agent_get_num_ctrls_run(Lyst params); /* Control Functions */ uint32_t agent_list_rpt_defs(Lyst params); uint32_t agent_list_time_rules(Lyst params); uint32_t agent_list_prod_rules(Lyst params); uint32_t agent_list_consts(Lyst params); uint32_t agent_list_data_defs(Lyst params); uint32_t agent_list_macros(Lyst params); uint32_t agent_list_ctrls(Lyst params); uint32_t agent_remove_item(Lyst params); #endif // ADM_AGENT_PRIV_H_ ion-3.2.0~dfsg1.orig/nm/agent/ldc.h0000644000175000017500000000306212260400056015312 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: ldc.h ** ** Description: This implements the NM Agent Local Data Collector (LDC). ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/22/11 E. Birrane Code comments and functional updates. ** 01/10/13 E. Birrane Update to latest version of DTNMP. Cleanup. *****************************************************************************/ #ifndef _LDC_H_ #define _LDC_H_ #include "shared/adm/adm.h" #include "shared/msg/msg_reports.h" #include "shared/msg/msg_def.h" int ldc_fill_report_data(mid_t *id, rpt_data_entry_t *entry); int ldc_fill_atomic(adm_datadef_t *adm_def, mid_t *id, rpt_data_entry_t *rpt); int ldc_fill_custom(def_gen_t *rpt_def, rpt_data_entry_t *rpt); #endif // _LDC_H_ ion-3.2.0~dfsg1.orig/nm/agent/Makefile0000644000175000017500000000103112260400056016031 0ustar l3onl3onSOURCES = ../shared/adm/*.c ../shared/msg/*.c ../shared/utils/*.c ../shared/primitives/*.c ./*.c IONDIR = /home/apluser/ion/ion-2013-08-02/ion-open-source/ OPTS = -Wno-write-strings -g all: g++ ${OPTS} \ -I. -I.. \ -I${IONDIR}/ici/include \ -I${IONDIR}/ltp/include \ -I${IONDIR}/ltp/library \ -I${IONDIR}/bp/include \ -I${IONDIR}/bp/library \ -I${IONDIR}/ici/library \ -I/usr/local/include \ -L${IONDIR}/ \ -L/usr/local/lib \ -lbp -lici -lltp \ -DMAXPATHLEN=2048 \ -c ${SOURCES} g++ -o nm_agent *.o -lltp -lbp -lici ion-3.2.0~dfsg1.orig/nm/agent/ldc.c0000644000175000017500000002532212260400056015310 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: ldc.c ** ** Description: This implements the NM Agent Local Data Collector (LDC). ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/22/11 E. Birrane Code comments and functional updates. ** 01/10/13 E. Birrane Update to latest version of DTNMP. Cleanup. *****************************************************************************/ #include "shared/adm/adm.h" #include "shared/primitives/mid.h" #include "shared/msg/msg_reports.h" #include "shared/msg/msg_def.h" #include "nmagent.h" #include "ldc.h" /****************************************************************************** * * \par Function Name: ldc_fill_report_data * * \par Populate the contents of a single report data entry. * * \param[in] id The ID of the generated report. * \param[out] entry The filled-in report. * * \par Notes: * - We assume that the passed-in report is pre-allocated. * - We do NOT fill in the report ID. This is because we call this function * recursively on nested report definitions. * * \return 0 - Success * !0 - Failure * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/11 E. Birrane Initial implementation. * 08/18/13 E. Birrane Added nesting levels to limit recursion. *****************************************************************************/ int ldc_fill_report_data(mid_t *id, rpt_data_entry_t *entry) { int result = 0; adm_datadef_t *adm_def = NULL; def_gen_t *rpt_def = NULL; char *msg = NULL; DTNMP_DEBUG_ENTRY("ldc_fill_report_data","(0x%x,0x%x)", (unsigned long) id, (unsigned long) entry); /* Step 0: Sanity Check */ if((id == NULL) || (entry == NULL)) { DTNMP_DEBUG_ERR("ldc_fill_report_data","Bad Args.",NULL); DTNMP_DEBUG_EXIT("ldc_fill_report_data","-> -1",NULL); return -1; } msg = mid_to_string(id); DTNMP_DEBUG_INFO("ldc_fill_report_data","Gathering report data for MID: %s", msg); /* Step 1: Search for this MID... */ /* Step 1.1: If this is an atomic data definition...*/ if((adm_def = adm_find_datadef(id)) != NULL) { DTNMP_DEBUG_INFO("ldc_fill_report_data","Filling pre-defined.", NULL); result = ldc_fill_atomic(adm_def,id,entry); } /* Step 1.2: If this is a data report...*/ else if((rpt_def = def_find_by_id(gAgentVDB.reports, &(gAgentVDB.reports_mutex), id)) != NULL) { DTNMP_DEBUG_INFO("ldc_fill_report_data","Filling custom.", NULL); result = ldc_fill_custom(rpt_def, entry); /* \todo: Do we need this? */ entry->id = mid_copy(id); } /* Step 1.3: If this is an unknown data MID. */ else { DTNMP_DEBUG_ERR("ldc_fill_report_data","Could not find def for MID %s", msg); result = -1; } MRELEASE(msg); DTNMP_DEBUG_EXIT("ldc_fill_report_data","-> %d", result); return result; } /****************************************************************************** * * \par Function Name: ldc_fill_custom * * \par Populate a data entry from a custom definition. This is somewhat * tricky because a custom definition may, itself, contain other * custom definitions. * * \param[in] rpt_def The custom definition * \param[out] rpt The filled-in report. * * \par Notes: * - We impose a maximum nesting level of 5. A custom definition may * contain no more than 5 other custom definitions. * * \return 0 - Success * !0 - Failure * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/11 E. Birrane Initial implementation. * 08/18/13 E. Birrane Added nesting levels to limit recursion. *****************************************************************************/ int ldc_fill_custom(def_gen_t *rpt_def, rpt_data_entry_t *rpt) { Lyst entries; uint64_t total_size = 0; uint64_t idx = 0; LystElt elt; mid_t *cur_mid = NULL; rpt_data_entry_t *temp = NULL; int result = 0; static int nesting = 0; DTNMP_DEBUG_ENTRY("ldc_fill_custom","(0x%x,0x%x)", (unsigned long) rpt_def, (unsigned long) rpt); nesting++; /* Step 0: Sanity Checks. */ if((rpt_def == NULL) || (rpt == NULL)) { DTNMP_DEBUG_ERR("ldc_fill_custom","Bad Args.", NULL); DTNMP_DEBUG_EXIT("ldc_fill_custom","-->-1", NULL); nesting--; return -1; } /* Step 1: Check for too much recursion. */ if(nesting > 5) { DTNMP_DEBUG_ERR("ldc_fill_custom","Too many nesting levels %d.", nesting); DTNMP_DEBUG_EXIT("ldc_fill_custom","-->-1", NULL); nesting--; return -1; } /* * Step 2: Allocate a lyst to hold individual reports from each MID * in this custom definition. */ if((entries = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("ldc_fill_custom","Can't allocate lyst.", NULL); DTNMP_DEBUG_EXIT("ldc_fill_custom","-->-1", NULL); nesting--; return -1; } /* * Step 3: For each MID in the definition build the data for the * report and store the result in a temporary area. */ for (elt = lyst_first(rpt_def->contents); elt; elt = lyst_next(elt)) { /* Step 3.1 Grab the mid */ if((cur_mid = (mid_t*)lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("ldc_fill_custom","Can't get mid from lyst!", NULL); result = -1; break; } /* Step 3.2: Grab the report for this MID. */ else { /* Step 3.2.1: Allocate space for this report. */ if((temp = (rpt_data_entry_t*)MTAKE(sizeof(rpt_data_entry_t))) == NULL) { DTNMP_DEBUG_ERR("ldc_fill_custom","Can't allocate %d bytes!", sizeof(rpt_data_entry_t)); result = -1; break; } /* Step 3.2.2: Populate the report. */ if(ldc_fill_report_data(cur_mid,temp) != 0) { DTNMP_DEBUG_ERR("ldc_fill_custom","Can't get mid from lyst!", NULL); rpt_release_data_entry(temp); result = -1; break; } /* Step 3.2.3: Add this report to the report list. */ lyst_insert_last(entries, temp); /* Step 3.2.4: Remember the total size of this report. */ total_size += temp->size; } } /* Step 4: Allocate total space for the resultant report. */ rpt->size = total_size; if((rpt->contents = (uint8_t *) MTAKE(rpt->size)) == NULL) { DTNMP_DEBUG_ERR("ldc_fill_custom","Can't allocate %d bytes!", rpt->size); rpt->size = 0; result = -1; } /* * Step 5: If any of the report generation failed, or the allocation of the * consolidated report from step 4 failed, clean up. */ if(result == -1) { /* Step 4.1: Walk the list and delete the entries. */ for (elt = lyst_first(entries); elt; elt = lyst_next(elt)) { temp = (rpt_data_entry_t *) lyst_data(elt); rpt_release_data_entry(temp); } lyst_destroy(entries); DTNMP_DEBUG_EXIT("ldc_fill_custom","->-1",NULL); nesting--; return -1; } /* * Step 6: Copy all the comprising reports into the single, consolidated * report. Note that we destroy the comprising reports as we go. */ for (elt = lyst_first(entries); elt; elt = lyst_next(elt)) { temp = (rpt_data_entry_t *) lyst_data(elt); /* Copy into the contents area. */ memcpy(&(rpt->contents[idx]), temp->contents, temp->size); idx += temp->size; rpt_release_data_entry(temp); } /* Step 7: Destroy the entries list. We destroyed list contents above. */ lyst_destroy(entries); nesting--; return 0; } /****************************************************************************** * * \par Function Name: ldc_fill_atomic * * \par Populate a data entry from a custom definition. * * \param[in] adm_def The atomic definition * \param[in] id Full ID (for OID parameters). * \param[out] rpt The filled-in report. * * \par Notes: * - We impose a maximum nesting level of 5. A custom definition may * contain no more than 5 other custom definitions. * * \return 0 - Success * !0 - Failure * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/11 E. Birrane Initial implementation. *****************************************************************************/ int ldc_fill_atomic(adm_datadef_t *adm_def, mid_t *id, rpt_data_entry_t *rpt) { int i = 0; char *msg = NULL; mid_t *mid = NULL; uint32_t temp = 0; DTNMP_DEBUG_ENTRY("ldc_fill_atomic","(0x%x, 0x%x)", (unsigned long) adm_def, (unsigned long) rpt); /* Step 0: Sanity Checks. */ if((adm_def == NULL) || (id == NULL) || (rpt == NULL)) { DTNMP_DEBUG_ERR("ldc_fill_atomic","Bad Args", NULL); DTNMP_DEBUG_EXIT("ldc_fill_atomic","-> -1.", NULL); return -1; } /* Step 1: Populate the report MID. */ if((rpt->id = mid_copy(id)) == NULL) { DTNMP_DEBUG_ERR("ldc_fill_atomic","Unable to copy MID.", NULL); DTNMP_DEBUG_EXIT("ldc_fill_atomic","-> -1.", NULL); return -1; } /* Step 2: Collect the information for this datum. */ expr_result_t result = adm_def->collect(id->oid->params); rpt->contents = result.value; rpt->size = result.length; /* Step 3: If there was a problem collecting information, bail. */ if((rpt->size == 0) || (rpt->contents == NULL)) { DTNMP_DEBUG_ERR("ldc_fill_atomic","Unable to collect data.", NULL); MRELEASE(rpt->id); MRELEASE(rpt->contents); DTNMP_DEBUG_EXIT("ldc_fill_atomic","-> -1.", NULL); return -1; } DTNMP_DEBUG_EXIT("ldc_fill_atomic","-> 0", NULL); return 0; } /* * \todo: Add fill computed data. */ ion-3.2.0~dfsg1.orig/nm/agent/lcc.c0000644000175000017500000001306412260400056015307 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: lcc.c ** ** Description: This implements the NM Agent Local Command and Control (LDC). ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/22/13 E. Birrane Update to latest version of DTNMP. Cleanup. *****************************************************************************/ #include "shared/adm/adm.h" #include "shared/primitives/mid.h" #include "shared/primitives/rules.h" #include "shared/primitives/instr.h" #include "nmagent.h" #include "lcc.h" /****************************************************************************** * * \par Function Name: lcc_run_ctrl_mid * * \par Run a control given the MID associated with that control. * * \param[in] id The MID identifying the control * * \par Notes: * * \return -1 - Error * !(-1) - Value returned from the run control. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/22/13 E. Birrane Initial implementation. *****************************************************************************/ int lcc_run_ctrl_mid(mid_t *id) { int result = 0; adm_ctrl_t *adm_ctrl = NULL; def_gen_t *macro_def = NULL; static int nesting = 0; char *msg = NULL; Lyst parms = NULL; nesting++; DTNMP_DEBUG_ENTRY("lcc_run_ctrl_mid","(0x%#llx)", (unsigned long) id); /* Step 0: Sanity Check */ if((id == NULL) || (id->oid == NULL)) { DTNMP_DEBUG_ERR("lcc_run_ctrl_mid","Bad Args.",NULL); DTNMP_DEBUG_EXIT("lcc_run_ctrl_mid","-> -1",NULL); nesting--; return -1; } if(nesting > 5) { DTNMP_DEBUG_ERR("lcc_run_ctrl_mid","Too many nesting levels (%d).",nesting); DTNMP_DEBUG_EXIT("lcc_run_ctrl_mid","-> -1",NULL); nesting--; return -1; } msg = mid_to_string(id); DTNMP_DEBUG_INFO("lcc_run_ctrl_mid","Running control: %s", msg); /* Step 1: See if this identifies an atomic control. */ if((adm_ctrl = adm_find_ctrl(id)) != NULL) { DTNMP_DEBUG_INFO("lcc_run_ctrl_mid","Found control.", NULL); result = adm_ctrl->run(id->oid->params); gAgentInstr.num_ctrls_run++; } /* Step 2: Otherwise, see if this identifies a pre-defined macro. */ else if((macro_def = def_find_by_id(gAgentVDB.macros, &(gAgentVDB.macros_mutex), id)) != NULL) { LystElt elt; mid_t *mid; /* * Step 2.1: This is a macro. Walk through each control running * the controls as we go. */ for(elt = lyst_first(macro_def->contents); elt; elt = lyst_next(elt)) { mid = (mid_t *)lyst_data(elt); result = lcc_run_ctrl_mid(mid); if(result != 0) { DTNMP_DEBUG_WARN("lcc_run_ctrl_mid","Running MID %s returned %d", msg, result); } } } /* Step 3: Otherwise, give up. */ else { DTNMP_DEBUG_ERR("lcc_run_ctrl_mid","Could not find control for MID %s", msg); result = -1; } MRELEASE(msg); nesting--; DTNMP_DEBUG_EXIT("lcc_run_ctrl_mid","-> %d", result); return result; } /****************************************************************************** * * \par Function Name: lcc_run_ctrl * * \par Run a control given a control execution structure. * * \param[in] ctrl_p The control execution structure. * * \par Notes: * * \return -1 - Error * !(-1) - Value returned from the run control. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/22/13 E. Birrane Initial implementation. *****************************************************************************/ int lcc_run_ctrl(ctrl_exec_t *ctrl_p) { int result = 0; char *msg = NULL; Lyst parms = NULL; LystElt elt; mid_t *cur_ctrl = NULL; char *str = NULL; DTNMP_DEBUG_ENTRY("lcc_run_ctrl","(0x%x)", (unsigned long) ctrl_p); /* Step 0: Sanity Check */ if(ctrl_p == NULL) { DTNMP_DEBUG_ERR("lcc_run_ctrl","Bad Args.",NULL); DTNMP_DEBUG_EXIT("lcc_run_ctrl","-> -1",NULL); return -1; } /* Step 1: Walk through the macro, running controls as we go. */ for (elt = lyst_first(ctrl_p->contents); elt; elt = lyst_next(elt)) { /* Step 1.1: Grab the next ctrl...*/ if((cur_ctrl = (mid_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("lcc_run_ctrl","Found NULL ctrl. Exiting", NULL); DTNMP_DEBUG_EXIT("lcc_run_ctrl","->-1.", NULL); return -1; } result = lcc_run_ctrl_mid(cur_ctrl); if(result != 0) { DTNMP_DEBUG_WARN("lcc_run_ctrl","Error running control.", NULL); } } DTNMP_DEBUG_EXIT("lcc_run_ctrl","-> %d", result); return result; } ion-3.2.0~dfsg1.orig/nm/agent/ingest.c0000644000175000017500000005177212260400056016047 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: ingest.h ** ** Description: This implements the data ingest thread to receive DTNMP msgs. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 08/31/11 V. Ramachandran Initial Implementation ** 01/10/13 E. Birrane Updates to lastest version of DTNMP spec. ** 06/27/13 E. Birrane Support persisted rules. *****************************************************************************/ #include "pthread.h" #include "platform.h" #include "nmagent.h" #include "shared/utils/nm_types.h" #include "shared/adm/adm.h" #include "shared/utils/ion_if.h" #include "shared/msg/pdu.h" #include "shared/msg/msg_admin.h" #include "shared/msg/msg_reports.h" #include "shared/msg/msg_def.h" #include "shared/msg/msg_ctrl.h" #include "shared/primitives/rules.h" #include "shared/primitives/instr.h" #include "shared/utils/utils.h" #include "ingest.h" extern eid_t manager_eid; /****************************************************************************** * * \par Function Name: rx_validate_mid_mc * * \par Determine whether a lyst contains valid, recognized MIDs. * * \param[in] mids The list of mids to validate. * \param[in] passEmpty Whether an empty list is OK (1) or not (0) * * \par Notes: * - A NULL list is always bad. * * \return 0 - Lyst failed to validate. * !0 - Valid lyst. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/10/13 E. Birrane Initial implementation. *****************************************************************************/ int rx_validate_mid_mc(Lyst mids, int passEmpty) { LystElt elt; mid_t *cur_mid = NULL; int i = 0; DTNMP_DEBUG_ENTRY("rx_validate_mid_mc","(0x%#llx, %d)", (unsigned long) mids, passEmpty); /* Step 0 : Sanity Check. */ if (mids == NULL) { DTNMP_DEBUG_ERR("rx_validate_mid_mc", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL); return 0; } /* Step 1: Walk the list of MIDs. */ for (elt = lyst_first(mids); elt; elt = lyst_next(elt)) { i++; /* Grab the next mid...*/ if((cur_mid = (mid_t*) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("rx_validate_mid_mc","Found unexpected NULL mid.", NULL); DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL); return 0; } char *mid_str = mid_to_string(cur_mid); /* Is this a valid MID? */ if(mid_sanity_check(cur_mid) == 0) { DTNMP_DEBUG_ERR("rx_validate_mid_mc","Malformed MID: %s.", mid_str); MRELEASE(mid_str); DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL); return 0; } /* Do we know this MID? */ if((adm_find_datadef(cur_mid) == NULL) && (def_find_by_id(gAgentVDB.reports, &(gAgentVDB.reports_mutex), cur_mid) == NULL)) { DTNMP_DEBUG_ERR("rx_validate_mid_mc","Unknown MID %s.", mid_str); MRELEASE(mid_str); DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL); return 0; } DTNMP_DEBUG_INFO("rx_validate_mid_mc","MID %s is recognized.", mid_str); MRELEASE(mid_str); } if((i == 0) && (passEmpty == 0)) { DTNMP_DEBUG_ERR("rx_validate_mid_mc","Empty MID list not allowed.", NULL); DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL); return 0; } DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 1", NULL); return 1; } /****************************************************************************** * * \par Function Name: rx_validate_rule * * \par Determines whether a production rule is correct. * * \param[in] rule The rule being evaluated. * * \return 0 - Bad rule. * 1 - Good rule. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/10/13 E. Birrane Initial implementation. *****************************************************************************/ int rx_validate_rule(rule_time_prod_t *rule) { int result = 1; DTNMP_DEBUG_ENTRY("rx_validate_rule","(0x%x)", (unsigned long) rule); /* Step 0: Sanity Check. */ if(rule == NULL) { DTNMP_DEBUG_ERR("rx_validate_rule","NULL rule.", NULL); DTNMP_DEBUG_EXIT("rx_validate_rule","-> 0", NULL); return 0; } /* Is the interval correct? */ if(rule->desc.interval_ticks == 0) { DTNMP_DEBUG_ERR("rx_validate_rule","Bad interval ticks: 0.", NULL); DTNMP_DEBUG_EXIT("rx_validate_rule","-> 0", NULL); return 0; } /* Do we understand the sender EID? */ if(memcmp(&(rule->desc.sender), &(manager_eid), MAX_EID_LEN) != 0) { DTNMP_DEBUG_ERR("rx_validate_rule","Unknown EID: %s.", rule->desc.sender.name); DTNMP_DEBUG_EXIT("rx_validate_rule","-> 0", NULL); return 0; } /* Is each MID valid and recognized? */ if(rx_validate_mid_mc(rule->mids, 0) == 0) { DTNMP_DEBUG_ERR("rx_validate_rule","Unknown MIDs",NULL); DTNMP_DEBUG_EXIT("rx_validate_rule","-> 0", NULL); return 0; } DTNMP_DEBUG_EXIT("rx_validate_rule","-> 1", NULL); return result; } /****************************************************************************** * * \par Function Name: rx_thread * * \par Receives and processes a DTNMP message. * * \param[in] threadId The thread identifier. * * \return NULL - Error * !NULL - Some thread thing. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/10/13 E. Birrane Initial implementation. *****************************************************************************/ void *rx_thread(void *threadId) { DTNMP_DEBUG_ENTRY("rx_thread","(0x%x)",(unsigned long) threadId); DTNMP_DEBUG_INFO("rx_thread","Receiver thread running...", NULL); uint32_t num_msgs = 0; uint8_t *buf = NULL; uint8_t *cursor = NULL; uint32_t bytes = 0; uint32_t i = 0; pdu_header_t *hdr = NULL; pdu_acl_t *acl = NULL; uint32_t size = 0; pdu_metadata_t meta; uvast val = 0; time_t group_timestamp = 0; /* * g_running controls the overall execution of threads in the * NM Agent. */ while(g_running) { /* Step 1: Receive a message from the Bundle Protocol Agent. */ buf = iif_receive(&ion_ptr, &size, &meta, NM_RECEIVE_TIMEOUT_SEC); if(buf != NULL) { DTNMP_DEBUG_INFO("rx_thread","Received buf (%x) of size %d", (unsigned long) buf, size); /* Grab # messages and timestamp for this group. */ cursor = buf; bytes = utils_grab_sdnv(cursor, size, &val); num_msgs = val; cursor += bytes; size -= bytes; bytes = utils_grab_sdnv(cursor, size, &val); group_timestamp = val; cursor += bytes; size -= bytes; DTNMP_DEBUG_INFO("rx_thread","Group had %d msgs", num_msgs); DTNMP_DEBUG_INFO("rx_thread","Group time stamp %lu", (unsigned long) group_timestamp); /* For each message in the bundle. */ for(i = 0; i < num_msgs; i++) { hdr = pdu_deserialize_hdr(cursor, size, &bytes); cursor += bytes; size -= bytes; switch (hdr->id) { case MSG_TYPE_CTRL_PERIOD_PROD: { DTNMP_DEBUG_ALWAYS("NM Agent :","Received Periodic Production Message.\n", NULL); rx_handle_time_prod(&meta, cursor,size,&bytes); } break; case MSG_TYPE_DEF_CUST_RPT: { DTNMP_DEBUG_ALWAYS("NM Agent :","Received Custom Report Definition.\n", NULL); rx_handle_rpt_def(&meta, cursor,size,&bytes); } break; case MSG_TYPE_CTRL_EXEC: { DTNMP_DEBUG_ALWAYS("NM Agent :","Received Perform Control Message.\n", NULL); rx_handle_exec(&meta, cursor,size,&bytes); } break; case MSG_TYPE_DEF_MACRO: { DTNMP_DEBUG_ALWAYS("NM Agent :","Received Macro Definition.\n", NULL); rx_handle_macro_def(&meta, cursor,size,&bytes); } break; default: { DTNMP_DEBUG_WARN("rx_thread","Received unknown type: %d.\n", hdr->type); DTNMP_DEBUG_ALWAYS("NM Agent :","Received Unsupported message of type 0x%x.\n", hdr->id); } break; } } } } DTNMP_DEBUG_ALWAYS("rx_thread","Shutting Down Agent Receive Thread.",NULL); DTNMP_DEBUG_EXIT("rx_thread","->.", NULL); pthread_exit(NULL); } /****************************************************************************** * * \par Function Name: rx_handle_rpt_def * * \par Process a received custom report definition message. This function * accepts a portion of a serialized message group, with the * understanding that the custom report definition message is at the * head of the serialized data stream. This function extracts the * current message, and returns the number of bytes consumed so that * the called may then know where the next message in the serialized * message group begins. * * \param[in] meta The metadata associated with the message. * \param[in] cursor Pointer to the start of the serialized message. * \param[in] size The size of the remaining serialized message group * \param[out] bytes_used The number of bytes consumed in processing this msg. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/10/13 E. Birrane Initial implementation. *****************************************************************************/ void rx_handle_rpt_def(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { def_gen_t* rpt_def = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("rx_handle_rpt_def","(0x%#llx, %d, 0x%#llx)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity checks. */ if((meta == NULL) || (cursor == NULL) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("rx_handle_rpt_def","Bad args.",NULL); DTNMP_DEBUG_EXIT("rx_handle_rpt_def","->.",NULL); return; } /* Step 1: Attempt to deserialize the message. */ rpt_def = def_deserialize_gen(cursor, size, &bytes); /* Step 2: If the deserialization failed, complain. */ if((rpt_def == NULL) || (bytes == 0)) { DTNMP_DEBUG_ERR("rx_handle_rpt_def","Can't deserialize.",NULL); def_release_gen(rpt_def); *bytes_used = 0; DTNMP_DEBUG_EXIT("rx_handle_rpt_def","->.",NULL); return; } /* Step 3: Otherwise, note how many bytes were consumed. */ *bytes_used = bytes; DTNMP_DEBUG_INFO("rx_handle_rpt_def","Adding new report definition.", NULL); /* Step 4: Persist this definition to our SDR. */ agent_db_report_persist(rpt_def); /* Step 5: Persist this definition to our memory lists. */ // agent_vdb_reports_init(getIonsdr()); ADD_REPORT(rpt_def); /* Step 6: Update instrumentation counters. */ gAgentInstr.num_rpt_defs++; } /****************************************************************************** * * \par Function Name: rx_handle_exec * * \par Process a received control exec message. This function * accepts a portion of a serialized message group, with the * understanding that the control exec message is at the * head of the serialized data stream. This function extracts the * current message, and returns the number of bytes consumed so that * the called may then know where the next message in the serialized * message group begins. * * \param[in] meta The metadata associated with the message. * \param[in] cursor Pointer to the start of the serialized message. * \param[in] size The size of the remaining serialized message group * \param[out] bytes_used The number of bytes consumed in processing this msg. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/10/13 E. Birrane Initial implementation. *****************************************************************************/ void rx_handle_exec(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { ctrl_exec_t* ctrl = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("rx_handle_exec","(0x%#llx, %d, 0x%#llx)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity checks. */ if((meta == NULL) || (cursor == NULL) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("rx_handle_exec","Bad args.",NULL); DTNMP_DEBUG_EXIT("rx_handle_exec","->.",NULL); return; } /* Step 1: Attempt to deserialize the message. */ ctrl = ctrl_deserialize_exec(cursor, size, &bytes); /* Step 2: If the deserialization failed, complain. */ if((ctrl == NULL) || (bytes == 0)) { DTNMP_DEBUG_ERR("rx_handle_exec","Can't deserialize.",NULL); ctrl_release_exec(ctrl); *bytes_used = 0; DTNMP_DEBUG_EXIT("rx_handle_exec","->.",NULL); return; } /* Step 3: Otherwise, note how many bytes were consumed. */ *bytes_used = bytes; /* * Step 4: Adjust the countdown ticks based on whether * we are given a relative or absolute time. */ if(ctrl->time <= DTNMP_RELATIVE_TIME_EPOCH) { /* Step 4a: If relative time, that is # seconds. */ ctrl->countdown_ticks = ctrl->time; } else { /* * Step 4b: If absolute time, # seconds if difference * from now until then. */ ctrl->countdown_ticks = (ctrl->time - getUTCTime()); } /* Step 5: Populate dynamic parts of the control. */ ctrl->desc.state = CONTROL_ACTIVE; strcpy(ctrl->desc.sender.name, meta->senderEid.name); /* Step 6: Persist this definition to our SDR. */ agent_db_ctrl_persist(ctrl); /* Step 7: Persist this definition to our memory lists. */ DTNMP_DEBUG_INFO("rx_handle_exec","Performing control.", NULL); ADD_CTRL(ctrl); /* Step 8: Update instrumentation counters. */ gAgentInstr.num_ctrls++; } /****************************************************************************** * * \par Function Name: rx_handle_time_prod * * \par Process a received time-based prod message. This function * accepts a portion of a serialized message group, with the * understanding that the time-based prod message is at the * head of the serialized data stream. This function extracts the * current message, and returns the number of bytes consumed so that * the called may then know where the next message in the serialized * message group begins. * * \param[in] meta The metadata associated with the message. * \param[in] cursor Pointer to the start of the serialized message. * \param[in] size The size of the remaining serialized message group * \param[out] bytes_used The number of bytes consumed in processing this msg. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/10/13 E. Birrane Initial implementation. *****************************************************************************/ void rx_handle_time_prod(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { rule_time_prod_t *new_rule = NULL; uint32_t bytes = 0; DTNMP_DEBUG_INFO("rx_handle_time_prod", "Processing a production rule.", NULL); /* Step 0: Sanity checks. */ if((meta == NULL) || (cursor == NULL) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("rx_handle_time_prod","Bad args.",NULL); DTNMP_DEBUG_EXIT("rx_handle_time_prod","->.",NULL); return; } /* Step 1: Attempt to deserialize the message. */ new_rule = ctrl_deserialize_time_prod_entry(cursor, size, &bytes); /* Step 2: If the deserialization failed, complain. */ if((new_rule == NULL) || (bytes == 0)) { DTNMP_DEBUG_ERR("rx_handle_time_prod","Can't deserialize.",NULL); rule_release_time_prod_entry(new_rule); *bytes_used = 0; DTNMP_DEBUG_EXIT("rx_handle_time_prod","->.",NULL); return; } /* Step 3: Otherwise, note how many bytes were consumed. */ *bytes_used = bytes; /* Step 4: Populate dynamic parts of the control. */ /* \todo: Consider single-fire absolute-time rules. */ new_rule->desc.num_evals = new_rule->count; new_rule->desc.interval_ticks = new_rule->period; new_rule->countdown_ticks = new_rule->desc.interval_ticks; strcpy(new_rule->desc.sender.name, meta->senderEid.name); if(new_rule->desc.num_evals == 0) { new_rule->desc.num_evals = DTNMP_RULE_EXEC_ALWAYS; } /* Step 5: Validate the new rule. */ if(rx_validate_rule(new_rule) == 0) { DTNMP_DEBUG_ERR("rx_handle_time_prod","New rule failed validation.",NULL); rule_release_time_prod_entry(new_rule); *bytes_used = 0; DTNMP_DEBUG_EXIT("rx_handle_time_prod","->.",NULL); return; } DTNMP_DEBUG_INFO("rx_handle_time_prod", "Adding new production rule.", NULL); /* Step 6: Persist this definition to our SDR. */ agent_db_rule_persist(new_rule); /* Step 7: Persist this definition to our memory lists. */ ADD_RULE(new_rule); /* Step 8: Update instrumentation counters. */ gAgentInstr.num_time_rules++; } /****************************************************************************** * * \par Function Name: rx_handle_macro_def * * \par Process a received macro def message. This function * accepts a portion of a serialized message group, with the * understanding that the macro def message is at the * head of the serialized data stream. This function extracts the * current message, and returns the number of bytes consumed so that * the called may then know where the next message in the serialized * message group begins. * * \param[in] meta The metadata associated with the message. * \param[in] cursor Pointer to the start of the serialized message. * \param[in] size The size of the remaining serialized message group * \param[out] bytes_used The number of bytes consumed in processing this msg. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/10/13 E. Birrane Initial implementation. *****************************************************************************/ void rx_handle_macro_def(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { def_gen_t* macro_def = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("rx_handle_macro_def","(0x%x, %d, 0x%x)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity checks. */ if((meta == NULL) || (cursor == NULL) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("rx_handle_time_prod","Bad args.",NULL); DTNMP_DEBUG_EXIT("rx_handle_time_prod","->.",NULL); return; } /* Step 1: Attempt to deserialize the message. */ macro_def = def_deserialize_gen(cursor, size, &bytes); /* Step 2: If the deserialization failed, complain. */ if((macro_def == NULL) || (bytes == 0)) { DTNMP_DEBUG_ERR("rx_handle_macro_def","Can;t deserialize.",NULL); def_release_gen(macro_def); *bytes_used = 0; DTNMP_DEBUG_EXIT("rx_handle_macro_def","->.",NULL); return; } /* Step 3: Otherwise, note how many bytes were consumed. */ *bytes_used = bytes; DTNMP_DEBUG_INFO("rx_handle_macro_def","Adding new report definition.", NULL); /* Step 4: Persist this definition to our SDR. */ agent_db_macro_persist(macro_def); /* Step 5: Persist this definition to our memory lists. */ ADD_MACRO(macro_def); /* Step 6: Update instrumentation counters. */ gAgentInstr.num_macros++; } ion-3.2.0~dfsg1.orig/nm/agent/adm_bp_priv.h0000644000175000017500000001050212260400056017027 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: adm_bp_priv.h ** ** Description: This implements the private aspects of a BP ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/16/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef ADM_BP_PRIV_H_ #define ADM_BP_PRIV_H_ #include "shared/adm/adm_bp.h" #include "shared/utils/expr.h" /****************************************************************************** * Retrieval Functions * ******************************************************************************/ void agent_adm_init_bp(); /* Retrieval Functions */ /* BP NODE */ expr_result_t bp_node_get_all(Lyst params); expr_result_t bp_node_get_node_id(Lyst params); expr_result_t bp_node_get_version(Lyst params); expr_result_t bp_node_get_storage(Lyst params); expr_result_t bp_node_get_last_restart(Lyst params); expr_result_t bp_node_get_num_reg(Lyst params); expr_result_t bp_node_get_fwd_pend(Lyst params); expr_result_t bp_node_get_dispatch_pend(Lyst params); expr_result_t bp_node_get_in_cust(Lyst params); expr_result_t bp_node_get_reassembly_pend(Lyst params); expr_result_t bp_node_get_blk_src_cnt(Lyst params); expr_result_t bp_node_get_norm_src_cnt(Lyst params); expr_result_t bp_node_get_exp_src_cnt(Lyst params); expr_result_t bp_node_get_blk_src_bytes(Lyst params); expr_result_t bp_node_get_norm_src_bytes(Lyst params); expr_result_t bp_node_get_exp_src_bytes(Lyst params); expr_result_t bp_node_get_blk_res_cnt(Lyst params); expr_result_t bp_node_get_norm_res_cnt(Lyst params); expr_result_t bp_node_get_exp_res_cnt(Lyst params); expr_result_t bp_node_get_blk_res_bytes(Lyst params); expr_result_t bp_node_get_norm_res_bytes(Lyst params); expr_result_t bp_node_get_exp_res_bytes(Lyst params); expr_result_t bp_node_get_bundles_frag(Lyst params); expr_result_t bp_node_get_frag_produced(Lyst params); expr_result_t bp_node_get_del_none(Lyst params); expr_result_t bp_node_get_del_expired(Lyst params); expr_result_t bp_node_get_del_fwd_uni(Lyst params); expr_result_t bp_node_get_del_cancel(Lyst params); expr_result_t bp_node_get_del_deplete(Lyst params); expr_result_t bp_node_get_del_bad_eid(Lyst params); expr_result_t bp_node_get_del_no_route(Lyst params); expr_result_t bp_node_get_del_no_contact(Lyst params); expr_result_t bp_node_get_del_bad_blk(Lyst params); expr_result_t bp_node_get_del_bytes(Lyst params); expr_result_t bp_node_get_fail_cust_cnt(Lyst params); expr_result_t bp_node_get_fail_cust_bytes(Lyst params); expr_result_t bp_node_get_fail_fwd_cnt(Lyst params); expr_result_t bp_node_get_fail_fwd_bytes(Lyst params); expr_result_t bp_node_get_fail_abandon_cnt(Lyst params); expr_result_t bp_node_get_fail_abandon_bytes(Lyst params); expr_result_t bp_node_get_fail_discard_cnt(Lyst params); expr_result_t bp_node_get_fail_discard_bytes(Lyst params); /* BP ENDPOINT */ expr_result_t bp_endpoint_get_names(Lyst params); expr_result_t bp_endpoint_get_all(Lyst params); expr_result_t bp_endpoint_get_name(Lyst params); expr_result_t bp_endpoint_get_active(Lyst params); expr_result_t bp_endpoint_get_singleton(Lyst params); expr_result_t bp_endpoint_get_abandon(Lyst params); /****************************************************************************** * Control Functions * ******************************************************************************/ uint32_t bp_ctrl_reset(Lyst params); #endif //#ifndef ADM_BP_PRIV_H_ ion-3.2.0~dfsg1.orig/nm/agent/adm_bp_priv.c0000644000175000017500000006326312260400056017036 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: adm_bp_priv.c ** ** Description: This implements the private aspects of a BP ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/16/13 E. Birrane Initial Implementation *****************************************************************************/ #include "ion.h" #include "lyst.h" #include "platform.h" #include "shared/adm/adm_bp.h" #include "shared/utils/utils.h" #include "adm_bp_priv.h" void agent_adm_init_bp() { /* Node-specific Information. */ uint8_t mid_str[ADM_MID_ALLOC]; adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 0, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_all); /* Node State Information */ adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 1, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_node_id); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 2, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_version); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 3, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_storage); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 4, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_last_restart); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 5, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_num_reg); /* Bundle State Information */ adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 6, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_fwd_pend); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 7, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_dispatch_pend); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 8, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_in_cust); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 9, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_reassembly_pend); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 10, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_blk_src_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 11, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_norm_src_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 12, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_exp_src_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 13, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_blk_src_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 14, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_norm_src_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 15, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_exp_src_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 16, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_blk_res_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 17, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_norm_res_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 18, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_exp_res_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 19, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_blk_res_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 20, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_norm_res_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 21, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_exp_res_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 22, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_bundles_frag); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 23, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_frag_produced); /* Error and Reporting Information */ adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 24, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_none); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 25, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_expired); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 26, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_fwd_uni); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 27, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_cancel); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 28, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_deplete); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 29, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_bad_eid); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 30, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_no_route); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 31, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_no_contact); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 32, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_bad_blk); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 33, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_del_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 34, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_fail_cust_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 35, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_fail_cust_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 36, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_fail_fwd_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 37, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_fail_fwd_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 38, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_fail_abandon_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 39, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_fail_abandon_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 40, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_fail_discard_cnt); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 41, mid_str); adm_add_datadef_collect(mid_str, bp_node_get_fail_discard_bytes); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 42, mid_str); adm_add_datadef_collect(mid_str, bp_endpoint_get_names); /* Endpoint-Specific Information */ adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 0, mid_str); adm_add_datadef_collect(mid_str, bp_endpoint_get_all); adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 1, mid_str); adm_add_datadef_collect(mid_str, bp_endpoint_get_name); adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 2, mid_str); adm_add_datadef_collect(mid_str, bp_endpoint_get_active); adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 3, mid_str); adm_add_datadef_collect(mid_str, bp_endpoint_get_singleton); adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 4, mid_str); adm_add_datadef_collect(mid_str, bp_endpoint_get_abandon); /* Controls */ adm_build_mid_str(0x01, BP_ADM_DATA_CTRL_NN, BP_ADM_DATA_CTRL_NN_LEN, 0, mid_str); adm_add_ctrl_run(mid_str, bp_ctrl_reset); } expr_result_t bp_node_get_all(Lyst params) { NmbpNode node_state; NmbpDisposition state; expr_result_t result; bpnm_node_get(&node_state); bpnm_disposition_get(&state); result.type = EXPR_TYPE_BLOB; result.value = (uint8_t*) MTAKE(sizeof(node_state) + sizeof(state)); memcpy(result.value, &node_state, sizeof(node_state)); memcpy(result.value + sizeof(node_state), &state, sizeof(state)); result.length = sizeof(node_state) + sizeof(state); return result; } expr_result_t bp_node_get_node_id(Lyst params) { expr_result_t result; NmbpNode node_state; bpnm_node_get(&node_state); result.type = EXPR_TYPE_STRING; result.value = adm_copy_string((char *) node_state.nodeID, &(result.length)); return result; } expr_result_t bp_node_get_version(Lyst params) { expr_result_t result; NmbpNode node_state; bpnm_node_get(&node_state); result.type = EXPR_TYPE_STRING; result.value = adm_copy_string((char *) node_state.bpVersionNbr, &(result.length)); return result; } expr_result_t bp_node_get_storage(Lyst params) { expr_result_t result; NmbpNode node_state; bpnm_node_get(&node_state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(node_state.avblStorage), sizeof(node_state.avblStorage), &(result.length)); return result; } expr_result_t bp_node_get_last_restart(Lyst params) { expr_result_t result; NmbpNode node_state; bpnm_node_get(&node_state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(node_state.lastRestartTime), sizeof(node_state.lastRestartTime), &(result.length)); return result; } expr_result_t bp_node_get_num_reg(Lyst params) { expr_result_t result; NmbpNode node_state; bpnm_node_get(&node_state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(node_state.nbrOfRegistrations), sizeof(node_state.nbrOfRegistrations), &(result.length)); return result; } expr_result_t bp_node_get_fwd_pend(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentForwardPending), sizeof(state.currentForwardPending), &(result.length)); return result; } expr_result_t bp_node_get_dispatch_pend(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentDispatchPending), sizeof(state.currentDispatchPending), &(result.length)); return result; } expr_result_t bp_node_get_in_cust(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentInCustody), sizeof(state.currentInCustody), &(result.length)); return result; } expr_result_t bp_node_get_reassembly_pend(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentReassemblyPending), sizeof(state.currentReassemblyPending), &(result.length)); return result; } expr_result_t bp_node_get_blk_src_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleSourceCount[0]), sizeof(state.bundleSourceCount[0]), &(result.length)); return result; } expr_result_t bp_node_get_norm_src_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleSourceCount[1]), sizeof(state.bundleSourceCount[1]), &(result.length)); return result; } expr_result_t bp_node_get_exp_src_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleSourceCount[2]), sizeof(state.bundleSourceCount[2]), &(result.length)); return result; } expr_result_t bp_node_get_blk_src_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleSourceBytes[0]), sizeof(state.bundleSourceBytes[0]), &(result.length)); return result; } expr_result_t bp_node_get_norm_src_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleSourceBytes[1]), sizeof(state.bundleSourceBytes[1]), &(result.length)); return result; } expr_result_t bp_node_get_exp_src_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleSourceBytes[2]), sizeof(state.bundleSourceBytes[2]), &(result.length)); return result; } expr_result_t bp_node_get_blk_res_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentResidentCount[0]), sizeof(state.currentResidentCount[0]), &(result.length)); return result; } expr_result_t bp_node_get_norm_res_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentResidentCount[1]), sizeof(state.currentResidentCount[1]), &(result.length)); return result; } expr_result_t bp_node_get_exp_res_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentResidentCount[2]), sizeof(state.currentResidentCount[2]), &(result.length)); return result; } expr_result_t bp_node_get_blk_res_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentResidentBytes[0]), sizeof(state.currentResidentBytes[0]), &(result.length)); return result; } expr_result_t bp_node_get_norm_res_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentResidentBytes[1]), sizeof(state.currentResidentBytes[1]), &(result.length)); return result; } expr_result_t bp_node_get_exp_res_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.currentResidentBytes[2]), sizeof(state.currentResidentBytes[2]), &(result.length)); return result; } expr_result_t bp_node_get_bundles_frag(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundlesFragmented), sizeof(state.bundlesFragmented), &(result.length)); return result; } expr_result_t bp_node_get_frag_produced(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.fragmentsProduced), sizeof(state.fragmentsProduced), &(result.length)); return result; } expr_result_t bp_node_get_del_none(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.delNoneCount), sizeof(state.delNoneCount), &(result.length)); return result; } expr_result_t bp_node_get_del_expired(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.delExpiredCount), sizeof(state.delExpiredCount), &(result.length)); return result; } expr_result_t bp_node_get_del_fwd_uni(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.delFwdUnidirCount), sizeof(state.delFwdUnidirCount), &(result.length)); return result; } expr_result_t bp_node_get_del_cancel(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.delCanceledCount), sizeof(state.delCanceledCount), &(result.length)); return result; } expr_result_t bp_node_get_del_deplete(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.delDepletionCount), sizeof(state.delDepletionCount), &(result.length)); return result; } expr_result_t bp_node_get_del_bad_eid(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.delEidMalformedCount), sizeof(state.delEidMalformedCount), &(result.length)); return result; } expr_result_t bp_node_get_del_no_route(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.delNoRouteCount), sizeof(state.delNoRouteCount), &(result.length)); return result; } expr_result_t bp_node_get_del_no_contact(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.delNoContactCount), sizeof(state.delNoContactCount), &(result.length)); return result; } expr_result_t bp_node_get_del_bad_blk(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.delBlkMalformedCount), sizeof(state.delBlkMalformedCount), &(result.length)); return result; } expr_result_t bp_node_get_del_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bytesDeletedToDate), sizeof(state.bytesDeletedToDate), &(result.length)); return result; } expr_result_t bp_node_get_fail_cust_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.custodyRefusedCount), sizeof(state.custodyRefusedCount), &(result.length)); return result; } expr_result_t bp_node_get_fail_cust_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.custodyRefusedBytes), sizeof(state.custodyRefusedBytes), &(result.length)); return result; } expr_result_t bp_node_get_fail_fwd_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleFwdFailedCount), sizeof(state.bundleFwdFailedCount), &(result.length)); return result; } expr_result_t bp_node_get_fail_fwd_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleFwdFailedBytes), sizeof(state.bundleFwdFailedBytes), &(result.length)); return result; } expr_result_t bp_node_get_fail_abandon_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleAbandonCount), sizeof(state.bundleAbandonCount), &(result.length)); return result; } expr_result_t bp_node_get_fail_abandon_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleAbandonBytes), sizeof(state.bundleAbandonBytes), &(result.length)); return result; } expr_result_t bp_node_get_fail_discard_cnt(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleDiscardCount), sizeof(state.bundleDiscardCount), &(result.length)); return result; } expr_result_t bp_node_get_fail_discard_bytes(Lyst params) { expr_result_t result; NmbpDisposition state; bpnm_disposition_get(&state); result.type = EXPR_TYPE_UVAST; result.value = adm_copy_integer((uint8_t*)&(state.bundleDiscardBytes), sizeof(state.bundleDiscardBytes), &(result.length)); return result; } expr_result_t bp_endpoint_get_names(Lyst params) { char names[2048]; char *ptrs[128]; int num = 0; Sdnv nm_sdnv; expr_result_t result; result.type = EXPR_TYPE_BLOB; uint8_t *cursor = NULL; bpnm_endpointNames_get((char *) names, 2048, ptrs, &num); extern void bpnm_endpointNames_get(char * nameBuffer, int bufLen, char * nameArray [], int * numStrings); encodeSdnv(&nm_sdnv, num); result.length = nm_sdnv.length + /* NUM as SDNV length */ strlen(ptrs[num-1]) + /* length of last string */ (ptrs[num-1] - names) + /* # bytes to get to last string */ 1; /* Final NULL terminator. */ result.value = (uint8_t *) MTAKE(result.length); cursor = result.value; memcpy(cursor,nm_sdnv.text, nm_sdnv.length); cursor += nm_sdnv.length; memcpy(cursor, names, result.length - nm_sdnv.length); return result; } expr_result_t bp_endpoint_get_all(Lyst params) { expr_result_t result; datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; char name[256]; /* \todo: Check for NULL entry here. */ NmbpEndpoint endpoint; int success = 0; result.type = EXPR_TYPE_BLOB; memset(name,'\0',256); memcpy(name,entry->value, entry->length); result.length = 0; result.value = NULL; bpnm_endpoint_get(name, &endpoint, &success); if(success != 0) { result.value = (uint8_t*) MTAKE(sizeof(endpoint)); memcpy(result.value, &endpoint, sizeof(endpoint)); result.length = sizeof(endpoint); } return result; } expr_result_t bp_endpoint_get_name(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; char name[256]; expr_result_t result; result.type = EXPR_TYPE_STRING; NmbpEndpoint endpoint; int success = 0; memset(name,'\0',256); memcpy(name,entry->value, entry->length); result.length = 0; result.value = NULL; bpnm_endpoint_get(name, &endpoint, &success); if(success != 0) { result.length = (uint64_t) strlen(endpoint.eid) + 1; result.value = (uint8_t*) MTAKE(result.length); memset(result.value,0,result.length); memcpy(result.value, endpoint.eid, result.length); } return result; } expr_result_t bp_endpoint_get_active(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); char name[256]; expr_result_t result; result.type = EXPR_TYPE_UINT32; NmbpEndpoint endpoint; int success = 0; memset(name,'\0',256); memcpy(name,entry->value, entry->length); result.length = 0; result.value = NULL; bpnm_endpoint_get(name, &endpoint, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(endpoint.active), sizeof(endpoint.active), &(result.length)); } return result; } expr_result_t bp_endpoint_get_singleton(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); char name[256]; expr_result_t result; result.type = EXPR_TYPE_UINT32; NmbpEndpoint endpoint; int success = 0; memset(name,'\0',256); memcpy(name,entry->value, entry->length); result.length = 0; result.value = NULL; bpnm_endpoint_get(name, &endpoint, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(endpoint.singleton), sizeof(endpoint.singleton), &(result.length)); } return result; } expr_result_t bp_endpoint_get_abandon(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); char name[256]; expr_result_t result; result.type = EXPR_TYPE_UINT32; NmbpEndpoint endpoint; int success = 0; memset(name,'\0',256); memcpy(name,entry->value, entry->length); result.length = 0; result.value = NULL; bpnm_endpoint_get(name, &endpoint, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(endpoint.abandonOnDelivFailure), sizeof(endpoint.abandonOnDelivFailure), &(result.length)); } return result; } /* Controls */ uint32_t bp_ctrl_reset(Lyst params) { bpnm_disposition_reset(); return 0; } ion-3.2.0~dfsg1.orig/nm/agent/adm_ion_priv.c0000644000175000017500000005207012260400056017214 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ #ifdef _HAVE_ION_ADM_ /***************************************************************************** ** ** File Name: adm_ion_priv.c ** ** Description: This implements the private aspects of an ION ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/16/13 E. Birrane Initial Implementation *****************************************************************************/ #include "ion.h" #include "platform.h" #include "shared/adm/adm_ion.h" #include "shared/utils/utils.h" #include "adm_ion_priv.h" void agent_adm_init_ion() { /* Register Nicknames */ uint8_t mid_str[ADM_MID_ALLOC]; /* ICI */ adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 0, mid_str); adm_add_datadef_collect(mid_str, ion_ici_get_sdr_state_all); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 1, mid_str); adm_add_datadef_collect(mid_str, ion_ici_get_small_pool_size); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 2, mid_str); adm_add_datadef_collect(mid_str, ion_ici_get_small_pool_free); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 3, mid_str); adm_add_datadef_collect(mid_str, ion_ici_get_small_pool_alloc); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 4, mid_str); adm_add_datadef_collect(mid_str, ion_ici_get_large_pool_size); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 5, mid_str); adm_add_datadef_collect(mid_str, ion_ici_get_large_pool_free); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 6, mid_str); adm_add_datadef_collect(mid_str, ion_ici_get_large_pool_alloc); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 7, mid_str); adm_add_datadef_collect(mid_str, ion_ici_get_unused_size); /* Inducts */ adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 0, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_all); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 1, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_name); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 2, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_last_reset); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 3, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_rx_bndl); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 4, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_rx_byte); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 5, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_mal_bndl); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 6, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_mal_byte); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 7, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_inauth_bndl); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 8, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_inauth_byte); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 9, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_over_bndl); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 10, mid_str); adm_add_datadef_collect(mid_str, ion_induct_get_over_byte); /* Outducts */ adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 0, mid_str); adm_add_datadef_collect(mid_str, ion_outduct_get_all); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 1, mid_str); adm_add_datadef_collect(mid_str, ion_outduct_get_name); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 2, mid_str); adm_add_datadef_collect(mid_str, ion_outduct_get_cur_q_bdnl); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 3, mid_str); adm_add_datadef_collect(mid_str, ion_outduct_get_cur_q_byte); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 4, mid_str); adm_add_datadef_collect(mid_str, ion_outduct_get_last_reset); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 5, mid_str); adm_add_datadef_collect(mid_str, ion_outduct_get_enq_bndl); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 6, mid_str); adm_add_datadef_collect(mid_str, ion_outduct_get_enq_byte); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 7, mid_str); adm_add_datadef_collect(mid_str, ion_outduct_get_deq_bndl); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 8, mid_str); adm_add_datadef_collect(mid_str, ion_outduct_get_deq_byte); /* Node */ adm_build_mid_str(0x00, ION_ADM_NODE_NN, ION_ADM_NODE_NN_LEN, 0, mid_str); adm_add_datadef_collect(mid_str, ion_node_get_all); adm_build_mid_str(0x00, ION_ADM_NODE_NN, ION_ADM_NODE_NN_LEN, 1, mid_str); adm_add_datadef_collect(mid_str, ion_node_get_inducts); adm_build_mid_str(0x00, ION_ADM_NODE_NN, ION_ADM_NODE_NN_LEN, 2, mid_str); adm_add_datadef_collect(mid_str, ion_node_get_outducts); /* Controls */ adm_build_mid_str(0x01, ION_ADM_CTRL_NN, ION_ADM_CTRL_NN_LEN, 0, mid_str); adm_add_ctrl_run(mid_str, ion_ctrl_induct_reset); adm_build_mid_str(0x01, ION_ADM_CTRL_NN, ION_ADM_CTRL_NN_LEN, 1, mid_str); adm_add_ctrl_run(mid_str, ion_ctrl_outduct_reset); } /* Retrieval Functions. */ expr_result_t ion_ici_get_sdr_state_all(Lyst params) { SdrnmState state; expr_result_t result; result.type = EXPR_TYPE_BLOB; result.length = sizeof(state); result.value = (uint8_t*) MTAKE(result.length); sdrnm_state_get(&state); memcpy(result.value, &state, result.length); return result; } expr_result_t ion_ici_get_small_pool_size(Lyst params) { SdrnmState state; expr_result_t result; result.type = EXPR_TYPE_UINT32; sdrnm_state_get(&state); result.value = adm_copy_integer((uint8_t*)&(state.smallPoolSize), sizeof(state.smallPoolSize), &(result.length)); return result; } expr_result_t ion_ici_get_small_pool_free(Lyst params) { SdrnmState state; expr_result_t result; result.type = EXPR_TYPE_UINT32; sdrnm_state_get(&state); result.value = adm_copy_integer((uint8_t*)&(state.smallPoolFree), sizeof(state.smallPoolFree), &(result.length)); return result; } expr_result_t ion_ici_get_small_pool_alloc(Lyst params) { SdrnmState state; expr_result_t result; result.type = EXPR_TYPE_UINT32; sdrnm_state_get(&state); result.value = adm_copy_integer((uint8_t*)&(state.smallPoolAllocated), sizeof(state.smallPoolAllocated), &(result.length)); return result; } expr_result_t ion_ici_get_large_pool_size(Lyst params) { SdrnmState state; expr_result_t result; result.type = EXPR_TYPE_UINT32; sdrnm_state_get(&state); result.value = adm_copy_integer((uint8_t*)&(state.largePoolSize), sizeof(state.largePoolSize), &(result.length)); return result; } expr_result_t ion_ici_get_large_pool_free(Lyst params) { SdrnmState state; expr_result_t result; result.type = EXPR_TYPE_UINT32; sdrnm_state_get(&state); result.value = adm_copy_integer((uint8_t*)&(state.largePoolFree), sizeof(state.largePoolFree), &(result.length)); return result; } expr_result_t ion_ici_get_large_pool_alloc(Lyst params) { SdrnmState state; expr_result_t result; result.type = EXPR_TYPE_UINT32; sdrnm_state_get(&state); result.value = adm_copy_integer((uint8_t*)&(state.largePoolAllocated), sizeof(state.largePoolAllocated), &(result.length)); return result; } expr_result_t ion_ici_get_unused_size(Lyst params) { SdrnmState state; expr_result_t result; result.type = EXPR_TYPE_UINT32; sdrnm_state_get(&state); result.value = adm_copy_integer((uint8_t*)&(state.unusedSize), sizeof(state.unusedSize), &(result.length)); return result; } /* ION INDUCT */ expr_result_t ion_induct_get_all(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; char name[256]; expr_result_t result; result.type = EXPR_TYPE_BLOB; NmbpInduct induct; int success = 0; memset(name,'\0',256); memcpy(name,entry->value, entry->length); result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.length = sizeof(NmbpInduct); result.value = (uint8_t*) MTAKE(result.length); memset(result.value, 0, result.length); memcpy(result.value, &induct, result.length); } return result; } expr_result_t ion_induct_get_name(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; char name[256]; expr_result_t result; result.type = EXPR_TYPE_STRING; NmbpInduct induct; int success = 0; memset(name,'\0',256); memcpy(name,entry->value, entry->length); result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.length = (uint64_t) strlen(induct.inductName) + 1; result.value = (uint8_t*) MTAKE(result.length); memset(result.value, 0, result.length); memcpy(result.value, induct.inductName, result.length); } return result; } expr_result_t ion_induct_get_last_reset(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpInduct induct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(induct.lastResetTime), sizeof(induct.lastResetTime), &(result.length)); } return result; } expr_result_t ion_induct_get_rx_bndl(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpInduct induct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(induct.bundleRecvCount), sizeof(induct.bundleRecvCount), &(result.length)); } return result; } expr_result_t ion_induct_get_rx_byte(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpInduct induct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(induct.bundleRecvBytes), sizeof(induct.bundleRecvBytes), &(result.length)); } return result; } expr_result_t ion_induct_get_mal_bndl(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpInduct induct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(induct.bundleMalformedCount), sizeof(induct.bundleMalformedCount), &(result.length)); } return result; } expr_result_t ion_induct_get_mal_byte(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpInduct induct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(induct.bundleMalformedBytes), sizeof(induct.bundleMalformedBytes), &(result.length)); } return result; } expr_result_t ion_induct_get_inauth_bndl(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpInduct induct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(induct.bundleInauthenticCount), sizeof(induct.bundleInauthenticCount), &(result.length)); } return result; } expr_result_t ion_induct_get_inauth_byte(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpInduct induct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(induct.bundleInauthenticBytes), sizeof(induct.bundleInauthenticBytes), &(result.length)); } return result; } expr_result_t ion_induct_get_over_bndl(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpInduct induct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(induct.bundleOverflowCount), sizeof(induct.bundleOverflowCount), &(result.length)); } return result; } expr_result_t ion_induct_get_over_byte(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpInduct induct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_induct_get(name, &induct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(induct.bundleOverflowBytes), sizeof(induct.bundleOverflowBytes), &(result.length)); } return result; } /* ION NODE */ expr_result_t ion_node_get_all(Lyst params) { expr_result_t inducts; expr_result_t outducts; expr_result_t result; result.type = EXPR_TYPE_BLOB; inducts = ion_node_get_inducts(params); outducts = ion_node_get_outducts(params); result.length = inducts.length + outducts.length; result.value = (uint8_t*) MTAKE(result.length); memcpy(result.value,inducts.value,inducts.length); memcpy(result.value + inducts.length, outducts.value, outducts.length); expr_release(inducts); expr_release(outducts); return result; } expr_result_t ion_node_get_inducts(Lyst params) { char names[2048]; char *ptrs[128]; int num = 0; Sdnv nm_sdnv; uint8_t *cursor = NULL; expr_result_t result; result.type = EXPR_TYPE_BLOB; bpnm_inductNames_get((char *) names, ptrs, &num); encodeSdnv(&nm_sdnv, num); result.length = nm_sdnv.length + /* NUM as SDNV length */ strlen(ptrs[num-1]) + /* length of last string */ (ptrs[num-1] - names) + /* # bytes to get to last string */ 1; /* Final NULL terminator. */ result.value = (uint8_t *) MTAKE(result.length); cursor = result.value; memcpy(cursor,nm_sdnv.text, nm_sdnv.length); cursor += nm_sdnv.length; memcpy(cursor, names, result.length - nm_sdnv.length); return result; } expr_result_t ion_node_get_outducts(Lyst params) { char names[2048]; char *ptrs[128]; int num = 0; Sdnv nm_sdnv; uint8_t *cursor = NULL; expr_result_t result; result.type = EXPR_TYPE_BLOB; result.length = 0; result.value = NULL; bpnm_outductNames_get((char *) names, ptrs, &num); encodeSdnv(&nm_sdnv, num); result.length = nm_sdnv.length + /* NUM as SDNV length */ strlen(ptrs[num-1]) + /* length of last string */ (ptrs[num-1] - names) + /* # bytes to get to last string */ 1; /* Final NULL terminator. */ result.value = (uint8_t *) MTAKE(result.length); cursor = result.value; memcpy(cursor,nm_sdnv.text, nm_sdnv.length); cursor += nm_sdnv.length; memcpy(cursor, names, result.length - nm_sdnv.length); return result; } /* ION OUTDUCT */ expr_result_t ion_outduct_get_all(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; char name[256]; expr_result_t result; result.type = EXPR_TYPE_BLOB; NmbpOutduct outduct; int success = 0; memset(name,'\0',256); memcpy(name,entry->value, entry->length); result.length = 0; result.value = NULL; bpnm_outduct_get(name, &outduct, &success); if(success != 0) { result.length = sizeof(NmbpInduct); result.value = (uint8_t*) MTAKE(result.length); memset(result.value, 0, result.length); memcpy(result.value, &outduct, result.length); } return result; } expr_result_t ion_outduct_get_name(Lyst params) { datacol_entry_t *entry = (datacol_entry_t*)lyst_data(lyst_first(params)); unsigned long val = 0; char name[256]; expr_result_t result; result.type = EXPR_TYPE_STRING; result.length = 0; result.value = NULL; NmbpOutduct outduct; int success = 0; memset(name,'\0',256); memcpy(name,entry->value, entry->length); bpnm_outduct_get(name, &outduct, &success); if(success != 0) { result.length = (uint64_t) strlen(outduct.outductName) + 1; result.value = (uint8_t*) MTAKE(result.length); memset(result.value, 0, result.length); memcpy(result.value, outduct.outductName, result.length); } return result; } expr_result_t ion_outduct_get_cur_q_bdnl(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpOutduct outduct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_outduct_get(name, &outduct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(outduct.currentQueuedBundlesCount), sizeof(outduct.currentQueuedBundlesCount), &(result.length)); } return result; } expr_result_t ion_outduct_get_cur_q_byte(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpOutduct outduct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_outduct_get(name, &outduct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(outduct.currentQueuedBundlesBytes), sizeof(outduct.currentQueuedBundlesBytes), &(result.length)); } return result; } expr_result_t ion_outduct_get_last_reset(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpOutduct outduct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_outduct_get(name, &outduct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(outduct.lastResetTime), sizeof(outduct.lastResetTime), &(result.length)); } return result; } expr_result_t ion_outduct_get_enq_bndl(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpOutduct outduct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_outduct_get(name, &outduct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(outduct.bundleEnqueuedCount), sizeof(outduct.bundleEnqueuedCount), &(result.length)); } return result; } expr_result_t ion_outduct_get_enq_byte(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpOutduct outduct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_outduct_get(name, &outduct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(outduct.bundleEnqueuedBytes), sizeof(outduct.bundleEnqueuedBytes), &(result.length)); } return result; } expr_result_t ion_outduct_get_deq_bndl(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpOutduct outduct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_outduct_get(name, &outduct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(outduct.bundleDequeuedCount), sizeof(outduct.bundleDequeuedCount), &(result.length)); } return result; } expr_result_t ion_outduct_get_deq_byte(Lyst params) { char *name = (char *) lyst_data(lyst_first(params)); NmbpOutduct outduct; int success = 0; expr_result_t result; result.type = EXPR_TYPE_UINT32; result.length = 0; result.value = NULL; bpnm_outduct_get(name, &outduct, &success); if(success != 0) { result.value = adm_copy_integer((uint8_t*)&(outduct.bundleDequeuedBytes), sizeof(outduct.bundleDequeuedBytes), &(result.length)); } return result; } uint32_t ion_ctrl_induct_reset(Lyst params) { /* TODO: Implement. */ return 0; } uint32_t ion_ctrl_outduct_reset(Lyst params) { /* TODO: Implement */ return 0; } #endif /* _HAVE_ION_ADM_ */ ion-3.2.0~dfsg1.orig/nm/shared/0000755000175000017500000000000012260400057014547 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/shared/adm/0000755000175000017500000000000012260400056015307 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/shared/adm/adm_bp.h0000644000175000017500000000773312260400056016714 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: adm_bp.h ** ** Description: This file contains the definitions of the Bundle Protocol ** ADM. ** ** Notes: ** ** Assumptions: ** 1. We current use a non-official OID root tree for DTN Bundle Protocol ** identifiers. ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/22/11 E. Birrane Initial Implementation. ** 01/02/13 E. Birrane Update to latest version of DTNMP. Cleanup. *****************************************************************************/ #ifndef ADM_BP_H_ #define ADM_BP_H_ #include "lyst.h" #include "bpnm.h" #include "shared/utils/nm_types.h" #include "shared/adm/adm.h" /* * [3] arrays ar eby classes of service. * 0 - BULK * 1 - NORM * 2 - EXP */ /* * +--------------------------------------------------------------------------+ * | ADM CONSTANTS + * +--------------------------------------------------------------------------+ */ /* * We will invent an OID space for BP ADM information, to live at: * * iso.identified-organization.dod.internet.mgmt.dtnmp.bp * or 1.3.6.1.2.3.1 * or, as OID,: 2A 06 01 02 03 01 * * Note: dtnmp.bp is a made-up subtree. */ static char* BP_ADM_ROOT = "2B0601020301"; #define BP_ADM_ROOT_LEN (6) /* * +--------------------------------------------------------------------------+ * | ADM ATOMIC DATA DEFINITIONS + * +--------------------------------------------------------------------------+ */ /* * Structure: Node Info is subtree at 01. Endpoint is subtree at 02. CLA is * subtree at 03. * * ADM_BP_ROOT (2A0601020301) * | * NODE_INFO (01) | ENDPOINT_INFO (02) CTRL (03) * +------------+----------+---------------------+ * | | | | */ /* Node-Specific Definitions */ static char* BP_ADM_DATA_NN = "2B060102030101"; #define BP_ADM_DATA_NN_LEN (7) /* Endpoint-Specific Definitions */ static char* BP_ADM_DATA_END_NN = "2B060102030102"; #define BP_ADM_DATA_END_NN_LEN (7) /* Bundle Protocol Controls */ static char* BP_ADM_DATA_CTRL_NN = "2B060102030103"; #define BP_ADM_DATA_CTRL_NN_LEN (7) /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ void adm_bp_init(); /* Custom Print Functions */ char *bp_print_node_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); char *bp_print_endpoint_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); /* Custom Size Functions. */ uint32_t bp_size_node_all(uint8_t* buffer, uint64_t buffer_len); uint32_t bp_size_endpoint_all(uint8_t* buffer, uint64_t buffer_len); uint32_t bp_size_node_id(uint8_t* buffer, uint64_t buffer_len); uint32_t bp_size_node_version(uint8_t* buffer, uint64_t buffer_len); uint32_t bp_size_node_restart_time(uint8_t* buffer, uint64_t buffer_len); uint32_t bp_size_node_num_reg(uint8_t* buffer, uint64_t buffer_len); uint32_t bp_size_endpoint_name(uint8_t* buffer, uint64_t buffer_len); #endif //ADM_BP_H_ ion-3.2.0~dfsg1.orig/nm/shared/adm/adm_ion.h0000644000175000017500000000537212260400056017075 0ustar l3onl3on// // adm_bp.h // // Created by Birrane, Edward J. on 10/22/11. // Copyright 2011 __MyCompanyName__. All rights reserved. // #ifndef ADM_ION_H_ #define ADM_ION_H_ #ifdef _HAVE_ION_ADM_ #include "lyst.h" #include "bpnm.h" #include "icinm.h" #include "shared/utils/nm_types.h" #include "shared/adm/adm.h" /* * We will invent an OID space for ION ADM information, to live at: * * iso.identified-organization.dod.internet.mgmt.dtnmp.ion * or 1.3.6.1.2.3.4 * or, as OID,: 2B 06 01 02 03 04 * * Note: dtnmp.ion is a made-up subtree. */ /* * +--------------------------------------------------------------------------+ * | ADM CONSTANTS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | ADM ATOMIC DATA DEFINITIONS + * +--------------------------------------------------------------------------+ */ /* * Structure: * * ADM_ION_ROOT (2A0601020304) * | * ICI (01) | INDUCT (02) OUTDUCT (03) NODE (04) * +-----------------------+--------------+--------------+ * | | | | */ static char* ION_ADM_ROOT = "2B0601020304"; #define ION_ADM_ROOT_LEN (6) static char* ION_ADM_ICI_NN = "2B060102030401"; #define ION_ADM_ICI_NN_LEN (7) static char* ION_ADM_INDUCT_NN = "2B060102030402"; #define ION_ADM_INDUCT_NN_LEN (7) static char* ION_ADM_OUTDUCT_NN = "2B060102030403"; #define ION_ADM_OUTDUCT_NN_LEN (7) static char* ION_ADM_NODE_NN = "2B060102030404"; #define ION_ADM_NODE_NN_LEN (7) static char* ION_ADM_CTRL_NN = "2B060102030405"; #define ION_ADM_CTRL_NN_LEN (7) void adm_ion_init(); /* Print Functions */ char *ion_print_sdr_state_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); char *ion_node_print_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); char *ion_induct_print_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); char *ion_outduct_print_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); /* Sizing Functions */ /* ION ICI */ uint32_t ion_size_sdr_state_all(uint8_t* buffer, uint64_t buffer_len); /* ION INDUCT */ uint32_t ion_induct_size_all(uint8_t* buffer, uint64_t buffer_len); /* ION OUTDUCT */ uint32_t ion_outduct_size_all(uint8_t* buffer, uint64_t buffer_len); /* ION NODE */ uint32_t ion_node_size_all(uint8_t* buffer, uint64_t buffer_len); uint32_t ion_node_size_inducts(uint8_t* buffer, uint64_t buffer_len); uint32_t ion_node_size_outducts(uint8_t* buffer, uint64_t buffer_len); #endif /* _HAVE_ION_ADM_ */ #endif //ADM_ION_H_ ion-3.2.0~dfsg1.orig/nm/shared/adm/adm_agent.c0000644000175000017500000001366312260400056017403 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: adm_agent_public.c ** ** Description: This implements the public aspects of a DTNMP agent ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/04/13 E. Birrane Initial Implementation *****************************************************************************/ #include "ion.h" #include "platform.h" #include "shared/adm/adm_agent.h" #include "shared/utils/utils.h" #include "shared/primitives/instr.h" void adm_agent_init() { /* Register Nicknames */ uint8_t mid_str[ADM_MID_ALLOC]; /* DTNMP Agent Data */ adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 0, mid_str); adm_add_datadef("DTNMP_AGENT_DATA", mid_str, 0, adm_print_agent_all, adm_size_agent_all); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 1, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_RPT_DEFS", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 2, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_SENT_RPTS", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 3, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_TIME_RULES", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 4, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_TIME_RULES_RUN", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 5, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_PROD_RULES", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 6, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_PROD_RULES_RUN", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 7, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_CONSTS", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 8, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_DATA_DEFS", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 9, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_MACROS", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 10, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_MACROS_RUN", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 11, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_CTRLS", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ADM_AGENT_NODE_NN, ADM_AGENT_NODE_NN_LEN, 12, mid_str); adm_add_datadef("DTNMP_AGENT_NUM_CTRLS_RUN", mid_str, 0, NULL, NULL); /* DTNMP Agent Controls */ adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 0, mid_str); adm_add_ctrl("DTNMP_AGENT_LIST_RPT_DEFS", mid_str, 0); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 1, mid_str); adm_add_ctrl("DTNMP_AGENT_LIST_TIME_RULES",mid_str, 0); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 2, mid_str); adm_add_ctrl("DTNMP_AGENT_LIST_PROD_RULES",mid_str, 0); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 3, mid_str); adm_add_ctrl("DTNMP_AGENT_LIST_CONSTS", mid_str, 0); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 4, mid_str); adm_add_ctrl("DTNMP_AGENT_LIST_DATA_DEFS", mid_str, 0); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 5, mid_str); adm_add_ctrl("DTNMP_AGENT_LIST_MACROS", mid_str, 0); adm_build_mid_str(0x01, ADM_AGENT_CTRL_NN, ADM_AGENT_CTRL_NN_LEN, 6, mid_str); adm_add_ctrl("DTNMP_AGENT_LIST_CTRLS", mid_str, 0); /* DTNMP Agent Literals */ /* \todo: Add Literals */ /* DTNMP Agent Operators */ /* \todo Add Operators */ } /* Custom Print Functions. */ char *adm_print_agent_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { agent_instr_t state; char *result; uint32_t temp_size = 0; // \todo: Check sizes. memcpy(&state, buffer, data_len); // Assume for now a 4 byte integer takes <= 20 characters. // Assume all the text strings average less than 25 characters per string. temp_size = 12 * sizeof(unsigned long); *str_len = (temp_size * 5) + (25 * 100); // Assume for now a 4 byte integer takes <= 20 characters to print. if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("adm_print_agent_all","Can't allocate %d bytes", *str_len); *str_len = 0; return NULL; } memset(result, '\0', *str_len); sprintf(result, "\num_rpt_defs = %ld\nnum_sent_rpts = %ld\nnum_time_rules = %ld\n \ num_time_rules_run = %ld\nnum_prod_rules = %ld\nnum_prod_rules_run = %ld\n \ num_consts = %ld\nnum_data_defs = %ld\nnum_macros = %ld\nnum_macros_run = %ld\n \ num_ctrls = %ld\nnum_ctrls_run = %ld\n", state.num_rpt_defs, state.num_sent_rpts, state.num_time_rules, state.num_time_rules_run, state.num_prod_rules, state.num_prod_rules_run, state.num_consts, state.num_data_defs, state.num_macros, state.num_macros_run, state.num_ctrls, state.num_ctrls_run); return result; } /* SIZE */ uint32_t adm_size_agent_all(uint8_t* buffer, uint64_t buffer_len) { return sizeof(gAgentInstr); } ion-3.2.0~dfsg1.orig/nm/shared/adm/adm.c0000644000175000017500000012447312260400056016227 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: adm.c ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for the identification and ** processing of Application Data Models (ADMs). ** ** Notes: ** 1) We need to find some more efficient way of querying ADMs by name ** and by MID. The current implementation uses too much stack space. ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/22/11 E. Birrane Initial Implementation ** 11/13/12 E. Birrane Technical review, comment updates. *****************************************************************************/ #include "ion.h" #include "platform.h" #include "shared/utils/nm_types.h" #include "shared/utils/utils.h" #include "shared/adm/adm.h" #include "shared/adm/adm_bp.h" #include "shared/adm/adm_ltp.h" #include "shared/adm/adm_ion.h" #include "shared/adm/adm_agent.h" Lyst gAdmData; Lyst gAdmCtrls; Lyst gAdmLiterals; Lyst gAdmOps; /****************************************************************************** * * \par Function Name: adm_add_datadef * * \par Registers a pre-configured ADM data definition with the local DTNMP actor. * * \param[in] name Name of the ADM entry. * \param[in] mid_str serialized MID value * \param[in] num_parms # parms needed for parameterized OIDs. * \param[in] to_string The to-string function * \param[in] get_size The sizing function for the ADM entry. * * \par Notes: * 1. When working with parameterized OIDs, the given MID should * be all information excluding the parameterized portion of the OID. * 2. ADM names will be truncated after ADM_MAX_NAME bytes. * 3. If a NULL to_string is given, we assume it is unsigned long. * 4. If a NULL get_size is given, we assume is it unsigned long. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. * 07/27/13 E. BIrrane Updated ADM to use Lysts. *****************************************************************************/ void adm_add_datadef(char *name, uint8_t *mid_str, int num_parms, adm_string_fn to_string, adm_size_fn get_size) { uint32_t size = 0; uint32_t used = 0; adm_datadef_t *new_entry = NULL; DTNMP_DEBUG_ENTRY("adm_add_datadef","(%llx, %llx, %d, %llx, %llx)", name, mid_str, num_parms, to_string, get_size); /* Step 0 - Sanity Checks. */ if((name == NULL) || (mid_str == NULL)) { DTNMP_DEBUG_ERR("adm_add_datadef","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_add_datadef","->.", NULL); return; } if(gAdmData == NULL) { DTNMP_DEBUG_ERR("adm_add_datadef","Global data list not initialized.", NULL); DTNMP_DEBUG_EXIT("adm_add_datadef","->.", NULL); return; } /* Step 1 - Check name length. */ if(strlen(name) > ADM_MAX_NAME) { DTNMP_DEBUG_WARN("adm_add_datadef","Trunc. %s to %d bytes.", name, ADM_MAX_NAME) } /* Step 2 - Allocate a Data Definition. */ if((new_entry = (adm_datadef_t *) MTAKE(sizeof(adm_datadef_t))) == NULL) { DTNMP_DEBUG_ERR("adm_add_datadef","Can't allocate new entry of size %d.", sizeof(adm_datadef_t)); DTNMP_DEBUG_EXIT("adm_add_datadef","->.", NULL); return; } /* Step 3 - Copy the ADM information. */ strncpy((char *)new_entry->name, name, ADM_MAX_NAME); new_entry->mid = mid_deserialize(mid_str, ADM_MID_ALLOC, &used); new_entry->num_parms = num_parms; new_entry->collect = NULL; new_entry->to_string = (to_string == NULL) ? adm_print_uvast : to_string; new_entry->get_size = (get_size == NULL) ? adm_size_uvast : get_size; /* Step 4 - Add the new entry. */ lyst_insert_last(gAdmData, new_entry); DTNMP_DEBUG_EXIT("adm_add_datadef","->.", NULL); return; } /****************************************************************************** * * \par Function Name: adm_add_datadef_collect * * \par Registers a collection function to a data definition. * * \param[in] mid_str serialized MID value * \param[in] collect The data collection function. * * \par Notes: * 1. When working with parameterized OIDs, the given MID should * be all information excluding the parameterized portion of the OID. * 2. ADM names will be truncated after ADM_MAX_NAME bytes. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. * 07/27/13 E. BIrrane Updated ADM to use Lysts. *****************************************************************************/ void adm_add_datadef_collect(uint8_t *mid_str, adm_data_collect_fn collect) { uint32_t used = 0; mid_t *mid = NULL; adm_datadef_t *entry = NULL; DTNMP_DEBUG_ENTRY("adm_add_datadef_collect","(%lld, %lld)", mid_str, collect); if((mid_str == NULL) || (collect == NULL)) { DTNMP_DEBUG_ERR("adm_add_datadef_collect","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_add_datadef_collect","->.", NULL); return; } if((mid = mid_deserialize(mid_str, ADM_MID_ALLOC, &used)) == NULL) { char *tmp = utils_hex_to_string(mid_str, ADM_MID_ALLOC); DTNMP_DEBUG_ERR("adm_add_datadef_collect","Can't deserialize MID str %s.",tmp); MRELEASE(tmp); DTNMP_DEBUG_EXIT("adm_add_datadef_collect","->.", NULL); return; } if((entry = adm_find_datadef(mid)) == NULL) { char *tmp = mid_to_string(mid); DTNMP_DEBUG_ERR("adm_add_datadef_collect","Can't find data for MID %s.", tmp); MRELEASE(tmp); } else { entry->collect = collect; } mid_release(mid); DTNMP_DEBUG_EXIT("adm_add_datadef_collect","->.", NULL); } /****************************************************************************** * * \par Function Name: adm_add_ctrl * * \par Registers a pre-configured ADM control with the local DTNMP actor. * * \param[in] name Name of the ADM control. * \param[in] mid_str MID value, as a string. * \param[in] num_parms # parms needed for parameterized OIDs. * \param[in] control The control collection function. * * \par Notes: * 1. When working with parameterized OIDs, the given MID string should * be all information excluding the parameterized portion of the OID. * 2. ADM names will be truncated after ADM_MAX_NAME bytes. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ void adm_add_ctrl(char *name, uint8_t *mid_str, int num_parms) { uint8_t *tmp = NULL; uint32_t size = 0; uint32_t used = 0; adm_ctrl_t *new_entry = NULL; DTNMP_DEBUG_ENTRY("adm_add_ctrl","(%#llx, %#llx, %d)", name, mid_str, num_parms); /* Step 0 - Sanity Checks. */ if((name == NULL) || (mid_str == NULL)) { DTNMP_DEBUG_ERR("adm_add_ctrl","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_add_ctrl","->.", NULL); return; } if(gAdmCtrls == NULL) { DTNMP_DEBUG_ERR("adm_add_ctrl","Global Controls list not initialized.", NULL); DTNMP_DEBUG_EXIT("adm_add_ctrl","->.", NULL); return; } /* Step 1 - Check name length. */ if(strlen(name) > ADM_MAX_NAME) { DTNMP_DEBUG_WARN("adm_add_ctrl","Trunc. %s to %d bytes.", name, ADM_MAX_NAME) } /* Step 2 - Allocate a Data Definition. */ if((new_entry = (adm_ctrl_t *) MTAKE(sizeof(adm_ctrl_t))) == NULL) { DTNMP_DEBUG_ERR("adm_add_ctrl","Can't allocate new entry of size %d.", sizeof(adm_datadef_t)); DTNMP_DEBUG_EXIT("adm_add_ctrl","->.", NULL); return; } /* Step 3 - Copy the ADM information. */ strncpy((char *)new_entry->name, name, ADM_MAX_NAME); new_entry->mid = mid_deserialize(mid_str, ADM_MID_ALLOC, &used); //new_entry->mid_len = size; new_entry->num_parms = num_parms; new_entry->run = NULL; /* Step 4 - Add the new entry. */ lyst_insert_last(gAdmCtrls, new_entry); DTNMP_DEBUG_EXIT("adm_add_ctrl","->.", NULL); return; } /****************************************************************************** * * \par Function Name: adm_add_ctrl_run * * \par Registers a control function with a Control MID. * * \param[in] mid_str MID value, as a string. * \param[in] control The control function. * * \par Notes: * 1. When working with parameterized OIDs, the given MID string should * be all information excluding the parameterized portion of the OID. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/28/13 E. Birrane Initial implementation. *****************************************************************************/ void adm_add_ctrl_run(uint8_t *mid_str, adm_ctrl_fn run) { uint32_t used = 0; mid_t *mid = NULL; adm_ctrl_t *entry = NULL; DTNMP_DEBUG_ENTRY("adm_add_ctrl_run","(%lld, %lld)", mid_str, run); if((mid_str == NULL) || (run == NULL)) { DTNMP_DEBUG_ERR("adm_add_ctrl_run","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_add_ctrl_run","->.",NULL); return; } if((mid = mid_deserialize(mid_str, ADM_MID_ALLOC, &used)) == NULL) { char *tmp = utils_hex_to_string(mid_str, ADM_MID_ALLOC); DTNMP_DEBUG_ERR("adm_add_ctrl_run","Can't deserialized MID %s", tmp); MRELEASE(tmp); DTNMP_DEBUG_EXIT("adm_add_ctrl_run","->.",NULL); return; } if((entry = adm_find_ctrl(mid)) == NULL) { char *tmp = mid_to_string(mid); DTNMP_DEBUG_ERR("adm_add_ctrl_run","Can't find control for MID %s", tmp); MRELEASE(tmp); } else { entry->run = run; } mid_release(mid); DTNMP_DEBUG_EXIT("adm_add_ctrl_run","->.",NULL); } /****************************************************************************** * * \par Function Name: adm_build_mid_str * * \par Constructs a MID string from a nickname and a single additional offset. * * \param[in] flag The MID FLAG byte. * \param[in] nn The nickname string. * \param[in] nn_len The number of SDNVs in the nickname. * \param[in] offset Integer acting as the next (and last) SDNV. * \param[out] mid_str The constructed string. * * \par Notes: * 1. The output string MUST be pre-allocated. This function does not create it. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/27/13 E. Birrane Initial implementation. *****************************************************************************/ void adm_build_mid_str(uint8_t flag, char *nn, int nn_len, int offset, uint8_t *mid_str) { uint8_t *cursor = NULL; Sdnv len; Sdnv off; uint32_t nn_size; uint8_t *tmp = NULL; int size = 0; DTNMP_DEBUG_ENTRY("adm_build_mid_str", "(%d, %s, %d, %d)", flag, nn, nn_len, offset); encodeSdnv(&len, nn_len + 1); encodeSdnv(&off, offset); tmp = utils_string_to_hex((unsigned char*)nn, &nn_size); size = 1 + nn_size + len.length + off.length + 1; if(size > ADM_MID_ALLOC) { DTNMP_DEBUG_ERR("adm_build_mid_str", "Size %d bigger than max MID size of %d.", size, ADM_MID_ALLOC); DTNMP_DEBUG_EXIT("adm_build_mid_str","->.", NULL); MRELEASE(tmp); return; } cursor = mid_str; memcpy(cursor, &flag, 1); cursor += 1; memcpy(cursor, len.text, len.length); cursor += len.length; memcpy(cursor, tmp, nn_size); cursor += nn_size; memcpy(cursor, off.text, off.length); cursor += off.length; memset(cursor, 0, 1); // NULL terminator. DTNMP_DEBUG_EXIT("adm_build_mid_str","->%s", mid_str); MRELEASE(tmp); return; } /****************************************************************************** * * \par Function Name: adm_copy_integer * * \par Copies and serializes integer values of various sizes. * * \retval NULL Failure * !NULL The serialized integer. * * \param[in] value Byte pointer to integer value. * \param[in] size Byte size of integer value. * \param[out] length Size of returned integer copy. * * \par Notes: * 1. The serialized integer copy is allocated on the heap and must be * released when no longer needed. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. * 07/27/13 E. Birrane Hold data defs in a Lyst. * *****************************************************************************/ uint8_t *adm_copy_integer(uint8_t *value, uint8_t size, uint64_t *length) { uint8_t *result = NULL; DTNMP_DEBUG_ENTRY("adm_copy_integer","(%#llx, %d, %#llx)", value, size, length); /* Step 0 - Sanity Check. */ if((value == NULL) || (size <= 0) || (length == NULL)) { DTNMP_DEBUG_ERR("adm_copy_integer","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_copy_integer","->NULL.", NULL); return NULL; } /* Step 1 - Alloc new space. */ if((result = (uint8_t *) MTAKE(size)) == NULL) { DTNMP_DEBUG_ERR("adm_copy_integer","Can't alloc %d bytes.", size); DTNMP_DEBUG_EXIT("adm_copy_integer","->NULL.", NULL); return NULL; } /* Step 2 - Copy data in. */ *length = size; memcpy(result, value, size); /* Step 3 - Return. */ DTNMP_DEBUG_EXIT("adm_copy_integer","->%#llx", result); return (uint8_t*)result; } uint8_t* adm_copy_string(char *value, uint64_t *length) { uint8_t *result = NULL; uint32_t size = 0; DTNMP_DEBUG_ENTRY("adm_copy_string","(%#llx, %d, %#llx)", value, size, length); /* Step 0 - Sanity Check. */ if((value == NULL) || (length == NULL)) { DTNMP_DEBUG_ERR("adm_copy_string","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_copy_string","->NULL.", NULL); return NULL; } size = strlen(value) + 1; /* Step 1 - Alloc new space. */ if((result = (uint8_t *) MTAKE(size)) == NULL) { DTNMP_DEBUG_ERR("adm_copy_string","Can't alloc %d bytes.", size); DTNMP_DEBUG_EXIT("adm_copy_string","->NULL.", NULL); return NULL; } /* Step 2 - Copy data in. */ *length = size; memcpy(result, value, size); /* Step 3 - Return. */ DTNMP_DEBUG_EXIT("adm_copy_string","->%s", (char *)result); return (uint8_t*)result; } void adm_destroy() { LystElt elt = 0; for (elt = lyst_first(gAdmData); elt; elt = lyst_next(elt)) { adm_datadef_t *cur = (adm_datadef_t *) lyst_data(elt); mid_release(cur->mid); MRELEASE(cur); } lyst_destroy(gAdmData); gAdmData = NULL; for (elt = lyst_first(gAdmCtrls); elt; elt = lyst_next(elt)) { adm_ctrl_t *cur = (adm_ctrl_t *) lyst_data(elt); mid_release(cur->mid); MRELEASE(cur); } lyst_destroy(gAdmCtrls); gAdmCtrls = NULL; lyst_destroy(gAdmLiterals); gAdmLiterals = NULL; lyst_destroy(gAdmOps); gAdmOps = NULL; } /****************************************************************************** * * \par Function Name: adm_find_datadef * * \par Find an ADM entry that corresponds to a received MID. * * \retval NULL Failure * !NULL The found ADM entry * * \param[in] mid The MID whose ADM-match is being queried. * * \par Notes: * 1. The returned entry is a direct pointer to the official ADM entry, * it must be treated as read-only. * 2. When the input MID is parameterized, the ADM find function only * matches the non-parameterized portion. * 3. This function is not complete, compare must be made to work when * tag values are in play * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. * 07/27/13 E. Birrane Hold data defs in a Lyst. *****************************************************************************/ adm_datadef_t *adm_find_datadef(mid_t *mid) { LystElt elt = 0; adm_datadef_t *cur = NULL; DTNMP_DEBUG_ENTRY("adm_find_datadef","(%llx)", mid); /* Step 0 - Sanity Check. */ if(mid == NULL) { DTNMP_DEBUG_ERR("adm_find_datadef", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_find_datadef", "->NULL.", NULL); return NULL; } /* Step 1 - Go lookin'. */ for(elt = lyst_first(gAdmData); elt; elt = lyst_next(elt)) { cur = (adm_datadef_t*) lyst_data(elt); /* Step 1.1 - Determine if we need to account for parameters. */ if (mid_compare(mid, cur->mid, 0) == 0) { break; } /** if(cur->num_parms == 0) { / * Step 1.1.1 - If no params, straight compare * / if((mid->raw_size == cur->mid_len) && (memcmp(mid->raw, cur->mid, mid->raw_size) == 0)) { break; } } else { uvast tmp; unsigned char *cursor = (unsigned char*) &(cur->mid[1]); / * Grab size less paramaters. Which is SDNV at [1]. * / / * \todo: We need a more refined compare here. For example, the * code below will not work if tag values are used. * / unsigned long byte = decodeSdnv(&tmp, cursor); if(memcmp(mid->raw, cur->mid, tmp + byte + 1) == 0) { break; } } */ cur = NULL; } /* Step 2 - Return what we found, or NULL. */ DTNMP_DEBUG_EXIT("adm_find_datadef", "->%llx.", cur); return cur; } /****************************************************************************** * * \par Function Name: adm_find_datadef_by_name * * \par Find an ADM entry that corresponds to a user-readable name. * * \retval NULL Failure * !NULL The found ADM entry * * \param[in] name The name whose ADM-match is being queried. * * \par Notes: * 1. The returned entry is a direct pointer to the official ADM entry, * it must be treated as read-only. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/27/13 E. Birrane Initial implementation. *****************************************************************************/ adm_datadef_t* adm_find_datadef_by_name(char *name) { LystElt elt = 0; adm_datadef_t *cur = NULL; DTNMP_DEBUG_ENTRY("adm_find_datadef_by_name","(%s)", name); /* Step 0 - Sanity Check. */ if(name == NULL) { DTNMP_DEBUG_ERR("adm_find_datadef_by_name", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_find_datadef_by_name", "->NULL.", NULL); return NULL; } /* Step 1 - Go lookin'. */ for(elt = lyst_first(gAdmData); elt; elt = lyst_next(elt)) { cur = (adm_datadef_t*) lyst_data(elt); if(memcmp(name, cur->name, strlen(cur->name)) == 0) { break; } cur = NULL; } /* Step 2 - Return what we found, or NULL. */ DTNMP_DEBUG_EXIT("adm_find_datadef_by_name", "->%llx.", cur); return cur; } adm_datadef_t* adm_find_datadef_by_idx(int idx) { LystElt elt = 0; int i = 0; adm_datadef_t *cur = NULL; DTNMP_DEBUG_ENTRY("adm_find_datadef_by_name","(%d)", idx); /* Step 1 - Go lookin'. */ for(elt = lyst_first(gAdmData); elt; elt = lyst_next(elt)) { cur = (adm_datadef_t*) lyst_data(elt); if(i == idx) { break; } i++; cur = NULL; } /* Step 2 - Return what we found, or NULL. */ DTNMP_DEBUG_EXIT("adm_find_datadef_by_name", "->%llx.", cur); return cur; } /****************************************************************************** * * \par Function Name: adm_find_ctrl * * \par Find an ADM control that corresponds to a received MID. * * \retval NULL Failure * !NULL The found ADM control * * \param[in] mid The MID whose ADM-match is being queried. * * \par Notes: * 1. The returned entry is a direct pointer to the official ADM control, * it must be treated as read-only. * 2. When the input MID is parameterized, the ADM find function only * matches the non-parameterized portion. * 3. This function is not complete, compare must be made to work when * tag values are in play * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/22/13 E. Birrane Initial implementation. * 07/27/13 E. Birrane Hold data defs in a Lyst. *****************************************************************************/ adm_ctrl_t* adm_find_ctrl(mid_t *mid) { LystElt elt = 0; adm_ctrl_t *cur = NULL; DTNMP_DEBUG_ENTRY("adm_find_ctrl","(%#llx)", mid); /* Step 0 - Sanity Check. */ if(mid == NULL) { DTNMP_DEBUG_ERR("adm_find_ctrl", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_find_ctrl", "->NULL.", NULL); return NULL; } for(elt = lyst_first(gAdmCtrls); elt; elt = lyst_next(elt)) { cur = (adm_ctrl_t *) lyst_data(elt); char *tmp1 = mid_to_string(mid); char *tmp2 = mid_to_string(cur->mid); MRELEASE(tmp1); MRELEASE(tmp2); if (mid_compare(mid, cur->mid, 0) == 0) { break; } /** / * Step 1.1 - Determine if we need to account for parameters. * / if(cur->num_parms == 0) { / * Step 1.1.1 - If no params, straight compare * / if((mid->raw_size == cur->mid_len) && (memcmp(mid->raw, cur->mid, mid->raw_size) == 0)) { break; } } else { uvast tmp; unsigned char *cursor = (unsigned char*) &(cur->mid[1]); / * Grab size less paramaters. Which is SDNV at [1]. * / / * \todo: We need a more refined compare here. For example, the * code below will not work if tag values are used. * / unsigned long bytes = decodeSdnv(&tmp, cursor); if(memcmp(mid->raw, cur->mid, tmp + bytes + 1) == 0) { break; } } */ cur = NULL; } /* Step 2 - Return what we found, or NULL. */ DTNMP_DEBUG_EXIT("adm_find_ctrl", "->%llx.", cur); return cur; } /****************************************************************************** * * \par Function Name: adm_find_ctrl_by_name * * \par Find an ADM control that corresponds to a user-readable name. * * \retval NULL Failure * !NULL The found ADM entry * * \param[in] name The name whose ADM-match is being queried. * * \par Notes: * 1. The returned entry is a direct pointer to the official ADM entry, * it must be treated as read-only. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/27/13 E. Birrane Initial implementation. *****************************************************************************/ adm_ctrl_t* adm_find_ctrl_by_name(char *name) { LystElt elt = 0; adm_ctrl_t *cur = NULL; DTNMP_DEBUG_ENTRY("adm_find_ctrl_by_name","(%s)", name); /* Step 0 - Sanity Check. */ if(name == NULL) { DTNMP_DEBUG_ERR("adm_find_ctrl_by_name", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_find_ctrl_by_name", "->NULL.", NULL); return NULL; } /* Step 1 - Go lookin'. */ for(elt = lyst_first(gAdmData); elt; elt = lyst_next(elt)) { cur = (adm_ctrl_t*) lyst_data(elt); if(memcmp(name, cur->name, strlen(cur->name)) == 0) { break; } cur = NULL; } /* Step 2 - Return what we found, or NULL. */ DTNMP_DEBUG_EXIT("adm_find_ctrl_by_name", "->%llx.", cur); return cur; } adm_ctrl_t* adm_find_ctrl_by_idx(int idx) { LystElt elt = 0; int i = 0; adm_ctrl_t *cur = NULL; DTNMP_DEBUG_ENTRY("adm_find_ctrl_by_idx","(%d)", idx); /* Step 1 - Go lookin'. */ for(elt = lyst_first(gAdmCtrls); elt; elt = lyst_next(elt)) { cur = (adm_ctrl_t*) lyst_data(elt); if(i == idx) { break; } i++; cur = NULL; } /* Step 2 - Return what we found, or NULL. */ DTNMP_DEBUG_EXIT("adm_find_ctrl_by_idx", "->%llx.", cur); return cur; } /****************************************************************************** * * \par Function Name: adm_init * * \par Initialize pre-configured ADMs. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ void adm_init() { DTNMP_DEBUG_ENTRY("adm_init","()", NULL); gAdmData = lyst_create(); gAdmCtrls = lyst_create(); gAdmLiterals = lyst_create(); gAdmOps = lyst_create(); adm_bp_init(); #ifdef _HAVE_LTP_ADM_ adm_ltp_init(); #endif /* _HAVE_LTP_ADM_ */ #ifdef _HAVE_ION_ADM_ adm_ion_init(); #endif /* _HAVE_ION_ADM_ */ adm_agent_init(); //initBpAdm(); //initLtpAdm(); //initIonAdm(); DTNMP_DEBUG_EXIT("adm_init","->.", NULL); } /****************************************************************************** * * \par Function Name: adm_print_string * * \par Performs the somewhat straightforward function of building a string * representation of a string. This is a generic to-string function for * ADM entries whose values are strings. * * \retval NULL Failure * !NULL The string representation of the ADM entry value. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * \param[in] data_len Length of data item at head of the buffer. * \param[out] str_len Length of returned string from print function. * * \par Notes: * 1. The string representation is allocated on the heap and must be * freed when no longer necessary. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ char *adm_print_string(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { char *result = NULL; uint32_t len = 0; DTNMP_DEBUG_ENTRY("adm_print_string","(%#llx, %ull, %ull, %#llx)", buffer, buffer_len, data_len, str_len); /* Step 0 - Sanity Checks. */ if((buffer == NULL) || (str_len == NULL)) { DTNMP_DEBUG_ERR("adm_print_string", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_print_string", "->NULL.", NULL); return NULL; } /* Step 1 - Data at head of buffer should be a string. Grab len & check. */ len = strlen((char*) buffer); if((len < 0) || (len > buffer_len) || (len != data_len)) { DTNMP_DEBUG_ERR("adm_print_string", "Bad len %d. Expected %d.", len, data_len); DTNMP_DEBUG_EXIT("adm_print_string", "->NULL.", NULL); return NULL; } /* Step 2 - Allocate size for string rep. of the string value. */ *str_len = len + 1; if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("adm_print_string", "Can't alloc %d bytes", *str_len); DTNMP_DEBUG_EXIT("adm_print_string", "->NULL.", NULL); return NULL; } /* Step 3 - Copy over. */ sprintf(result,"%s", (char*) buffer); DTNMP_DEBUG_EXIT("adm_print_string", "->%s.", result); return result; } /****************************************************************************** * * \par Function Name: adm_print_string_list * * \par Generates a single string representation of a list of strings. * * \retval NULL Failure * !NULL The string representation of the ADM entry value. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * \param[in] data_len Length of data item at head of the buffer. * \param[out] str_len Length of returned string from print function. * * \par Notes: * 1. The string representation is allocated on the heap and must be * freed when no longer necessary. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ char *adm_print_string_list(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { char *result = NULL; char *cursor = NULL; uint8_t *buf_ptr = NULL; uvast num = 0; int len = 0; DTNMP_DEBUG_ENTRY("adm_print_string_list", "(%#llx, %ull, %ull, %#llx)", buffer, buffer_len, data_len, str_len); /* Step 0 - Sanity Checks. */ if((buffer == NULL) || (str_len == NULL)) { DTNMP_DEBUG_ERR("adm_print_string_list", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_print_string_list", "->NULL.", NULL); return NULL; } /* Step 1 - Figure out size of resulting string. */ buf_ptr = buffer; len = decodeSdnv(&num, buf_ptr); buf_ptr += len; *str_len = data_len + /* String length */ 9 + /* Header info. */ (2 * len) + /* ", " per string */ 1; /* Trailer. */ /* Step 2 - Allocate the result. */ if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("adm_print_string_list","Can't alloc %d bytes", *str_len); *str_len = 0; DTNMP_DEBUG_EXIT("adm_print_string_list", "->NULL.", NULL); return NULL; } /* Step 3 - Accumulate the result. */ cursor = result; cursor += sprintf(cursor,"("UVAST_FIELDSPEC"): ",num); /* Add stirngs to result. */ int i; for(i = 0; i < num; i++) { cursor += sprintf(cursor, "%s, ",buf_ptr); buf_ptr += strlen((char*)buf_ptr) + 1; } DTNMP_DEBUG_EXIT("adm_print_string_list", "->%#llx.", result); return result; } /****************************************************************************** * * \par Function Name: adm_print_unsigned_long * * \par Generates a single string representation of an unsigned long. * * \retval NULL Failure * !NULL The string representation of the ADM entry value. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * \param[in] data_len Length of data item at head of the buffer. * \param[out] str_len Length of returned string from print function. * * \par Notes: * 1. The string representation is allocated on the heap and must be * freed when no longer necessary. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ char *adm_print_unsigned_long(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { char *result; uint64_t temp = 0; DTNMP_DEBUG_ENTRY("adm_print_unsigned_long", "(%#llx, %ull, %ull, %#llx)", buffer, buffer_len, data_len, str_len); /* Step 0 - Sanity Checks. */ if((buffer == NULL) || (str_len == NULL)) { DTNMP_DEBUG_ERR("adm_print_unsigned_long", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_print_unsigned_long", "->NULL.", NULL); return NULL; } /* Step 1 - Make sure we have buffer space. */ if(data_len > buffer_len) { DTNMP_DEBUG_ERR("adm_print_unsigned_long","Data Len %d > buf len %d.", data_len, buffer_len); *str_len = 0; DTNMP_DEBUG_EXIT("adm_print_unsigned_long", "->NULL.", NULL); return NULL; } /* Step 2 - Size the string and allocate it. * \todo: A better estimate should go here. */ *str_len = 22; if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("adm_print_unsigned_long","Can't alloc %d bytes.", *str_len); *str_len = 0; DTNMP_DEBUG_EXIT("adm_print_unsigned_long", "->NULL.", NULL); return NULL; } /* Step 3 - Copy data and return. */ memcpy(&temp, buffer, data_len); isprintf(result,*str_len,"%ld", temp); DTNMP_DEBUG_EXIT("adm_print_unsigned_long", "->%#llx.", result); return result; } /****************************************************************************** * * \par Function Name: adm_print_unsigned_long_list * * \par Generates a single string representation of a list of unsigned longs. * * \retval NULL Failure * !NULL The string representation of the ADM entry value. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * \param[in] data_len Length of data item at head of the buffer. * \param[out] str_len Length of returned string from print function. * * \par Notes: * 1. The string representation is allocated on the heap and must be * freed when no longer necessary. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ char *adm_print_unsigned_long_list(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { char *result = NULL; char *cursor = NULL; uint8_t *buf_ptr = NULL; uvast num = 0; unsigned long val = 0; int len = 0; DTNMP_DEBUG_ENTRY("adm_print_unsigned_long_list", "(%#llx, %ull, %ull, %#llx)", buffer, buffer_len, data_len, str_len); /* Step 0 - Sanity Checks. */ if((buffer == NULL) || (str_len == NULL)) { DTNMP_DEBUG_ERR("adm_print_unsigned_long_list", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_print_unsigned_long_list", "->NULL.", NULL); return NULL; } /* Step 1 - Figure out how many unsigned longs we need to print out. */ buf_ptr = buffer; len = decodeSdnv(&num, buf_ptr); buf_ptr += len; /* Step 2 - Size & allocate the string. */ *str_len = data_len + /* Data length */ 9 + /* Header info. */ (2 * len) + /* ", " per number */ 1; /* Trailer. */ if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("adm_print_unsigned_long_list", "Can't alloc %d bytes.", *str_len); *str_len = 0; DTNMP_DEBUG_EXIT("adm_print_unsigned_long_list", "->NULL.", NULL); return NULL; } /* Step 3 - Accumulate string result. */ cursor = result; cursor += sprintf(cursor,"("UVAST_FIELDSPEC"): ",num); int i; for(i = 0; i < num; i++) { memcpy(&val, buf_ptr, sizeof(val)); buf_ptr += sizeof(val); cursor += sprintf(cursor, "%ld, ",val); } DTNMP_DEBUG_EXIT("adm_print_unsigned_long_list", "->%#llx.", result); return result; } /****************************************************************************** * * \par Function Name: adm_print_uvast * * \par Generates a single string representation of a uvast. * * \retval NULL Failure * !NULL The string representation of the ADM entry value. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * \param[in] data_len Length of data item at head of the buffer. * \param[out] str_len Length of returned string from print function. * * \par Notes: * 1. The string representation is allocated on the heap and must be * freed when no longer necessary. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/16/13 E. Birrane Initial implementation. *****************************************************************************/ char *adm_print_uvast(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { char *result; uint64_t temp = 0; DTNMP_DEBUG_ENTRY("adm_print_uvast", "(%#llx, %ull, %ull, %#llx)", buffer, buffer_len, data_len, str_len); /* Step 0 - Sanity Checks. */ if((buffer == NULL) || (str_len == NULL)) { DTNMP_DEBUG_ERR("adm_print_uvast", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_print_uvast", "->NULL.", NULL); return NULL; } /* Step 1 - Make sure we have buffer space. */ if(data_len > buffer_len) { DTNMP_DEBUG_ERR("adm_print_uvast","Data Len %d > buf len %d.", data_len, buffer_len); *str_len = 0; DTNMP_DEBUG_EXIT("adm_print_uvast", "->NULL.", NULL); return NULL; } /* Step 2 - Size the string and allocate it. * \todo: A better estimate should go here. */ *str_len = 32; if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("adm_print_uvast","Can't alloc %d bytes.", *str_len); *str_len = 0; DTNMP_DEBUG_EXIT("adm_print_uvast", "->NULL.", NULL); return NULL; } /* Step 3 - Copy data and return. */ memcpy(&temp, buffer, data_len); isprintf(result,*str_len,UVAST_FIELDSPEC, temp); DTNMP_DEBUG_EXIT("adm_print_uvast", "->%#llx.", result); return result; } /****************************************************************************** * * \par Function Name: adm_size_string * * \par Calculates size of a string, as an ADM sizing callback. * * \retval Size of the ADM value entry. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ uint32_t adm_size_string(uint8_t* buffer, uint64_t buffer_len) { uint32_t len = 0; DTNMP_DEBUG_ENTRY("adm_size_string","(%#llx, %ull)", buffer, buffer_len); /* Step 0 - Sanity Check. */ if(buffer == NULL) { DTNMP_DEBUG_ERR("adm_size_string","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_size_string","->0.", NULL); return 0; } len = strlen((char*) buffer); if(len > buffer_len) { DTNMP_DEBUG_ERR("adm_size_string","Bad len: %ul > %ull.", len, buffer_len); DTNMP_DEBUG_EXIT("adm_size_string","->0.", NULL); return 0; } DTNMP_DEBUG_EXIT("adm_size_string","->%ul", len); return len; } /****************************************************************************** * * \par Function Name: adm_size_string_list * * \par Calculates size of a string list, as an ADM sizing callback. * * \retval Size of the ADM value entry. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ uint32_t adm_size_string_list(uint8_t* buffer, uint64_t buffer_len) { uint32_t result = 0; uvast num = 0; uint8_t *cursor = NULL; int tmp = 0; DTNMP_DEBUG_ENTRY("adm_size_string_list","(%#llx, %ull)", buffer, buffer_len); /* Step 0 - Sanity Check. */ if(buffer == NULL) { DTNMP_DEBUG_ERR("adm_size_string_list","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_size_string_list","->0.", NULL); return 0; } /* Step 1 - Figure out # strings. */ result = decodeSdnv(&num, buffer); cursor = buffer + result; /* Add up the strings to calculate length. */ int i; for(i = 0; i < num; i++) { tmp = strlen((char *)cursor) + 1; result += tmp; cursor += tmp; } DTNMP_DEBUG_EXIT("adm_size_string_list", "->%ul", result); return result; } /****************************************************************************** * * \par Function Name: adm_size_unsigned_long * * \par Calculates size of an unsigned long, as an ADM sizing callback. * * \retval Size of the ADM value entry. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ uint32_t adm_size_unsigned_long(uint8_t* buffer, uint64_t buffer_len) { uint32_t len = 0; DTNMP_DEBUG_ENTRY("adm_size_unsigned_long","(%#llx, %ull)", buffer, buffer_len); /* Step 0 - Sanity Check. */ if(buffer == NULL) { DTNMP_DEBUG_ERR("adm_size_unsigned_long","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_size_unsigned_long","->0.", NULL); return 0; } DTNMP_DEBUG_EXIT("adm_size_string","->%ul", sizeof(unsigned long)); return sizeof(unsigned long); } /****************************************************************************** * * \par Function Name: adm_size_unsigned_long_list * * \par Calculates size of a list of unsigned long, as an ADM sizing callback. * * \retval Size of the ADM value entry. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. *****************************************************************************/ uint32_t adm_size_unsigned_long_list(uint8_t* buffer, uint64_t buffer_len) { uint32_t result = 0; uvast num = 0; DTNMP_DEBUG_ENTRY("adm_size_unsigned_long","(%#llx, %ull)", buffer, buffer_len); /* Step 0 - Sanity Check. */ if(buffer == NULL) { DTNMP_DEBUG_ERR("adm_size_unsigned_long","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_size_unsigned_long","->0.", NULL); return 0; } /* Step 1 - Calculate size. This is size of the SDNV, plus size of the * "num" of unsigned longs after the SDNV. */ result = decodeSdnv(&num, buffer); result += (num * sizeof(unsigned long)); DTNMP_DEBUG_EXIT("adm_size_string","->%ul", result); return result; } /****************************************************************************** * * \par Function Name: adm_size_uvast * * \par Calculates size of a uvast, as an ADM sizing callback. * * \retval Size of the ADM value entry. * * \param[in] buffer The start of the ADM entry value. * \param[in] buffer_len Length of the given buffer. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/16/13 E. Birrane Initial implementation. *****************************************************************************/ uint32_t adm_size_uvast(uint8_t* buffer, uint64_t buffer_len) { uint32_t len = 0; DTNMP_DEBUG_ENTRY("adm_size_uvast","(%#llx, %ull)", buffer, buffer_len); /* Step 0 - Sanity Check. */ if(buffer == NULL) { DTNMP_DEBUG_ERR("adm_size_uvast","Bad Args.", NULL); DTNMP_DEBUG_EXIT("adm_size_uvast","->0.", NULL); return 0; } DTNMP_DEBUG_EXIT("adm_size_uvast","->%ul", sizeof(uvast)); return sizeof(uvast); } ion-3.2.0~dfsg1.orig/nm/shared/adm/adm_ltp.h0000644000175000017500000000323612260400056017104 0ustar l3onl3on// // adm_bp.h // // Created by Birrane, Edward J. on 10/22/11. // Copyright 2011 __MyCompanyName__. All rights reserved. // #ifndef ADM_LTP_H_ #define ADM_LTP_H_ #ifdef _HAVE_LTP_ADM_ #include "lyst.h" #include "ltpnm.h" #include "shared/utils/nm_types.h" #include "shared/adm/adm.h" /* * We will invent an OID space for LTP ADM information, to live at: * * iso.identified-organization.dod.internet.mgmt.dtnmp.ltp * or 1.3.6.1.2.3.2 * or, as OID,: 2B 06 01 02 03 02 * * Note: dtnmp.ltp is a made-up subtree. */ /* * Structure: * * ADM_LTP_ROOT (2A0601020302) * | * NODE (01) | ENGINE (02) * +-----------------------+ * | | */ static char* ADM_LTP_ROOT = "2B0601020302"; #define ADM_LTP_ROOT_LEN (6) static char* ADM_LTP_NODE_NN = "2B060102030201"; #define ADM_LTP_NODE_NN_LEN (7) static char* ADM_LTP_ENGINE_NN = "2B060102030202"; #define ADM_LTP_ENGINE_NN_LEN (7) static char* ADM_LTP_CTRL_NN = "2B060102030203"; #define ADM_LTP_CTRL_NN_LEN (7) void adm_ltp_init(); /* Print Functions */ char *ltp_print_node_resources_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); char *ltp_engine_print_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); /* SIZE */ uint32_t ltp_size_node_resources_all(uint8_t* buffer, uint64_t buffer_len); uint32_t ltp_size_heap_bytes_reserved(uint8_t* buffer, uint64_t buffer_len); uint32_t ltp_size_heap_bytes_used(uint8_t* buffer, uint64_t buffer_len); uint32_t ltp_engine_size(uint8_t* buffer, uint64_t buffer_len); #endif /* _HAVE_LTP_ADM */ #endif //ADM_LTP_H_ ion-3.2.0~dfsg1.orig/nm/shared/adm/adm_ltp.c0000644000175000017500000002204012260400056017071 0ustar l3onl3on#ifdef _HAVE_LTP_ADM_ #include "platform.h" #include "ion.h" #include "shared/utils/utils.h" #include "shared/adm/adm_ltp.h" void adm_ltp_init() { uint8_t mid_str[ADM_MID_ALLOC]; adm_build_mid_str(0x00, ADM_LTP_NODE_NN, ADM_LTP_NODE_NN_LEN, 0, mid_str); adm_add_datadef("LTP_NODE_RESOURCES_ALL", mid_str, 0, ltp_print_node_resources_all, ltp_size_node_resources_all); adm_build_mid_str(0x00, ADM_LTP_NODE_NN, ADM_LTP_NODE_NN_LEN, 1, mid_str); adm_add_datadef("LTP_HEAP_BYTES_RSV", mid_str, 0, NULL, ltp_size_heap_bytes_reserved); adm_build_mid_str(0x00, ADM_LTP_NODE_NN, ADM_LTP_NODE_NN_LEN, 2, mid_str); adm_add_datadef("LTP_HEAD_BYTES_USED", mid_str, 0, NULL, ltp_size_heap_bytes_used); adm_build_mid_str(0x00, ADM_LTP_NODE_NN, ADM_LTP_NODE_NN_LEN, 3, mid_str); adm_add_datadef("LTP_ENGINE_IDS", mid_str, 0, adm_print_unsigned_long_list, adm_size_unsigned_long_list); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 0, mid_str); adm_add_datadef("LTP_ENG_ALL", mid_str, 1, adm_print_unsigned_long_list, ltp_engine_size); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 1, mid_str); adm_add_datadef("LTP_ENG_NUM", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 2, mid_str); adm_add_datadef("LTP_ENG_EXP_SESS", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 3, mid_str); adm_add_datadef("LTP_ENG_CUR_OUT_SEG", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 4, mid_str); adm_add_datadef("LTP_ENG_CUR_IMP_SESS", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 5, mid_str); adm_add_datadef("LTP_ENG_CUR_IN_SEG", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 6, mid_str); adm_add_datadef("LTP_ENG_LAST_RESET_TIME", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 7, mid_str); adm_add_datadef("LTP_ENG_OUT_SEG_Q_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 8, mid_str); adm_add_datadef("LTP_ENG_OUT_SEG_Q_BYTE", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 9, mid_str); adm_add_datadef("LTP_ENG_OUT_SEG_POP_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 10, mid_str); adm_add_datadef("LTP_ENG_OUT_SEG_POP_BYTE", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 11, mid_str); adm_add_datadef("LTP_ENG_OUT_CKP_XMIT_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 12, mid_str); adm_add_datadef("LTP_ENG_OUT_POS_ACK_RCV_CNT",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 13, mid_str); adm_add_datadef("LTP_ENG_OUT_NEG_ACK_RCV_CNT",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 14, mid_str); adm_add_datadef("LTP_ENG_OUT_CANC_RCV_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 15, mid_str); adm_add_datadef("LTP_ENG_OUT_CKP_REXMT_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 16, mid_str); adm_add_datadef("LTP_ENG_OUT_CANC_XMIT_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 17, mid_str); adm_add_datadef("LTP_ENG_OUT_COMPL_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 18, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_RCV_RED_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 19, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_RCV_RED_BYTE",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 20, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_RCV_GRN_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 21, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_RCV_GRN_BYTE",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 22, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_RDNDT_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 23, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_RDNDT_BYTE", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 24, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_MAL_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 25, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_MAL_BYTE", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 26, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_UNK_SND_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 27, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_UNK_SND_BYTE",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 28, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_UNK_CLI_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 29, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_UNK_CLI_BYTE",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 30, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_STRAY_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 31, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_STRAY_BYTE", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 32, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_MISCOL_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 33, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_MISCOL_BYTE", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 34, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_CLSD_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 35, mid_str); adm_add_datadef("LTP_ENG_IN_SEG_CLSD_BYTE", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 36, mid_str); adm_add_datadef("LTP_ENG_IN_CKP_RCV_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 37, mid_str); adm_add_datadef("LTP_ENG_IN_POS_ACK_XMIT_CNT",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 38, mid_str); adm_add_datadef("LTP_ENG_IN_NEG_ACK_XMIT_CNT",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 39, mid_str); adm_add_datadef("LTP_ENG_IN_CANC_XMIT_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 40, mid_str); adm_add_datadef("LTP_ENG_IN_ACK_REXMT_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 41, mid_str); adm_add_datadef("LTP_ENG_IN_CANC_RCV_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ADM_LTP_ENGINE_NN, ADM_LTP_ENGINE_NN_LEN, 42, mid_str); adm_add_datadef("LTP_ENG_IN_COMPL_CNT", mid_str, 1, NULL, NULL); adm_build_mid_str(0x41, ADM_LTP_CTRL_NN, ADM_LTP_CTRL_NN_LEN, 0, mid_str); adm_add_ctrl("LTP_ENG_RESET", mid_str, 1); } /* Print Functions */ char *ltp_print_node_resources_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { unsigned long bytes_reserved; unsigned long bytes_used; char *result; uint32_t temp_size = 0; temp_size = 2 * sizeof(unsigned long); memcpy(&bytes_reserved, buffer, sizeof(bytes_reserved)); memcpy(&bytes_used, &(buffer[sizeof(bytes_reserved)]), sizeof(bytes_used)); // Assume for now a 4 byte integer takes <= 20 characters. // Assume all the text strings average less than 25 characters per string. *str_len = (data_len * 5) + (25 * 2); // Assume for now a 4 byte integer takes <= 20 characters to print. if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("ltpPrintNodeResourceAll","Can't allocate %d bytes", *str_len); *str_len = 0; return NULL; } memset(result, '\0', *str_len); sprintf(result, "\nheapBytesReserved = %ld\nheapBytesOccupied = %ld\n", bytes_reserved, bytes_used); return result; } char *ltp_engine_print_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { } /* SIZE */ uint32_t ltp_size_node_resources_all(uint8_t* buffer, uint64_t buffer_len) { return (sizeof(unsigned long) * 2); } uint32_t ltp_size_heap_bytes_reserved(uint8_t* buffer, uint64_t buffer_len) { return sizeof(unsigned long); } uint32_t ltp_size_heap_bytes_used(uint8_t* buffer, uint64_t buffer_len) { return sizeof(unsigned long); } uint32_t ltp_engine_size(uint8_t* buffer, uint64_t buffer_len) { return sizeof(NmltpSpan); } #endif /* _HAVE_LTP_ADM */ ion-3.2.0~dfsg1.orig/nm/shared/adm/adm_bp.c0000644000175000017500000003520412260400056016701 0ustar l3onl3on#include "ion.h" #include "lyst.h" #include "platform.h" #include "shared/adm/adm_bp.h" #include "shared/utils/utils.h" void adm_bp_init() { /* Node-specific Information. */ uint8_t mid_str[ADM_MID_ALLOC]; adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 0, mid_str); adm_add_datadef("BP_NODE_ALL", mid_str, 0, bp_print_node_all, bp_size_node_all); /* Node State Information */ adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 1, mid_str); adm_add_datadef("BP NODE ID", mid_str, 0, adm_print_string, adm_size_string/*bp_size_node_id*/); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 2, mid_str); adm_add_datadef("BP_NODE_VER", mid_str, 0, adm_print_string, adm_size_string/*bp_size_node_version*/); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 3, mid_str); adm_add_datadef("BP_NODE_AVAIL_STOR", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 4, mid_str); adm_add_datadef("BP_NODE_LAST_RESET_TIME", mid_str, 0, NULL, bp_size_node_restart_time); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 5, mid_str); adm_add_datadef("BP_NODE_NUM_REG", mid_str, 0, NULL, bp_size_node_num_reg); /* Bundle State Information */ adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 6, mid_str); adm_add_datadef("BP_BNDL_CUR_FWD_PEND_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 7, mid_str); adm_add_datadef("BP_BNDL_CUR_DISPATCH_PEND_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 8, mid_str); adm_add_datadef("BP_BNDL_CUR_IN_CUSTODY_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 9, mid_str); adm_add_datadef("BP_BNDL_CUR_REASSMBL_PEND_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 10, mid_str); adm_add_datadef("BP_BNDL_CUR_BULK_RES_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 11, mid_str); adm_add_datadef("BP_BNDL_CUR_NORM_RES_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 12, mid_str); adm_add_datadef("BP_BNDL_CUR_EXP_RES_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 13, mid_str); adm_add_datadef("BP_BNDL_CUR_BULK_RES_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 14, mid_str); adm_add_datadef("BP_BNDL_CUR_NORM_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 15, mid_str); adm_add_datadef("BP_BNDL_CUR_EXP_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 16, mid_str); adm_add_datadef("BP_BNDL_BULK_SRC_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 17, mid_str); adm_add_datadef("BP_BNDL_NORM_SRC_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 18, mid_str); adm_add_datadef("BP_BNDL_EXP_SRC_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 19, mid_str); adm_add_datadef("BP_BNDL_BULK_SRC_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 20, mid_str); adm_add_datadef("BP_BNDL_NORM_SRC_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 21, mid_str); adm_add_datadef("BP_BNDL_EXP_SRC_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 22, mid_str); adm_add_datadef("BP_BNDL_FRAGMENTED_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 23, mid_str); adm_add_datadef("BP_BNDL_FRAG_PRODUCED", mid_str, 0, NULL, NULL); /* Error and Reporting Information */ adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 24, mid_str); adm_add_datadef("BP_RPT_NOINFO_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 25, mid_str); adm_add_datadef("BP_RPT_EXPIRED_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 26, mid_str); adm_add_datadef("BP_RPT_UNI_FWD_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 27, mid_str); adm_add_datadef("BP_RPT_CANCEL_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 28, mid_str); adm_add_datadef("BP_RPT_NO_STRG_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 29, mid_str); adm_add_datadef("BP_RPT_BAD_EID_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 30, mid_str); adm_add_datadef("BP_RPT_NO_ROUTE_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 31, mid_str); adm_add_datadef("BP_RPT_NO_CONTACT_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 32, mid_str); adm_add_datadef("BP_RPT_BAD_BLOCK_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 33, mid_str); adm_add_datadef("BP_RPT_BUNDLES_DEL_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 34, mid_str); adm_add_datadef("BP_RPT_FAIL_CUST_XFER_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 35, mid_str); adm_add_datadef("BP_RPT_FAIL_CUST_XFER_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 36, mid_str); adm_add_datadef("BP_RPT_FAIL_FWD_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 37, mid_str); adm_add_datadef("BP_RPT_FAIL_FWD_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 38, mid_str); adm_add_datadef("BP_RPT_ABANDONED_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 39, mid_str); adm_add_datadef("BP_RPT_ABANDONED_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 40, mid_str); adm_add_datadef("BP_RPT_DISCARD_CNT", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 41, mid_str); adm_add_datadef("BP_RPT_DISCARD_BYTES", mid_str, 0, NULL, NULL); adm_build_mid_str(0, BP_ADM_DATA_NN, BP_ADM_DATA_NN_LEN, 42, mid_str); adm_add_datadef("BP_NODE_ENDPOINT_NAMES", mid_str, 0, adm_print_string_list, adm_size_string_list); /* Endpoint-Specific Information */ adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 0, mid_str); adm_add_datadef("BP_ENDPT_ALL", mid_str, 1, bp_print_endpoint_all, bp_size_endpoint_all); adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 1, mid_str); adm_add_datadef("BP_ENDPT_NAME", mid_str, 1, adm_print_string, bp_size_endpoint_name); adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 2, mid_str); adm_add_datadef("BP_ENDPT_ACTIVE", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 3, mid_str); adm_add_datadef("BP_ENDPT_SINGLETON", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, BP_ADM_DATA_END_NN, BP_ADM_DATA_END_NN_LEN, 4, mid_str); adm_add_datadef("BP_ENDPT_ABANDON_ON_DEL_FAIL", mid_str, 1, NULL, NULL); /* Controls */ adm_build_mid_str(0x01, BP_ADM_DATA_CTRL_NN, BP_ADM_DATA_CTRL_NN_LEN, 0, mid_str); adm_add_ctrl("BP_NODE_RESET_COUNTS", mid_str, 0); } char *bp_print_node_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { NmbpNode node_state; NmbpDisposition state; char *result; char temp[256]; memcpy(&node_state, buffer, sizeof(node_state)); memcpy(&state, buffer+sizeof(node_state), sizeof(state)); // Assume for now a 8 byte integer takes <= 20 characters. // Assume all the text strings average less than 30 characters per string. *str_len = (20 * 40) + (30 * 60); if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("bp_print_node_all","Can't allocate %d bytes.", *str_len); *str_len = 0; return NULL; } memset(result,0,*str_len); memset(temp,0,256); snprintf(temp, 256, "\n\nNode State Information\n------------------------------"); strncat(result,temp,256); snprintf(temp, 256, "\nNode ID = %s \ \nNode Version = %s \ \nAvailable Storage = " UVAST_FIELDSPEC " \ \nLast Restart Time = " UVAST_FIELDSPEC " \ \n# Registrations = %d", node_state.nodeID, node_state.bpVersionNbr, node_state.avblStorage, (uvast)node_state.lastRestartTime, node_state.nbrOfRegistrations); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\n\nBundle Retention Counts\n------------------------------"); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\nForward Pending = " UVAST_FIELDSPEC " \ \nDispatch Pending = " UVAST_FIELDSPEC " \ \nCustody Accepted = " UVAST_FIELDSPEC " \ \nReassemby Pending = " UVAST_FIELDSPEC, state.currentForwardPending, state.currentDispatchPending, state.currentInCustody, state.currentReassemblyPending); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\n\nPriority Counts\n------------------------------"); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\nBulk Sources Count = " UVAST_FIELDSPEC " \ \nNormal Sourced Count = " UVAST_FIELDSPEC " \ \nExpedited Sourced Count = " UVAST_FIELDSPEC, state.bundleSourceCount[0], state.bundleSourceCount[1], state.bundleSourceCount[2]); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\nBulk Sources Bytes = " UVAST_FIELDSPEC " \ \nNormal Sourced Bytes = " UVAST_FIELDSPEC " \ \nExpedited Sourced Bytes = " UVAST_FIELDSPEC, state.bundleSourceBytes[0], state.bundleSourceBytes[1], state.bundleSourceBytes[2]); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\nBulk Resident Count = " UVAST_FIELDSPEC " \ \nNormal Resident Count = " UVAST_FIELDSPEC " \ \nExpedited Resident Count = " UVAST_FIELDSPEC, state.currentResidentCount[0], state.currentResidentCount[1], state.currentResidentCount[2]); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\nBulk Resident Bytes = " UVAST_FIELDSPEC " \ \nNormal Resident Bytes = " UVAST_FIELDSPEC " \ \nExpedited Resident Bytes = " UVAST_FIELDSPEC, state.currentResidentBytes[0], state.currentResidentBytes[1], state.currentResidentBytes[2]); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\n\nFragmentation Counts\n------------------------------"); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\nBundles Fragmented = " UVAST_FIELDSPEC " \ \nFragments Produced = " UVAST_FIELDSPEC, state.bundlesFragmented, state.fragmentsProduced); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\n\nBundle Deletion Counts By Reason\n------------------------------"); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\nNo Info = " UVAST_FIELDSPEC " \ \nExpired = " UVAST_FIELDSPEC " \ \nUnicast Fwd = " UVAST_FIELDSPEC " \ \nCancelled = " UVAST_FIELDSPEC " \ \nNo Storage = " UVAST_FIELDSPEC " \ \nBad EID = " UVAST_FIELDSPEC " \ \nNo Route = " UVAST_FIELDSPEC " \ \nNo Contact = " UVAST_FIELDSPEC " \ \nBad Block = " UVAST_FIELDSPEC " \ \nTotal Bytes = " UVAST_FIELDSPEC, state.delNoneCount, state.delExpiredCount, state.delFwdUnidirCount, state.delCanceledCount, state.delDepletionCount, state.delEidMalformedCount, state.delNoRouteCount, state.delNoContactCount, state.delBlkMalformedCount, state.bytesDeletedToDate); strncat(result,temp,256); memset(temp,0,256); snprintf(temp,256, "\n\nBundle Processing Errors\n------------------------------"); strncat(result,temp,256); memset(temp,0,256); snprintf(temp, 256, "\nNo Custody Count = " UVAST_FIELDSPEC " \ \nNo Custody Bytes = " UVAST_FIELDSPEC " \ \nFwd Failed Count = " UVAST_FIELDSPEC " \ \nFwd Failed Bytes = " UVAST_FIELDSPEC " \ \nAbandoned Count = " UVAST_FIELDSPEC " \ \nAbandoned Bytes = " UVAST_FIELDSPEC " \ \nDiscarded Count = " UVAST_FIELDSPEC " \ \nDiscarded Bytes = " UVAST_FIELDSPEC, state.custodyRefusedCount, state.custodyRefusedBytes, state.bundleFwdFailedCount, state.bundleFwdFailedBytes, state.bundleAbandonCount, state.bundleAbandonBytes, state.bundleDiscardCount, state.bundleDiscardBytes); strncat(result,temp,256); return result; } char *bp_print_endpoint_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { NmbpEndpoint endpoint; char *result; char temp[256]; uint32_t temp_size = 0; memcpy(&endpoint, buffer, data_len); // Assume for now a 8 byte integer takes <= 20 characters. // Assume all the text strings average less than 100 characters per string. temp_size = (sizeof(uvast)*20) + 1; *str_len = (3 * temp_size) + (100 * 1); if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("bp_endpoint_print_all","Can't allocate %d bytes.", *str_len); *str_len = 0; return NULL; } memset(result, 0, *str_len); memset(temp,0,256); sprintf(temp, "\nName = %s \ \nActive = %d \ \nSingleton = %d \ \nAbandon = %d", endpoint.eid, endpoint.active, endpoint.singleton, endpoint.abandonOnDelivFailure); strcat(result,temp); return result; } /* SIZE */ uint32_t bp_size_node_all(uint8_t* buffer, uint64_t buffer_len) { NmbpNode node_state; NmbpDisposition state; return sizeof(state) + sizeof(node_state); } uint32_t bp_size_endpoint_all(uint8_t* buffer, uint64_t buffer_len) { NmbpEndpoint endpoint; return sizeof(endpoint); } uint32_t bp_size_node_id(uint8_t* buffer, uint64_t buffer_len) { NmbpNode node; return sizeof(node.nodeID); } uint32_t bp_size_node_version(uint8_t* buffer, uint64_t buffer_len) { NmbpNode node; return sizeof(node.bpVersionNbr); } uint32_t bp_size_node_restart_time(uint8_t* buffer, uint64_t buffer_len) { NmbpNode node; return sizeof(node.lastRestartTime); } uint32_t bp_size_node_num_reg(uint8_t* buffer, uint64_t buffer_len) { NmbpNode node; return sizeof(node.nbrOfRegistrations); } uint32_t bp_size_endpoint_name(uint8_t* buffer, uint64_t buffer_len) { NmbpEndpoint endpoint; return sizeof(endpoint.eid); } ion-3.2.0~dfsg1.orig/nm/shared/adm/adm_ion.c0000644000175000017500000002443612260400056017072 0ustar l3onl3on #ifdef _HAVE_ION_ADM_ #include "ion.h" #include "platform.h" #include "shared/adm/adm_ion.h" #include "shared/utils/utils.h" void adm_ion_init() { /* Register Nicknames */ uint8_t mid_str[ADM_MID_ALLOC]; /* ICI */ adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 0, mid_str); adm_add_datadef("ICI_SDR_STATE_ALL", mid_str, 0, ion_print_sdr_state_all, ion_size_sdr_state_all); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 1, mid_str); adm_add_datadef("ICI_SMALL_POOL_SIZE", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 2, mid_str); adm_add_datadef("ICI_SMALL_POOL_FREE", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 3, mid_str); adm_add_datadef("ICI_SMALL_POOL_ALLOC",mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 4, mid_str); adm_add_datadef("ICI_LARGE_POOL_SIZE", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 5, mid_str); adm_add_datadef("ICI_LARGE_POOL_FREE", mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 6, mid_str); adm_add_datadef("ICI_LARGE_POOL_ALLOC",mid_str, 0, NULL, NULL); adm_build_mid_str(0x00, ION_ADM_ICI_NN, ION_ADM_ICI_NN_LEN, 7, mid_str); adm_add_datadef("ICI_UNUSED_SIZE", mid_str, 0, NULL, NULL); /* Inducts */ adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 0, mid_str); adm_add_datadef("ICI_INDUCT_ALL", mid_str, 1, ion_induct_print_all, ion_induct_size_all); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 1, mid_str); adm_add_datadef("ION_INDUCT_NAME", mid_str, 1, adm_print_string, adm_size_string); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 2, mid_str); adm_add_datadef("ION_INDUCT_LAST_RESET", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 3, mid_str); adm_add_datadef("ION_INDUCT_RX_BUNDLES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 4, mid_str); adm_add_datadef("ION_INDUCT_RX_BYTES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 5, mid_str); adm_add_datadef("ION_INDUCT_MAL_BUNDLES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 6, mid_str); adm_add_datadef("ION_INDUCT_MAL_BYTES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 7, mid_str); adm_add_datadef("ION_INDUCT_INAUTH_BUNDLES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 8, mid_str); adm_add_datadef("ION_INDUCT_INAUTH_BYTES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 9, mid_str); adm_add_datadef("ION_INDUCT_OVERFLOW_BUNDLES",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_INDUCT_NN, ION_ADM_INDUCT_NN_LEN, 10, mid_str); adm_add_datadef("ION_INDUCT_OVERFLOW_BYTES", mid_str, 1, NULL, NULL); /* Outducts */ adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 0, mid_str); adm_add_datadef("ION_OUTDUCT_ALL", mid_str, 1, ion_outduct_print_all, ion_outduct_size_all); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 1, mid_str); adm_add_datadef("ION_OUTDUCT_NAME", mid_str, 1, adm_print_string, adm_size_string); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 2, mid_str); adm_add_datadef("ION_OUTDUCT_CUR_QUEUE_BUNDLES",mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 3, mid_str); adm_add_datadef("ION_OUTDUCT_CUR_QUEUE_BYTES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 4, mid_str); adm_add_datadef("ION_OUTDUCT_LAST_RESET", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 5, mid_str); adm_add_datadef("ION_OUTDUCT_ENQUEUED_BUNDLES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 6, mid_str); adm_add_datadef("ION_OUTDUCT_ENQUEUED_BYTES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 7, mid_str); adm_add_datadef("ION_OUTDUCT_DEQUEUED_BUNDLES", mid_str, 1, NULL, NULL); adm_build_mid_str(0x40, ION_ADM_OUTDUCT_NN, ION_ADM_OUTDUCT_NN_LEN, 8, mid_str); adm_add_datadef("ION_OUTDUCT_DEQUEUED_BYTES", mid_str, 1, NULL, NULL); /* Node */ adm_build_mid_str(0x00, ION_ADM_NODE_NN, ION_ADM_NODE_NN_LEN, 0, mid_str); adm_add_datadef("ION_NODE_ALL", mid_str, 0, ion_node_print_all, ion_node_size_all); adm_build_mid_str(0x00, ION_ADM_NODE_NN, ION_ADM_NODE_NN_LEN, 1, mid_str); adm_add_datadef("ION_NODE_INDUCTS", mid_str, 0, adm_print_string_list, adm_size_string_list); adm_build_mid_str(0x00, ION_ADM_NODE_NN, ION_ADM_NODE_NN_LEN, 2, mid_str); adm_add_datadef("ION_NODE_OUTDUCTS",mid_str, 0, adm_print_string_list, adm_size_string_list); /* Controls */ adm_build_mid_str(0x01, ION_ADM_CTRL_NN, ION_ADM_CTRL_NN_LEN, 0, mid_str); adm_add_ctrl("ION_INDUCT_RESET", mid_str, 0); adm_build_mid_str(0x01, ION_ADM_CTRL_NN, ION_ADM_CTRL_NN_LEN, 1, mid_str); adm_add_ctrl("ION_OUTDUCT_RESET", mid_str, 0); } /* Custom Print Functions. */ char *ion_node_print_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { char *result = NULL; char *cursor = NULL; char *inducts = NULL; char *outducts = NULL; uint32_t induct_len = 0; uint32_t outduct_len = 0; uint32_t tmp = 0; induct_len = adm_size_string_list(buffer, buffer_len); inducts = adm_print_string_list(buffer, buffer_len, data_len, &tmp); outduct_len = adm_size_string_list(buffer, buffer_len); outducts = adm_print_string_list(buffer+induct_len, buffer_len-induct_len, data_len, &tmp); *str_len = induct_len + outduct_len + 25; result = (char*) MTAKE(*str_len); cursor = result; sprintf(cursor, "inducts: %s\noutducts: %s\n",inducts, outducts); MRELEASE(inducts); MRELEASE(outducts); return result; } char *ion_print_sdr_state_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { SdrnmState state; char *result; uint32_t temp_size = 0; // \todo: Check sizes. memcpy(&state, buffer, data_len); // Assume for now a 4 byte integer takes <= 20 characters. // Assume all the text strings average less than 25 characters per string. temp_size = 7 * sizeof(unsigned long); *str_len = (temp_size * 5) + (25 * 100); // Assume for now a 4 byte integer takes <= 20 characters to print. if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("iciPrintSdrStateAll","Can;t allocate %d bytes", *str_len); *str_len = 0; return NULL; } memset(result, '\0', *str_len); sprintf(result, "\nsmallPoolSize = %ld\nsmallPoolFree = %ld\nsmallPoolAllocated = %ld\n \ largePoolSize = %ld\nlargePoolFree = %ld\nlargePoolAllocated = %ld\n \ unusedSize = %ld\n",state.smallPoolSize, state.smallPoolFree, state.smallPoolAllocated, state.largePoolSize, state.largePoolFree, state.largePoolAllocated, state.unusedSize); return result; } char *ion_induct_print_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { NmbpInduct induct; char *result; uint32_t temp_size = 0; // \todo: Check sizes. memcpy(&induct, buffer, data_len); // Assume for now a 8 byte integer takes <= 20 characters. // Assume all the text strings average less than 25 characters per string. temp_size = 9 * sizeof(unsigned long); *str_len = (temp_size * 5) + (25 * 100) + strlen(induct.inductName); // Assume for now a 4 byte integer takes <= 20 characters to print. if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("ion_induct_print_all","Can't allocate %d bytes", *str_len); *str_len = 0; return NULL; } memset(result, '\0', *str_len); sprintf(result, "\ninductName = %s\nlastResetTime = %ld\nbundleRecvCount = %ld\n\ bundleMalformedCount = %ld\nbundleMalformedBytes = %ld\nbundleInauthenticCount = %ld\n\ bundleInauthenticBytes = %ld\nbundleOverflowCount = %ld\nbundleOverflowBytes\n", induct.inductName, induct.lastResetTime, induct.bundleRecvCount, induct.bundleRecvBytes, induct.bundleMalformedCount, induct.bundleMalformedBytes, induct.bundleInauthenticCount, induct.bundleInauthenticBytes, induct.bundleOverflowCount, induct.bundleOverflowBytes); return result; } char *ion_outduct_print_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len) { NmbpOutduct outduct; char *result; uint32_t temp_size = 0; // \todo: Check sizes. memcpy(&outduct, buffer, data_len); // Assume for now a 8 byte integer takes <= 20 characters. // Assume all the text strings average less than 25 characters per string. temp_size = 7 * sizeof(unsigned long); *str_len = (temp_size * 5) + (25 * 100) + strlen(outduct.outductName); // Assume for now a 4 byte integer takes <= 20 characters to print. if((result = (char *) MTAKE(*str_len)) == NULL) { DTNMP_DEBUG_ERR("ion_outduct_print_all","Can't allocate %d bytes", *str_len); *str_len = 0; return NULL; } memset(result, '\0', *str_len); sprintf(result, "\noutductName = %s\ncurrentQueuedBundlesCount = %ld\ncurrentQueuedBundlesBytes = %ld\n\ lastResetTime = %ld\nbundleEnqueuedCount = %ld\nbundleEnqueuedBytes = %ld\n\ bundleDequeuedCount = %ld\nbundleDequeuedBytes = %ld\n", outduct.outductName, outduct.currentQueuedBundlesCount, outduct.currentQueuedBundlesBytes, outduct.lastResetTime, outduct.bundleEnqueuedCount, outduct.bundleEnqueuedBytes, outduct.bundleDequeuedCount, outduct.bundleDequeuedBytes); return result; } /* SIZE */ uint32_t ion_induct_size_all(uint8_t* buffer, uint64_t buffer_len) { return sizeof(NmbpInduct); } uint32_t ion_outduct_size_all(uint8_t* buffer, uint64_t buffer_len) { return sizeof(NmbpOutduct); } uint32_t ion_node_size_all(uint8_t* buffer, uint64_t buffer_len) { uint32_t result = 0; result = adm_size_string_list(buffer, buffer_len); result += adm_size_string_list(buffer+result, buffer_len-result); return result; } uint32_t ion_size_sdr_state_all(uint8_t* buffer, uint64_t buffer_len) { SdrnmState state; return sizeof(state); } #endif /* _HAVE_ION_ADM_ */ ion-3.2.0~dfsg1.orig/nm/shared/adm/adm.h0000644000175000017500000001562512260400056016232 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: adm.h ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for the identification and ** processing of Application Data Models (ADMs). ** ** Notes: ** 1) We need to find some more efficient way of querying ADMs by name ** and by MID. The current implementation uses too much stack space. ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/22/11 E. Birrane Initial Implementation ** 11/13/12 E. Birrane Technical review, comment updates. *****************************************************************************/ #ifndef ADM_H_ #define ADM_H_ #include "lyst.h" #include "shared/primitives/mid.h" #include "shared/utils/expr.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ /* The largest size of a supported MID, in bytes. */ #define ADM_MID_ALLOC (15) /* The longest user name of a MID, in bytes. */ #define ADM_MAX_NAME (32) /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ /** * Functions implementing key responsibilities for each ADM item: * - The data collect function collects data from the local agent. * - The string function generates a String representation of the data value. * - The size function returns the size of the data, in bytes. * - The ctrl function executes a control associated with this MID. */ typedef expr_result_t (*adm_data_collect_fn)(Lyst parms); typedef char* (*adm_string_fn)(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); typedef uint32_t (*adm_size_fn)(uint8_t* buffer, uint64_t buffer_len); typedef uint32_t (*adm_ctrl_fn)(Lyst params); /** * Describes an ADM data definition entry in the system. * * This structure captures general information for those ADM entries pre- * configured on the local machine. * * Note: The collect function is OPTIONAL and is only configured on DTNMP * Actors acting as Agents. */ typedef struct { char name[ADM_MAX_NAME]; /**> Name of this MIB item */ mid_t *mid; /**> The MID identifying this def. */ //uint8_t mid[ADM_MID_ALLOC]; /**> The MID up to, but excluding, params */ //uint8_t mid_len; /**> Length, in bytes, of the MID. */ uint8_t num_parms; /**> # params needed to complete this MID.*/ adm_size_fn get_size; /**> Configured sizing function. */ adm_data_collect_fn collect; /**> Configured data collection function. */ adm_string_fn to_string; /**> Configured to-string function. */ } adm_datadef_t; /** * Describes an ADM Control in the system. * * This structure captures general information about a control, including * its name an associated MID. * * Note: The run function is OPTIONAL and is only configured on DTNMP Actors * that are authorized to perform the control. */ typedef struct { char name[ADM_MAX_NAME]; mid_t *mid; /**> The MID identifying this def. */ // uint8_t mid[ADM_MID_ALLOC]; /**> The MID up to, but excluding, params */ // uint8_t mid_len; /**> Length, in bytes, of the MID. */ uint8_t num_parms; /**> # params needed to complete this MID.*/ adm_ctrl_fn run; /**> Configured data collection function. */ } adm_ctrl_t; /* * +--------------------------------------------------------------------------+ * | DATA DEFINITIONS + * +--------------------------------------------------------------------------+ */ /** * Global data collection of supported ADM information. */ extern Lyst gAdmData; extern Lyst gAdmCtrls; extern Lyst gAdmLiterals; extern Lyst gAdmOps; /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ void adm_add_datadef(char *name, uint8_t *mid_str, int num_parms, adm_string_fn to_string, adm_size_fn get_size); void adm_add_datadef_collect(uint8_t *mid_str, adm_data_collect_fn collect); void adm_add_ctrl(char *name, uint8_t *mid_str, int num_parms); void adm_add_ctrl_run(uint8_t *mid_str, adm_ctrl_fn run); void adm_build_mid_str(uint8_t flag, char *nn, int nn_len, int offset, uint8_t *mid_str); uint8_t* adm_copy_integer(uint8_t *value, uint8_t size, uint64_t *length); uint8_t* adm_copy_string(char *value, uint64_t *length); // \todo: void adm_erase_datadef(adm_datadef_t *entry); // \todo: void adm_erase_ctrl(adm_ctrl_t *entry); void adm_destroy(); adm_datadef_t* adm_find_datadef(mid_t *mid); adm_datadef_t* adm_find_datadef_by_name(char *name); adm_datadef_t* adm_find_datadef_by_idx(int idx); adm_ctrl_t* adm_find_ctrl(mid_t *mid); adm_ctrl_t* adm_find_ctrl_by_name(char *name); adm_ctrl_t* adm_find_ctrl_by_idx(int idx); void adm_init(); char* adm_print_string(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); char* adm_print_string_list(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); char* adm_print_unsigned_long(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); char* adm_print_unsigned_long_list(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); char* adm_print_uvast(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); uint32_t adm_size_string(uint8_t* buffer, uint64_t buffer_len); uint32_t adm_size_string_list(uint8_t* buffer, uint64_t buffer_len); uint32_t adm_size_unsigned_long(uint8_t* buffer, uint64_t buffer_len); uint32_t adm_size_unsigned_long_list(uint8_t* buffer, uint64_t buffer_len); uint32_t adm_size_uvast(uint8_t* buffer, uint64_t buffer_len); #endif /* ADM_H_*/ ion-3.2.0~dfsg1.orig/nm/shared/adm/adm_agent.h0000644000175000017500000001026412260400056017402 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: adm_agent_public.h ** ** Description: This implements the public portions of a DTNMP Agent ADM. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/04/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef ADM_AGENT_H_ #define ADM_AGENT_H_ #include "lyst.h" #include "shared/utils/nm_types.h" #include "shared/adm/adm.h" /* * We will invent an OID space for DTNMP AGENT ADM information, to live at: * * iso.identified-organization.dod.internet.mgmt.dtnmp.agent * or 1.3.6.1.2.3.3 * or, as OID,: 2B 06 01 02 03 03 * * Note: dtnmp.bp is a made-up subtree. */ /* * +--------------------------------------------------------------------------+ * | ADM CONSTANTS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | ADM ATOMIC DATA DEFINITIONS + * +--------------------------------------------------------------------------+ */ /* * Structure: * * ADM_AGENT_ROOT (2A0601020303) * | * | * Data(1) | Ctrl(2) Op(3) Literals (4) * +-----+------+------------+-------------+ */ static char* ADM_AGENT_ROOT = "2B0601020303"; #define ADM_AGENT_ROOT_LEN (6) static char* ADM_AGENT_NODE_NN = "2B060102030301"; #define ADM_AGENT_NODE_NN_LEN (7) static char* ADM_AGENT_CTRL_NN = "2B060102030302"; #define ADM_AGENT_CTRL_NN_LEN (7) static char* ADM_AGENT_OP_NN = "2B060102030303"; #define ADM_AGENT_OP_NN_LEN (7) static char* ADM_AGENT_LIT_NN = "2B060102030304"; #define ADM_AGENT_LIT_NN_LEN (7) /* AGENT DATA */ /* Ops static char *DTNMP_AGENT_OP_ADD = "030A2A030102010101010300"; static char *DTNMP_AGENT_OP_SUB = "030A2A030102010101010301"; static char *DTNMP_AGENT_OP_DIV = "030A2A030102010101010302"; static char *DTNMP_AGENT_OP_MULT = "030A2A030102010101010303"; static char *DTNMP_AGENT_OP_BIT_AND = "030A2A030102010101010304"; static char *DTNMP_AGENT_OP_BIT_OR = "030A2A030102010101010305"; static char *DTNMP_AGENT_OP_BIT_XOR = "030A2A030102010101010306"; static char *DTNMP_AGENT_OP_BIT_NOT = "030A2A030102010101010307"; static char *DTNMP_AGENT_OP_LT = "030A2A030102010101010308"; static char *DTNMP_AGENT_OP_LTE = "030A2A030102010101010309"; static char *DTNMP_AGENT_OP_GT = "030A2A03010201010101030A"; static char *DTNMP_AGENT_OP_GTE = "030A2A03010201010101030B"; static char *DTNMP_AGENT_OP_EQ = "030A2A03010201010101030C"; static char *DTNMP_AGENT_OP_NEQ = "030A2A03010201010101030D"; static char *DTNMP_AGENT_OP_LOG_AND = "030A2A03010201010101030E"; static char *DTNMP_AGENT_OP_LOG_OR = "030A2A03010201010101030F"; static char *DTNMP_AGENT_OP_LOG_NOT = "030A2A030102010101010310"; static char *DTNMP_AGENT_OP_LSHFT = "030A2A030102010101010311"; static char *DTNMP_AGENT_OP_RSHFT = "030A2A030102010101010312"; static char *DTNMP_AGENT_OP_MOD = "030A2A030102010101010313"; static char *DTNMP_AGENT_OP_NEG = "030A2A030102010101010314"; */ void adm_agent_init(); /* Print Functions */ char *adm_print_agent_all(uint8_t* buffer, uint64_t buffer_len, uint64_t data_len, uint32_t *str_len); /* Sizing Functions */ uint32_t adm_size_agent_all(uint8_t* buffer, uint64_t buffer_len); #endif //ADM_AGENT_H_ ion-3.2.0~dfsg1.orig/nm/shared/msg/0000755000175000017500000000000012260400057015335 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/shared/msg/msg_reports.h0000644000175000017500000000716112260400057020057 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file msg_reports.h ** ** ** Description: Defines the serialization and de-serialization methods ** used to translate data types into byte streams associated ** with DTNMP messages, and vice versa. ** ** Notes: ** Not all fields of internal structures are serialized into/ ** deserialized from DTNMP messages. ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/09/11 M. Reid Initial Implementation (in other files) ** 11/02/12 E. Birrane Redesign of messaging architecture. ** 01/11/13 E. Birrane Migrate data structures to primitives. *****************************************************************************/ #ifndef MSG_REPORTS_H_ #define MSG_REPORTS_H_ #include "lyst.h" #include "shared/utils/nm_types.h" #include "shared/primitives/mid.h" #include "shared/primitives/report.h" #include "shared/msg/pdu.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ /* Reporting messages */ #define MSG_TYPE_RPT_DATA_LIST (0x10) #define MSG_TYPE_RPT_DATA_DEFS (0x11) #define MSG_TYPE_RPT_DATA_RPT (0x12) #define MSG_TYPE_RPT_PROD_SCHED (0x13) /* * +--------------------------------------------------------------------------+ * | MACROS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ /* Serialize functions. */ uint8_t *rpt_serialize_lst(rpt_items_t *msg, uint32_t *len); uint8_t *rpt_serialize_defs(rpt_defs_t *msg, uint32_t *len); uint8_t *rpt_serialize_data_entry(rpt_data_entry_t *entry, uint32_t *len); uint8_t *rpt_serialize_data(rpt_data_t *msg, uint32_t *len); uint8_t *rpt_serialize_prod(rpt_prod_t *msg, uint32_t *len); /* Deserialize functions. */ rpt_items_t *rpt_deserialize_lst(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); rpt_defs_t *rpt_deserialize_defs(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); rpt_data_t *rpt_deserialize_data(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); rpt_prod_t *rpt_deserialize_prod(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); #endif // MSG_REPORTS_H_ ion-3.2.0~dfsg1.orig/nm/shared/msg/msg_ctrl.c0000644000175000017500000002267412260400057017326 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file msg_ctrl.c ** ** ** Description: Defines the serialization and de-serialization methods ** used to translate data types into byte streams associated ** with DTNMP messages, and vice versa. ** ** Notes: ** Not all fields of internal structures are serialized into/ ** deserialized from DTNMP messages. ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 11/04/12 E. Birrane Redesign of messaging architecture. ** 01/17/13 E. Birrane Updated to use primitive types. *****************************************************************************/ #include "platform.h" #include "ion.h" #include "shared/utils/utils.h" #include "shared/msg/msg_ctrl.h" /* Create functions. */ /* Serialize functions. */ uint8_t *ctrl_serialize_time_prod_entry(rule_time_prod_t *msg, uint32_t *len) { uint8_t *result = NULL; uint8_t *cursor = NULL; Sdnv time_sdnv; Sdnv period_sdnv; Sdnv count_sdnv; uint8_t *contents = NULL; uint32_t contents_len = 0; DTNMP_DEBUG_ENTRY("ctrl_serialize_time_prod_entry","(0x%x, 0x%x)", (unsigned long)msg, (unsigned long) len); /* Step 0: Sanity Checks. */ if((msg == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("ctrl_serialize_time_prod_entry","Bad Args",NULL); DTNMP_DEBUG_EXIT("ctrl_serialize_time_prod_entry","->NULL",NULL); return NULL; } *len = 0; /* Step 1: Serialize contents individually. */ encodeSdnv(&time_sdnv, msg->time); encodeSdnv(&period_sdnv, msg->period); encodeSdnv(&count_sdnv, msg->count); if((contents = midcol_serialize(msg->mids, &contents_len)) == NULL) { DTNMP_DEBUG_ERR("ctrl_serialize_time_prod_entry","Can't serialize contents.",NULL); DTNMP_DEBUG_EXIT("ctrl_serialize_time_prod_entry","->NULL",NULL); return NULL; } /* Step 2: Figure out the length. */ *len = time_sdnv.length + period_sdnv.length + count_sdnv.length + contents_len; /* STEP 3: Allocate the serialized message. */ if((result = (uint8_t*)MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("ctrl_serialize_time_prod_entry","Can't alloc %d bytes", *len); *len = 0; MRELEASE(contents); DTNMP_DEBUG_EXIT("ctrl_serialize_time_prod_entry","->NULL",NULL); return NULL; } /* Step 4: Populate the serialized message. */ cursor = result; memcpy(cursor,time_sdnv.text,time_sdnv.length); cursor += time_sdnv.length; memcpy(cursor,period_sdnv.text,period_sdnv.length); cursor += period_sdnv.length; memcpy(cursor,count_sdnv.text,count_sdnv.length); cursor += count_sdnv.length; memcpy(cursor, contents, contents_len); cursor += contents_len; MRELEASE(contents); /* Step 5: Last sanity check. */ if((cursor - result) != *len) { DTNMP_DEBUG_ERR("ctrl_serialize_time_prod_entry","Wrote %d bytes but allcated %d", (unsigned long) (cursor - result), *len); *len = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("ctrl_serialize_time_prod_entry","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("ctrl_serialize_time_prod_entry","->0x%x",(unsigned long)result); return result; } uint8_t *ctrl_serialize_pred_prod_entry(rule_pred_prod_t *msg, uint32_t *len) { return NULL; } uint8_t *ctrl_serialize_exec(ctrl_exec_t *msg, uint32_t *len) { uint8_t *result = NULL; uint8_t *cursor = NULL; Sdnv time_sdnv; uint8_t *contents = NULL; uint32_t contents_len = 0; DTNMP_DEBUG_ENTRY("ctrl_serialize_exec","(0x%x, 0x%x)", (unsigned long)msg, (unsigned long) len); /* Step 0: Sanity Checks. */ if((msg == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("ctrl_serialize_exec","Bad Args",NULL); DTNMP_DEBUG_EXIT("ctrl_serialize_exec","->NULL",NULL); return NULL; } *len = 0; /* Step 1: Serialize contents individually. */ encodeSdnv(&time_sdnv, msg->time); if((contents = midcol_serialize(msg->contents, &contents_len)) == NULL) { DTNMP_DEBUG_ERR("ctrl_serialize_exec","Can't serialize contents.",NULL); DTNMP_DEBUG_EXIT("ctrl_serialize_exec","->NULL",NULL); return NULL; } /* Step 2: Figure out the length. */ *len = time_sdnv.length + contents_len; /* STEP 3: Allocate the serialized message. */ if((result = (uint8_t*)MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("ctrl_serialize_exec","Can't alloc %d bytes", *len); *len = 0; MRELEASE(contents); DTNMP_DEBUG_EXIT("ctrl_serialize_exec","->NULL",NULL); return NULL; } /* Step 4: Populate the serialized message. */ cursor = result; memcpy(cursor,time_sdnv.text,time_sdnv.length); cursor += time_sdnv.length; memcpy(cursor, contents, contents_len); cursor += contents_len; MRELEASE(contents); /* Step 5: Last sanity check. */ if((cursor - result) != *len) { DTNMP_DEBUG_ERR("ctrl_serialize_exec","Wrote %d bytes but allcated %d", (unsigned long) (cursor - result), *len); *len = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("ctrl_serialize_exec","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("ctrl_serialize_exec","->0x%x",(unsigned long)result); return result; } /* Deserialize functions. */ rule_time_prod_t *ctrl_deserialize_time_prod_entry(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { rule_time_prod_t *result = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("ctrl_deserialize_time_prod_entry","(0x%x, %d, 0x%x)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((cursor == NULL) || (bytes_used == 0)) { DTNMP_DEBUG_ERR("ctrl_deserialize_time_prod_entry","Bad Args.",NULL); DTNMP_DEBUG_EXIT("ctrl_deserialize_time_prod_entry","->NULL",NULL); return NULL; } /* Step 1: Allocate the new message structure. */ if((result = (rule_time_prod_t*)MTAKE(sizeof(rule_time_prod_t))) == NULL) { DTNMP_DEBUG_ERR("ctrl_deserialize_time_prod_entry","Can't Alloc %d Bytes.", sizeof(rule_time_prod_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("ctrl_deserialize_time_prod_entry","->NULL",NULL); return NULL; } else { memset(result,0,sizeof(rule_time_prod_t)); } /* Step 2: Deserialize the message. */ uvast val; bytes = decodeSdnv(&val, cursor); result->time = val; cursor += bytes; size -= bytes; *bytes_used += bytes; bytes = decodeSdnv(&val,cursor); result->period = val; cursor += bytes; size -= bytes; *bytes_used += bytes; bytes = decodeSdnv(&val,cursor); result->count = val; cursor += bytes; size -= bytes; *bytes_used += bytes; /* Grab the list of contents. */ if((result->mids = midcol_deserialize(cursor, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("ctrl_deserialize_time_prod_entry","Can't grab contents.",NULL); *bytes_used = 0; rule_release_time_prod_entry(result); DTNMP_DEBUG_EXIT("ctrl_deserialize_time_prod_entry","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } DTNMP_DEBUG_EXIT("ctrl_deserialize_time_prod_entry","->0x%x", (unsigned long)result); return result; } rule_pred_prod_t *ctrl_deserialize_pred_prod_entry(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { *bytes_used = 0; return NULL; } ctrl_exec_t *ctrl_deserialize_exec(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { ctrl_exec_t *result = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("ctrl_deserialize_exec","(0x%x, %d, 0x%x)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((cursor == NULL) || (bytes_used == 0)) { DTNMP_DEBUG_ERR("ctrl_deserialize_exec","Bad Args.",NULL); DTNMP_DEBUG_EXIT("ctrl_deserialize_exec","->NULL",NULL); return NULL; } /* Step 1: Allocate the new message structure. */ if((result = (ctrl_exec_t*)MTAKE(sizeof(ctrl_exec_t))) == NULL) { DTNMP_DEBUG_ERR("ctrl_deserialize_exec","Can't Alloc %d Bytes.", sizeof(ctrl_exec_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("ctrl_deserialize_exec","->NULL",NULL); return NULL; } else { memset(result,0,sizeof(ctrl_exec_t)); } /* Step 2: Deserialize the message. */ uvast val; bytes = decodeSdnv(&val, cursor); result->time = val; cursor += bytes; size -= bytes; *bytes_used += bytes; /* Grab the list of contents. */ if((result->contents = midcol_deserialize(cursor, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("ctrl_deserialize_exec","Can't grab contents.",NULL); *bytes_used = 0; ctrl_release_exec(result); DTNMP_DEBUG_EXIT("ctrl_deserialize_exec","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } DTNMP_DEBUG_EXIT("ctrl_deserialize_exec","->0x%x", (unsigned long)result); return result;} ion-3.2.0~dfsg1.orig/nm/shared/msg/msg_ctrl.h0000644000175000017500000000520612260400057017323 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file msg_ctrl.h ** ** ** Description: Defines the serialization and de-serialization methods ** used to translate data types into byte streams associated ** with DTNMP messages, and vice versa. ** ** Notes: ** Not all fields of internal structures are serialized into/ ** deserialized from DTNMP messages. ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 11/04/12 E. Birrane Redesign of messaging architecture. ** 01/17/13 E. Birrane Updated to use primitive types. *****************************************************************************/ #ifndef MSG_CTRL_H_ #define MSG_CTRL_H_ #include "stdint.h" #include "lyst.h" #include "shared/utils/nm_types.h" #include "shared/primitives/mid.h" #include "shared/primitives/rules.h" #include "shared/msg/pdu.h" /* Control messages */ #define MSG_TYPE_CTRL_PERIOD_PROD (0x18) #define MSG_TYPE_CTRL_PRED_PROD (0x19) #define MSG_TYPE_CTRL_EXEC (0x1A) #define MAX_RULE_SIZE (1024) /* Serialize functions. */ uint8_t *ctrl_serialize_time_prod_entry(rule_time_prod_t *msg, uint32_t *len); uint8_t *ctrl_serialize_pred_prod_entry(rule_pred_prod_t *msg, uint32_t *len); uint8_t *ctrl_serialize_exec(ctrl_exec_t *msg, uint32_t *len); /* Deserialize functions. */ rule_time_prod_t *ctrl_deserialize_time_prod_entry(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); rule_pred_prod_t *ctrl_deserialize_pred_prod_entry(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); ctrl_exec_t *ctrl_deserialize_exec(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); #endif // MSG_CTRL_H_ ion-3.2.0~dfsg1.orig/nm/shared/msg/msg_reports.c0000644000175000017500000003514112260400057020051 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file msg_reports.c ** ** ** Description: Defines the serialization and de-serialization methods ** used to translate data types into byte streams associated ** with DTNMP messages, and vice versa. ** **\todo Add more checks for overbounds reads on deserialization. ** ** Notes: ** Not all fields of internal structures are serialized into/ ** deserialized from DTNMP messages. ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/09/11 M. Reid Initial Implementation (in other files) ** 11/02/12 E. Birrane Redesign of messaging architecture. ** 01/11/13 E. Birrane Migrate data structures to primitives. *****************************************************************************/ #include "platform.h" #include "ion.h" #include "shared/utils/utils.h" #include "shared/primitives/mid.h" #include "shared/msg/pdu.h" #include "shared/msg/msg_reports.h" #include "shared/msg/msg_ctrl.h" /* Serialize functions. */ uint8_t *rpt_serialize_lst(rpt_items_t *msg, uint32_t *len) { uint8_t *result = NULL; uint8_t *cursor = NULL; uint8_t *contents = NULL; uint32_t contents_len = 0; DTNMP_DEBUG_ENTRY("rpt_serialize_lst","(0x%x, 0x%x)", (unsigned long)msg, (unsigned long) len); /* Step 0: Sanity Checks. */ if((msg == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("rpt_serialize_lst","Bad Args",NULL); DTNMP_DEBUG_EXIT("rpt_serialize_lst","->NULL",NULL); return NULL; } *len = 0; /* STEP 2: Serialize the Contents. */ if((contents = midcol_serialize(msg->contents, &contents_len)) == NULL) { DTNMP_DEBUG_ERR("rpt_serialize_lst","Can't serialize hdr.",NULL); DTNMP_DEBUG_EXIT("rpt_serialize_lst","->NULL",NULL); return NULL; } /* Step 4: Figure out the length. */ *len = contents_len; /* STEP 5: Allocate the serialized message. */ if((result = (uint8_t*)MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("rpt_serialize_lst","Can't alloc %d bytes", *len); *len = 0; MRELEASE(contents); DTNMP_DEBUG_EXIT("rpt_serialize_lst","->NULL",NULL); return NULL; } /* Step 6: Populate the serialized message. */ cursor = result; memcpy(cursor, contents, contents_len); cursor += contents_len; MRELEASE(contents); /* Step 7: Last sanity check. */ if((cursor - result) != *len) { DTNMP_DEBUG_ERR("rpt_serialize_lst","Wrote %d bytes but allcated %d", (unsigned long) (cursor - result), *len); *len = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("rpt_serialize_lst","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("rpt_serialize_lst","->0x%x",(unsigned long)result); return result; } uint8_t *rpt_serialize_defs(rpt_defs_t *msg, uint32_t *len) { /* \todo Implement this. */ *len = 0; return NULL; } uint8_t *rpt_serialize_data_entry(rpt_data_entry_t *entry, uint32_t *len) { uint8_t *id = NULL; uint32_t id_len = 0; Sdnv size; uint8_t *result = NULL; uint8_t *cursor = NULL; /* Step 0: Sanity Check. */ if((entry == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("rpt_serialize_data_entry", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("rpt_serialize_data_entry","->NULL",NULL); return NULL; } /* Step 1: Serialize the ID */ if((id = mid_serialize(entry->id, &id_len)) == NULL) { DTNMP_DEBUG_ERR("rpt_serialize_data_entry", "Can't serialize id.", NULL); *len = 0; DTNMP_DEBUG_EXIT("rpt_serialize_data_entry","->NULL",NULL); return NULL; } /* Step 2: Serialize the size value in an SDNV. */ encodeSdnv(&size,entry->size); /* Step 3: Calculate the size of the serialized entry. */ *len = id_len + entry->size + size.length; /* Step 4: Allocate the serialized entry space. */ if((result = (uint8_t*)MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("rpt_serialize_data_entry", "Can't alloc %d bytes.", *len); MRELEASE(id); *len = 0; DTNMP_DEBUG_EXIT("rpt_serialize_data_entry","->NULL",NULL); return NULL; } else { memset(result,0,*len); } /* Step 5: Copy in the pieces. */ cursor = result; memcpy(cursor,id,id_len); cursor += id_len; MRELEASE(id); memcpy(cursor,size.text, size.length); cursor += size.length; memcpy(cursor,entry->contents,entry->size); cursor += entry->size; /* Step 6: Last sanity check. */ if((cursor - result) != *len) { DTNMP_DEBUG_ERR("rpt_serialize_data_entry", "Wrote %d bytes but allcated %d", (unsigned long) (cursor - result), *len); *len = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("rpt_serialize_data_entry","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("rpt_serialize_data_entry","->0x%x", (unsigned long) result); return result; } uint8_t *rpt_serialize_data(rpt_data_t *msg, uint32_t *len) { uint8_t *result = NULL; uint8_t *cursor = NULL; Sdnv time; Sdnv num_rpts_sdnv; uint32_t num_rpts; DTNMP_DEBUG_ENTRY("rpt_serialize_data","(0x%x, 0x%x)", (unsigned long)msg, (unsigned long) len); /* Step 0: Sanity Checks. */ if((msg == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("rpt_serialize_data","Bad Args",NULL); DTNMP_DEBUG_EXIT("rpt_serialize_data","->NULL",NULL); return NULL; } *len = 0; /* Step 2: Serialize the time and # reports. */ encodeSdnv(&time, msg->time); num_rpts = lyst_length(msg->reports); encodeSdnv(&num_rpts_sdnv, num_rpts); /* STEP 4: Allocate individual storage for each report. */ uint8_t **temp_space = NULL; uint32_t *temp_len = NULL; LystElt elt; temp_space = (uint8_t**)MTAKE(num_rpts * sizeof(uint8_t *)); temp_len = (uint32_t*)MTAKE(num_rpts * sizeof(uint32_t)); if((temp_space == NULL) || (temp_len == NULL)) { DTNMP_DEBUG_ERR("rpt_serialize_data","Can't allocate %d bytes.", (num_rpts * sizeof(uint8_t *))); MRELEASE(temp_space); MRELEASE(temp_len); *len = 0; DTNMP_DEBUG_EXIT("rpt_serialize_data","->NULL",NULL); return NULL; } else { memset(temp_space,0,num_rpts * sizeof(uint8_t *)); memset(temp_len,0,num_rpts * sizeof(uint32_t)); } /* Step 5: Capture each serialized report. */ int i = 0; uint8_t success = 1; uint32_t bytes = 0; for(elt = lyst_first(msg->reports); (elt && success); elt = lyst_next(elt)) { rpt_data_entry_t *entry = (rpt_data_entry_t*)lyst_data(elt); if(entry != NULL) { temp_space[i] = rpt_serialize_data_entry(entry, &(temp_len[i])); success = (temp_space[i] != NULL) && (temp_len[i] != 0); bytes += temp_len[i]; i++; } else { DTNMP_DEBUG_WARN("rpt_serialize_data", "NULL item in report list.",NULL); success = 0; } } if(success == 0) { DTNMP_DEBUG_ERR("rpt_serialize_data","Can't serialize reports.",NULL); for(i = 0; i < num_rpts; i++) { MRELEASE(temp_space[i]); } MRELEASE(temp_space); MRELEASE(temp_len); *len = 0; DTNMP_DEBUG_EXIT("rpt_serialize_data","->NULL",NULL); return NULL; } /* Step 6. Calculate final size of the full report set. */ *len = time.length + num_rpts_sdnv.length + bytes; /* Step 7: Allocate the final full report. */ if((result = (uint8_t*)MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("rpt_serialize_data","Can't alloc %d bytes.", *len); for(i = 0; i < num_rpts; i++) { MRELEASE(temp_space[i]); } MRELEASE(temp_space); MRELEASE(temp_len); *len = 0; DTNMP_DEBUG_EXIT("rpt_serialize_data","->NULL",NULL); return NULL; } else { memset(result,0,*len); } /* Step 8: Copy data into the buffer. */ cursor = result; memcpy(cursor,time.text, time.length); cursor += time.length; memcpy(cursor, num_rpts_sdnv.text, num_rpts_sdnv.length); cursor += num_rpts_sdnv.length; for(i = 0; i < num_rpts; i++) { memcpy(cursor,temp_space[i], temp_len[i]); cursor += temp_len[i]; MRELEASE(temp_space[i]); } MRELEASE(temp_space); MRELEASE(temp_len); /* Step 9: Last sanity check. */ if((cursor - result) != *len) { DTNMP_DEBUG_ERR("rpt_serialize_data","Wrote %d bytes but allcated %d", (unsigned long) (cursor - result), *len); *len = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("rpt_serialize_data","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("rpt_serialize_data","->0x%x",(unsigned long)result); return result; } uint8_t *rpt_serialize_prod(rpt_prod_t *msg, uint32_t *len) { /* \todo: Finish this one. */ *len = 0; return NULL; } /* Deserialize functions. */ rpt_items_t *rpt_deserialize_lst(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { rpt_items_t *result = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("rpt_deserialize_lst","(0x%x, %d, 0x%x)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((cursor == NULL) || (bytes_used == 0)) { DTNMP_DEBUG_ERR("rpt_deserialize_lst","Bad Args.",NULL); DTNMP_DEBUG_EXIT("rpt_deserialize_lst","->NULL",NULL); return NULL; } *bytes_used = 0; /* Step 1: Allocate the new message structure. */ if((result = (rpt_items_t*)MTAKE(sizeof(rpt_items_t))) == NULL) { DTNMP_DEBUG_ERR("rpt_deserialize_lst","Can't Alloc %d Bytes.", sizeof(rpt_items_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("rpt_deserialize_lst","->NULL",NULL); return NULL; } else { memset(result,0,sizeof(rpt_items_t)); } /* Step 2: Deserialize the message. */ /* Grab the contents MC. */ if((result->contents = midcol_deserialize(cursor, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("rpt_deserialize_lst","Can't grab ID MID.", NULL); *bytes_used = 0; rpt_release_lst(result); DTNMP_DEBUG_EXIT("rpt_deserialize_lst","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } DTNMP_DEBUG_EXIT("rpt_deserialize_lst","->0x%x",(unsigned long)result); return result; } rpt_defs_t *rpt_deserialize_defs(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { /* \todo: Implement this. */ *bytes_used = 0; return NULL; } rpt_data_t *rpt_deserialize_data(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { rpt_data_t *result = NULL; int i = 0; uint32_t bytes = 0; uvast num_rpts = 0; uvast tmp_val; rpt_data_entry_t *cur_entry = NULL; DTNMP_DEBUG_ENTRY("rpt_deserialize_data","(0x%x, %d, 0x%x)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((cursor == NULL) || (bytes_used == 0)) { DTNMP_DEBUG_ERR("rpt_deserialize_data","Bad Args.",NULL); DTNMP_DEBUG_EXIT("rpt_deserialize_data","->NULL",NULL); return NULL; } *bytes_used = 0; /* Step 1: Allocate the new message structure. */ if((result = (rpt_data_t*)MTAKE(sizeof(rpt_data_t))) == NULL) { DTNMP_DEBUG_ERR("rpt_deserialize_data","Can't Alloc %d Bytes.", sizeof(rpt_data_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("rpt_deserialize_data","->NULL",NULL); return NULL; } else { memset(result,0,sizeof(rpt_data_t)); /* We build lyst in this function, so create it here. */ result->reports = lyst_create(); *bytes_used = 0; } /* Step 2: Deserialize the message. */ /* Grab the timestamp. */ if((bytes = utils_grab_sdnv(cursor, size, &tmp_val)) == 0) { DTNMP_DEBUG_ERR("rpt_deserialize_data","Can't Grab time SDNV.", sizeof(rpt_data_t)); rpt_release_data(result); *bytes_used = 0; DTNMP_DEBUG_EXIT("rpt_deserialize_data","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; result->time = tmp_val; } /* Grab the # reports. */ if((bytes = utils_grab_sdnv(cursor, size, &tmp_val)) == 0) { DTNMP_DEBUG_ERR("rpt_deserialize_data","Can't Grab time SDNV.", sizeof(rpt_data_t)); rpt_release_data(result); *bytes_used = 0; DTNMP_DEBUG_EXIT("rpt_deserialize_data","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; num_rpts = tmp_val; } /* For each report, deserialize and add it to the lyst. */ for(i = 0; i < num_rpts; i++) { /* Allocate new entry type. */ if((cur_entry = (rpt_data_entry_t*)MTAKE(sizeof(rpt_data_entry_t))) == NULL) { DTNMP_DEBUG_ERR("rpt_deserialize_data","Can't alloc %d bytes.", sizeof(rpt_data_entry_t)); rpt_release_data(result); *bytes_used = 0; DTNMP_DEBUG_EXIT("rpt_deserialize_data","->NULL",NULL); return NULL; } /* Grab the MID. */ if((cur_entry->id = mid_deserialize(cursor,size,&bytes)) == NULL) { DTNMP_DEBUG_ERR("rpt_deserialize_data","Can't grab %dth MID.", i); rpt_release_data(result); MRELEASE(cur_entry); *bytes_used = 0; DTNMP_DEBUG_EXIT("rpt_deserialize_data","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } /* Grab the size. */ if((bytes = utils_grab_sdnv(cursor, size, &tmp_val)) == 0) { DTNMP_DEBUG_ERR("rpt_deserialize_data","Can't Grab %dth size.", i); rpt_release_data(result); MRELEASE(cur_entry); *bytes_used = 0; DTNMP_DEBUG_EXIT("rpt_deserialize_data","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; cur_entry->size = tmp_val; } /* Allocate the size. */ if((cur_entry->contents = (uint8_t*)MTAKE(cur_entry->size)) == NULL) { DTNMP_DEBUG_ERR("rpt_deserialize_data","Can't Alloc %d.", cur_entry->size); rpt_release_data(result); MRELEASE(cur_entry); *bytes_used = 0; DTNMP_DEBUG_EXIT("rpt_deserialize_data","->NULL",NULL); return NULL; } /* Copy over the data. */ memcpy(cur_entry->contents, cursor, cur_entry->size); cursor += cur_entry->size; size -= cur_entry->size; *bytes_used += cur_entry->size; lyst_insert_last(result->reports, cur_entry); } result->size = *bytes_used; DTNMP_DEBUG_EXIT("rpt_deserialize_data","->0x%x",(unsigned long)result); return result; } rpt_prod_t *rpt_deserialize_prod(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { /* \todo: Implement this. */ *bytes_used = 0; return NULL; } ion-3.2.0~dfsg1.orig/nm/shared/msg/msg_admin.h0000644000175000017500000000462512260400057017453 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file msg_admin.h ** ** ** Description: Defines the data types associated with administrative ** messages within the protocol. Also, identify the functions ** that pack and unpack these messages. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/24/12 E. Birrane Initial Implementation ** 11/01/12 E. Birrane Redesign of messaging architecture. *****************************************************************************/ #ifndef MSG_ADMIN_H_ #define MSG_ADMIN_H_ #include "stdint.h" #include "lyst.h" #include "shared/utils/nm_types.h" #include "shared/primitives/mid.h" #include "shared/primitives/admin.h" #include "shared/msg/pdu.h" /* Administrative messages */ #define MSG_TYPE_ADMIN_REG_AGENT (0x00) #define MSG_TYPE_ADMIN_RPT_POLICY (0x01) #define MSG_TYPE_ADMIN_STAT_MSG (0x02) /* Serialize functions. */ uint8_t *msg_serialize_reg_agent(adm_reg_agent_t *msg, uint32_t *len); uint8_t *msg_serialize_rpt_policy(adm_rpt_policy_t *msg, uint32_t *len); uint8_t *msg_serialize_stat_msg(adm_stat_msg_t *msg, uint32_t *len); /* Deserialize functions. */ adm_reg_agent_t *msg_deserialize_reg_agent(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); adm_rpt_policy_t *msg_deserialize_rpt_policy(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); adm_stat_msg_t *msg_deserialize_stat_msg(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); #endif // MSG_ADMIN_H_ ion-3.2.0~dfsg1.orig/nm/shared/msg/pdu.c0000644000175000017500000005723612260400057016306 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file pdu.c ** ** ** Description: ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/24/12 E. Birrane Initial Implementation ** 11/01/12 E. Birrane Redesign of messaging architecture. ** 06/25/13 E. Birrane Renamed message "bundle" message "group". ** 06/26/13 E. Birrane Added group timestamp *****************************************************************************/ #include "platform.h" #include "ion.h" #include "shared/adm/adm.h" #include "shared/msg/pdu.h" #include "shared/primitives/mid.h" #include "shared/utils/utils.h" pdu_group_t *pdu_create_empty_group() { pdu_group_t *result = NULL; result = (pdu_group_t*) MTAKE(sizeof(pdu_group_t)); result->msgs = lyst_create(); result->time = time(NULL); return result; } pdu_group_t *pdu_create_group(pdu_msg_t *msg) { pdu_group_t *result = NULL; result = pdu_create_empty_group(); lyst_insert_last(result->msgs, msg); result->time = time(NULL); return result; } pdu_header_t *pdu_create_hdr(uint8_t id, uint8_t ack, uint8_t nack, uint8_t acl) { pdu_header_t *result = NULL; DTNMP_DEBUG_ENTRY("pdu_create_hdr","(%d, %d, %d, %d, %d)",id ,ack, nack, acl); if((result = (pdu_header_t *) MTAKE(sizeof(pdu_header_t))) == NULL) { DTNMP_DEBUG_ERR("pdu_create_hdr","Can't alloc %d bytes", sizeof(pdu_header_t)); DTNMP_DEBUG_EXIT("pdu_create_hdr","->NULL",NULL); return NULL; } result->id = id; result->type = id & 0x07; result->context = (id >> 3) & 0x03; result->ack = ack; result->nack = nack; result->acl = acl; DTNMP_DEBUG_EXIT("pdu_create_hdr","->0x%x",(unsigned long)result); return result; } pdu_msg_t *pdu_create_msg(uint8_t id, uint8_t *data, uint32_t data_size, pdu_acl_t *acl) { pdu_msg_t *result = NULL; DTNMP_DEBUG_ENTRY("pdu_create_msg","(%d, 0x%x, %d, 0x%x)", id, (unsigned long) data, data_size, (unsigned long) acl); /* Step 0: Sanity Check. */ if(data == NULL) { DTNMP_DEBUG_ERR("pdu_create_msg","Bad args",NULL); DTNMP_DEBUG_EXIT("pdu_create_msg","->0x%x",result); return NULL; } /* Step 1: Allocate the message. */ if((result = (pdu_msg_t*)MTAKE(sizeof(pdu_msg_t))) == NULL) { DTNMP_DEBUG_ERR("pdu_create_msg","Can't Alloc %d bytes", sizeof(pdu_msg_t)); DTNMP_DEBUG_EXIT("pdu_create_msg","->0x%x",result); return NULL; } /* Step 3: Shallow-copy the result. */ result->hdr = pdu_create_hdr(id,0,0,0); result->contents = data; result->size = data_size; result->acl = acl; DTNMP_DEBUG_EXIT("pdu_create_msg","->0x%x",result); return result; } void pdu_release_hdr(pdu_header_t *hdr) { if(hdr != NULL) { MRELEASE(hdr); } } void pdu_release_meta(pdu_metadata_t *meta) { if(meta != NULL) { MRELEASE(meta); } } void pdu_release_acl(pdu_acl_t *acl) { if(acl != NULL) { MRELEASE(acl); } } void pdu_release_msg(pdu_msg_t *pdu) { if(pdu != NULL) { MRELEASE(pdu->hdr); MRELEASE(pdu->contents); MRELEASE(pdu->acl); MRELEASE(pdu); } } void pdu_release_group(pdu_group_t *group) { LystElt elt; if(group == NULL) { return; } for(elt = lyst_first(group->msgs); elt; elt = lyst_next(elt)) { pdu_msg_t *cur_msg = (pdu_msg_t*) lyst_data(elt); pdu_release_msg(cur_msg); } lyst_destroy(group->msgs); MRELEASE(group); } /** * \brief builds a serialized header from a header structure. * * \author Ed Birrane * * \note * - The returned serialized header has been taken from the memory pool and * must be returned to the pool when no longer needed. * - Right now, the whole header is a byte, but we allocate anyway for future * expansion. * * \return NULL - Failure. * !NULL - The serialized header. * * \param[in] hdr The header being serialized. * \param[out] len The length of the serialized header, in bytes. */ uint8_t *pdu_serialize_hdr(pdu_header_t *hdr, uint32_t *len) { uint8_t *result = NULL; uint32_t result_len = 1; DTNMP_DEBUG_ENTRY("pdu_serialize_hdr","(0x%x, 0x%x)", (unsigned long) hdr, (unsigned long) len); /* Step 0: Sanity Checks. */ if((hdr == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("pdu_serialize_hdr","Bad Args.",NULL); DTNMP_DEBUG_EXIT("pdu_serialize_hdr","->NULL",NULL); return NULL; } /* Step 1: Grab space. */ if((result = (uint8_t*)MTAKE(result_len)) == NULL) { DTNMP_DEBUG_ERR("pdu_serialize_hdr","Can't allocate %d bytes.", result_len); *len = 0; DTNMP_DEBUG_EXIT("pdu_serialize_hdr","->NULL",NULL); return NULL; } *len = 1; /* Step 2: Populate the space. */ *result = (hdr->type & 0x7) << 5; *result |= (hdr->context & 0x3) << 3; *result |= (hdr->ack & 0x01) << 2; *result |= (hdr->nack & 0x01) << 1; *result |= (hdr->acl & 0x01); DTNMP_DEBUG_EXIT("pdu_serialize_hdr","->0x%x",(unsigned long)result); return result; } /** * \brief builds a serialized ACL from an acl structure. * * \author Ed Birrane * * \note * - The returned serialized ACL has been taken from the memory pool and * must be returned to the pool when no longer needed. * * \todo * - Implement this. * * \return NULL - Failure. * !NULL - The serialized ACL. * * \param[in] acl The acl being serialized. * \param[out] len The length of the serialized header, in bytes. */ uint8_t *pdu_serialize_acl(pdu_acl_t *acl, uint32_t *len) { uint8_t *result = NULL; uint32_t result_len = sizeof(pdu_acl_t); DTNMP_DEBUG_ENTRY("pdu_serialize_acl","(0x%x, 0x%x)", (unsigned long) acl, (unsigned long) len); /* Step 0: Sanity Checks. */ if((acl == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("pdu_serialize_acl","Bad Args.",NULL); DTNMP_DEBUG_EXIT("pdu_serialize_acl","->NULL",NULL); return NULL; } /* Step 1: Grab space. */ if((result = (uint8_t*)MTAKE(result_len)) == NULL) { DTNMP_DEBUG_ERR("pdu_serialize_acl","Can't allocate %d bytes.", result_len); *len = 0; DTNMP_DEBUG_EXIT("pdu_serialize_acl","->NULL",NULL); return NULL; } /* Step 2: Populate the space. */ /* \todo: Implement this. */ DTNMP_DEBUG_ERR("pdu_serialize_acl","Not implemented yet.",NULL); MRELEASE(result); result = NULL; DTNMP_DEBUG_EXIT("pdu_serialize_acl","->0x%x",(unsigned long)result); return result; } uint8_t *pdu_serialize_msg(pdu_msg_t *msg, uint32_t *len) { uint8_t *result = NULL; uint8_t *cursor = NULL; uint8_t *hdr = NULL; uint32_t hdr_len = 0; uint8_t *acl = NULL; uint32_t acl_len = 0; DTNMP_DEBUG_ENTRY("pdu_serialize_msg","(0x%x, 0x%x)", (unsigned long) msg, (unsigned long) len); if((hdr = pdu_serialize_hdr(msg->hdr, &hdr_len)) == NULL) { DTNMP_DEBUG_ERR("pdu_serialize_msg","Can't serialize hdr",NULL); DTNMP_DEBUG_EXIT("pdu_serialize_msg","->NULL",NULL); return NULL; } if(msg->acl != NULL) { if((acl = pdu_serialize_acl(msg->acl, &acl_len)) == NULL) { DTNMP_DEBUG_ERR("pdu_serialize_msg","Can't serialize acl",NULL); MRELEASE(hdr); DTNMP_DEBUG_EXIT("pdu_serialize_msg","->NULL",NULL); return NULL; } } *len = hdr_len + msg->size + acl_len; if((result = (uint8_t *) MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("pdu_serialize_msg","Can't alloc %d bytes",*len); MRELEASE(hdr); MRELEASE(acl); DTNMP_DEBUG_EXIT("pdu_serialize_msg","->NULL",NULL); return NULL; } cursor = result; memcpy(cursor,hdr,hdr_len); cursor += hdr_len; MRELEASE(hdr); memcpy(cursor,msg->contents, msg->size); cursor += msg->size; if(msg->acl != NULL) { memcpy(cursor, acl, acl_len); cursor += acl_len; MRELEASE(acl); } if((cursor-result) != *len) { DTNMP_DEBUG_ERR("pdu_serialize_msg","Wrote %d not %d bytes!", (unsigned long)(cursor-result), *len); MRELEASE(result); DTNMP_DEBUG_EXIT("pdu_serialize_msg","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("pdu_serialize_msg","->0x%x",(unsigned long)result); return result; } uint8_t *pdu_serialize_group(pdu_group_t *group, uint32_t *len) { uint8_t *result = NULL; uint8_t *cursor = NULL; uint8_t **tmp_data = NULL; uint32_t *tmp_size = NULL; uint32_t num_msgs = 0; Sdnv num_msgs_sdnv; Sdnv time_sdnv; uint32_t i = 0; uint32_t tot_size = 0; LystElt elt; DTNMP_DEBUG_ENTRY("pdu_serialize_group","(0x%x,0x%x)", (unsigned long) group, (unsigned long) len); /* Step 0: Sanity Checks. */ if((group == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("pdu_serialize_group","Bad Args.", NULL); DTNMP_DEBUG_EXIT("pdu_serialize_group","->NULL.", NULL); return NULL; } num_msgs = lyst_length(group->msgs); /* Step 1: Allocate space to store serialized msgs. */ if((tmp_data = (uint8_t **) MTAKE(num_msgs * sizeof(uint8_t *))) == NULL) { DTNMP_DEBUG_ERR("pdu_serialize_group","Can't Alloc %d bytes.", num_msgs * sizeof(uint8_t *)); DTNMP_DEBUG_EXIT("pdu_serialize_group","->NULL.", NULL); return NULL; } else { memset(tmp_data,0,num_msgs * sizeof(uint8_t*)); } if((tmp_size = (uint32_t *) MTAKE(num_msgs * sizeof(uint32_t))) == NULL) { DTNMP_DEBUG_ERR("pdu_serialize_group","Can't Alloc %d bytes.", num_msgs * sizeof(uint32_t)); MRELEASE(tmp_data); DTNMP_DEBUG_EXIT("pdu_serialize_group","->NULL.", NULL); return NULL; } else { memset(tmp_size, 0, num_msgs * sizeof(uint32_t)); } /* Step 2: Serialize messages in turn. */ tot_size = 0; for(elt = lyst_first(group->msgs); elt; elt = lyst_next(elt)) { pdu_msg_t *cur_msg = (pdu_msg_t*) lyst_data(elt); if(cur_msg == NULL) { DTNMP_DEBUG_WARN("pdu_serialize_group","Null %dth msg", i); } else { if((tmp_data[i] = pdu_serialize_msg(cur_msg,&(tmp_size[i]))) != NULL) { tot_size += tmp_size[i]; i++; } else { DTNMP_DEBUG_WARN("pdu_serialize_group", "Can't serialize %dth msg", i); } } } /* Step 3: If we had any problems, time to bail. */ if(i < num_msgs) { DTNMP_DEBUG_ERR("pdu_serialize_group","Problems serializing.",NULL); int j = 0; for(j = 0; j < i; j++) { MRELEASE(tmp_data[j]); } MRELEASE(tmp_data); MRELEASE(tmp_size); DTNMP_DEBUG_EXIT("pdu_serialize_group","->NULL.", NULL); return NULL; } /* Step 4: Add size and time and allocate final result. */ encodeSdnv(&num_msgs_sdnv, num_msgs); encodeSdnv(&time_sdnv, group->time); *len = num_msgs_sdnv.length + time_sdnv.length + tot_size; DTNMP_DEBUG_INFO("pdu_serialize_group", "msgs is %d, time is %d, total is %d", num_msgs_sdnv.length, time_sdnv.length, tot_size); if((result = (uint8_t*) MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("pdu_serialize_group","Can't alloc %d bytes.",*len); int j = 0; for(j = 0; j < i; j++) { MRELEASE(tmp_data[j]); } MRELEASE(tmp_data); MRELEASE(tmp_size); DTNMP_DEBUG_EXIT("pdu_serialize_group","->NULL.", NULL); return NULL; } cursor = result; /* Step 5: Copy data into the serialize buffer. */ memcpy(cursor, num_msgs_sdnv.text, num_msgs_sdnv.length); cursor += num_msgs_sdnv.length; memcpy(cursor, time_sdnv.text, time_sdnv.length); cursor += time_sdnv.length; for(i = 0; i < num_msgs; i++) { memcpy(cursor, tmp_data[i], tmp_size[i]); MRELEASE(tmp_data[i]); cursor += tmp_size[i]; } MRELEASE(tmp_data); MRELEASE(tmp_size); DTNMP_DEBUG_EXIT("pdu_serialize_group","->0x%x",(unsigned long) result); return result; } /** * \brief Constructs a header from a serialized stream. * * \author Ed Birrane * * \note * - The returned header object is allocated on the memory pool and must * be released when finished. * * \param[in] cursor The buffer holding the header. * \param[in] size The size of the buffer, in bytes. * \param[out] bytes_used The # bytes used to construct the header. */ pdu_header_t *pdu_deserialize_hdr(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { pdu_header_t *result = NULL; DTNMP_DEBUG_ENTRY("pdu_deserialize_hdr","(0x%x,%d,0x%x)", (unsigned long) cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Check */ if((cursor == 0) || (size <= 0) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("pdu_deserialize_hdr","Bad args.", NULL); DTNMP_DEBUG_EXIT("pdu_deserialize_hdr","->NULL",NULL); return NULL; } /* Step 1: Allocate the header object. */ if((result = (pdu_header_t*) MTAKE(sizeof(pdu_header_t))) == NULL) { DTNMP_DEBUG_ERR("pdu_deserialize_hdr","Can't allocate %d bytes.", sizeof(pdu_header_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("pdu_deserialize_hdr","->NULL",NULL); return NULL; } /* Step 2: Populate the object. */ uint8_t byte = *cursor; result->type = (byte & 0xE0) >> 5; result->context = (byte & 0x18) >> 3; result->ack = (byte & 0x04) >> 2; result->nack = (byte & 0x02) >> 1; result->acl = (byte & 0x01); result->id = (result->context << 3) | result->type; *bytes_used = 1; DTNMP_DEBUG_EXIT("pdu_deserialize_hdr","->0x%x",result); return result; } /** * \brief Constructs an ACL from a serialized stream. * * \author Ed Birrane * * \note * - The returned ACL object is allocated on the memory pool and must * be released when finished. * * \param[in] cursor The buffer holding the acl. * \param[in] size The size of the buffer, in bytes. * \param[out] bytes_used The # bytes used to construct the acl. */ pdu_acl_t *pdu_deserialize_acl(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { pdu_acl_t *result = NULL; DTNMP_DEBUG_ENTRY("pdu_deserialize_acl","(0x%x,%d,0x%x)", (unsigned long) cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Check */ if((cursor == 0) || (size <= 0) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("pdu_deserialize_acl","Bad args.", NULL); DTNMP_DEBUG_EXIT("pdu_deserialize_acl","->NULL",NULL); return NULL; } /* Step 1: Allocate the header object. */ if((result = (pdu_acl_t*)MTAKE(sizeof(pdu_acl_t))) == NULL) { DTNMP_DEBUG_ERR("pdu_deserialize_acl","Can't allocate %d bytes.", sizeof(pdu_acl_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("pdu_deserialize_acl","->NULL",NULL); return NULL; } /* Step 2: Populate the object. */ /* \todo: Implement this. */ DTNMP_DEBUG_ERR("pdu_deserialize_acl","Not implemented yet.",NULL); MRELEASE(result); result = NULL; DTNMP_DEBUG_EXIT("pdu_deserialize_acl","->0x%x",result); return result; } int pdu_add_msg_to_group(pdu_group_t *group, pdu_msg_t *msg) { int result = 0; lyst_insert_last(group->msgs, msg); return result; } /*** nm_custom_report* createCustomReport(pdu *cur_pdu) { unsigned char* cursor; int sdnv_len = 0; unsigned long sdnv_tmp = 0; nm_custom_report *report; mid_t *cur_mid = NULL; unsigned long mid_used = 0; char *mid_str = NULL; DTNMP_DEBUG_PROC("+ PDU: createCustomReport(0x%x)", (unsigned long) cur_pdu); / * Step 0: Sanity check the pdu type to ensure it contains a rule * / if(cur_pdu->hdr.type != MSG_TYPE_DEF_CUST_RPT) { DTNMP_DEBUG_ERR("x PDU: Cannot create custom report from msg of type %d", cur_pdu->hdr.type); DTNMP_DEBUG_PROC("- PDU: createCustomReport -> NULL", NULL); return NULL; } / * Step 1: Allocate the new custom report definition. * / if((report = (nm_custom_report*) MTAKE(sizeof(nm_custom_report))) == NULL) { DTNMP_DEBUG_ERR("x PDU: Unable to allocate new custom report definition.", NULL); DTNMP_DEBUG_PROC("- PDU: createRule -> NULL", NULL); return NULL; } report->mids = lyst_create(); cursor = cur_pdu->content; DTNMP_DEBUG_INFO("i PDU: Cursor is %x", (unsigned long) cursor); / * Step 2: Extract the custom report ID. * / report->report_id = build_mid(cursor, (cur_pdu->content + cur_pdu->data_size) - cursor, &mid_used); mid_str = mid_string(report->report_id); DTNMP_DEBUG_INFO("i PDU: Report has ID of %s. Used is %d.", mid_str, mid_used); MRELEASE(mid_str); cursor += mid_used; / * Step 3: Grab the list of MIDs to be produced by this rule. * / while(cursor < (cur_pdu->content + cur_pdu->data_size)) { cur_mid = build_mid(cursor, (cur_pdu->content + cur_pdu->data_size) - cursor, &mid_used); if(cur_mid != NULL) { char *name = mid_string(cur_mid); lyst_insert_last(report->mids, cur_mid); cursor += mid_used; DTNMP_DEBUG_INFO("i PDU: Added MID %s of size %d to report.", name, mid_used); MRELEASE(name); } } if(cursor != (cur_pdu->content + cur_pdu->data_size)) { DTNMP_DEBUG_WARN("w MID: Unexpected size mismatch: cursor (%x) end data (%x)", (unsigned long) cursor, (unsigned long) (cur_pdu->content + cur_pdu->data_size)); } strcpy(report->sender.name, cur_pdu->meta.senderEid.name); DTNMP_DEBUG_INFO("i PDU: PDU sender EID is %s", report->sender.name); DTNMP_DEBUG_PROC("- PDU: createProdRule -> %x", (unsigned long) report); return report; } nm_report *createDataReport(pdu *cur_pdu) { unsigned char* cursor; int sdnv_len = 0; unsigned long sdnv_tmp = 0; nm_report *report; DTNMP_DEBUG_PROC("+ PDU: createDataReport(0x%x)", (unsigned long)cur_pdu); / * Step 0: Sanity check the pdu type to ensure it contains a rule * / if(cur_pdu->hdr.type != MSG_TYPE_RPT_DATA_RPT) { DTNMP_DEBUG_ERR("x PDU: Cannot create report from msg of type %d", cur_pdu->hdr.type); DTNMP_DEBUG_PROC("- PDU: createDataReport -> NULL", NULL); return NULL; } / * Step 1: Allocate the new report. * / if((report = (nm_report*) MTAKE(sizeof(nm_report))) == NULL) { DTNMP_DEBUG_ERR("x PDU: Unable to allocate new report of size %d.", sizeof(nm_report)); DTNMP_DEBUG_PROC("- PDU: createDataReport -> NULL", NULL); return NULL; } report->length = 0; report->report_data = lyst_create(); cursor = cur_pdu->content; DTNMP_DEBUG_INFO("i PDU: Cursor is %x", (unsigned long) cursor); / * Step 2: Extract the Report Timestamp * / if((sdnv_len = decodeSdnv(&(sdnv_tmp), cursor)) == 0) { DTNMP_DEBUG_ERR("x PDU: No timestamp field in report msg.", NULL); lyst_destroy(report->report_data); MRELEASE(report); DTNMP_DEBUG_PROC("- PDU: createDataReport -> NULL", NULL); return NULL; } report->timestamp = sdnv_tmp; cursor += sdnv_len; DTNMP_DEBUG_INFO("i PDU: Report has timestamp of %ld", report->timestamp); / * Step 3: Grab the data entries contained in this report. * / nm_report_entry *cur_entry = NULL; unsigned long mid_size = 0; char *mid_str; while(cursor < (cur_pdu->content + cur_pdu->data_size)) { / * Allocate the entry * / cur_entry = (nm_report_entry*) MTAKE(sizeof(nm_report_entry)); / * Grab the MID * / if((cur_entry->mid = build_mid(cursor, (cur_pdu->content + cur_pdu->data_size) - cursor, &mid_size)) == NULL) { DTNMP_DEBUG_ERR("x PDU: Unable to build MID!", NULL); MRELEASE(report); DTNMP_DEBUG_PROC("- PDU: createDataReport -> NULL", NULL); return NULL; } cursor += mid_size; report->length += mid_size; DTNMP_DEBUG_INFO("i PDU: MID size is %d", mid_size); / * Grab the data length. * / sdnv_len = decodeSdnv(&(sdnv_tmp), cursor); cur_entry->data_size = sdnv_tmp; report->length += sdnv_tmp; cursor += sdnv_len; DTNMP_DEBUG_INFO("i PDU: Got data size of %d", cur_entry->data_size); / * Grab the data * / cur_entry->data = (uint8_t*) MTAKE(cur_entry->data_size); memcpy(cur_entry->data, cursor, cur_entry->data_size); cursor += cur_entry->data_size; mid_str = mid_string(cur_entry->mid); DTNMP_DEBUG_INFO("i PDU: Added entry for mid %s of size %d", mid_str, cur_entry->data_size); MRELEASE(mid_str); / * Add the entry to the entry list. * / lyst_insert_last(report->report_data, cur_entry); } if(cursor != (cur_pdu->content + cur_pdu->data_size)) { DTNMP_DEBUG_WARN("w MID: Unexpected size mismatch: cursor (%x) end data (%x)", (unsigned long) cursor, (unsigned long) (cur_pdu->content + cur_pdu->data_size)); } strcpy(report->recipient.name, cur_pdu->meta.recipientEid.name); DTNMP_DEBUG_PROC("- PDU: createProdRule -> %x", (unsigned long) report); return report; } uint8_t *buildProdRulePDU(int offset, int period, int evals, Lyst mids, int mid_size, int *msg_len) { uint8_t *pdu; Sdnv offset_tmp; Sdnv period_tmp; Sdnv evals_tmp; uint32_t length = 0; LystElt elt; int idx = 0; DTNMP_DEBUG_PROC("+ PDU: buildProdRulePDU(%d, %d, %d, 0x%x", offset, period, evals, (unsigned long)mids); / * Translate the SDNVs * / encodeSdnv(&offset_tmp,offset); encodeSdnv(&period_tmp,period); encodeSdnv(&evals_tmp, evals); / * Figure out the length of the resulting buffer * / length = 1; / * Message Type. * / length += offset_tmp.length; length += period_tmp.length; length += evals_tmp.length; length += mid_size; if((pdu = (uint8_t*) MTAKE(length)) == NULL) { DTNMP_DEBUG_ERR("x PDU: Failed allocating pdu of size %d", length); return NULL; } idx = 0; pdu[idx++] = (uint8_t) MSG_TYPE_CTRL_PERIOD_PROD; memcpy(&(pdu[idx]), offset_tmp.text, offset_tmp.length); idx += offset_tmp.length; memcpy(&(pdu[idx]), period_tmp.text, period_tmp.length); idx += period_tmp.length; memcpy(&(pdu[idx]), evals_tmp.text, evals_tmp.length); idx += evals_tmp.length; for (elt = lyst_first(mids); elt; elt = lyst_next(elt)) { nm_adu_entry *entry = (nm_adu_entry*) lyst_data(elt); if((idx + entry->mid_len) > length) { DTNMP_DEBUG_ERR("x PDU: Invalid sizes. Length %d, idx+mid %d", length, idx + entry->mid_len); MRELEASE(pdu); return NULL; } memcpy(&pdu[idx], entry->mid, entry->mid_len); idx += entry->mid_len; } *msg_len = length; DTNMP_DEBUG_PROC("- PDU: buildProdRulePDU --> (0x%x)", pdu); return pdu; } uint8_t *buildReportDefPDU(mid_t *report_id, Lyst mids, uint32_t mid_size, int *msg_len) { uint8_t *pdu = NULL; uint32_t idx = 0; LystElt elt; DTNMP_DEBUG_INFO("i report_id size %d mis_size %d i %d", report_id->raw_size, mid_size, 1); *msg_len = report_id->raw_size + mid_size + 1; pdu = (uint8_t *) MTAKE(*msg_len); idx = 0; pdu[idx++] = (uint8_t) MSG_TYPE_DEF_CUST_RPT; memcpy(&(pdu[idx]), report_id->raw, report_id->raw_size); idx += report_id->raw_size; for (elt = lyst_first(mids); elt; elt = lyst_next(elt)) { mid_t *cur_mid = (mid_t*) lyst_data(elt); char *mid_str = NULL; if((idx + cur_mid->raw_size) > *msg_len) { DTNMP_DEBUG_ERR("x PDU: Invalid sizes. Length %d, idx+mid %d", *msg_len, idx + cur_mid->raw_size); MRELEASE(pdu); return NULL; } mid_str = mid_string(cur_mid); DTNMP_DEBUG_INFO("i PFU: Adding mid %s to custom report.", mid_str); MRELEASE(mid_str); memcpy(&pdu[idx], cur_mid->raw, cur_mid->raw_size); idx += cur_mid->raw_size; } DTNMP_DEBUG_PROC("- PDU: buildProdRulePDU --> (0x%x)", pdu); return pdu; } */ ion-3.2.0~dfsg1.orig/nm/shared/msg/pdu.h0000644000175000017500000000667612260400057016315 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file pdu.h ** ** ** Description: ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/24/12 E. Birrane Initial Implementation ** 11/01/12 E. Birrane Redesign of messaging architecture. ** 06/25/13 E. Birrane Renamed message "bundle" message "group". ** 06/26/13 E. Birrane Added group timestamp *****************************************************************************/ #ifndef DTNMPDU_H_ #define DTNMPDU_H_ #include "lyst.h" #include "stdint.h" #include "shared/utils/nm_types.h" typedef struct { /** The EID of the last node of this message. */ eid_t senderEid; /** The EID of the message originator. */ eid_t originatorEid; /** The EID of the message recipient. */ eid_t recipientEid; } pdu_metadata_t; typedef struct { /** Message type */ uint8_t type; /**> The opcode field identifying the message opcode. */ uint8_t context; /**> Message category. */ uint8_t ack; /**> Whether the message must be ACK'd. */ uint8_t nack; /**> Whether the message must send error on failure. */ uint8_t acl; /**> Whether the message has an ACL appended to it. */ uint8_t id; /**> Combination of type and category. */ } pdu_header_t; /* * \todo Support this... */ typedef struct { } pdu_acl_t; typedef struct { pdu_header_t *hdr; pdu_metadata_t meta; uint8_t *contents; uint32_t size; pdu_acl_t *acl; } pdu_msg_t; typedef struct { Lyst msgs; time_t time; } pdu_group_t; pdu_group_t *pdu_create_empty_group(); pdu_group_t *pdu_create_group(pdu_msg_t *msg); pdu_header_t *pdu_create_hdr(uint8_t id, uint8_t ack, uint8_t nack, uint8_t acl); pdu_msg_t *pdu_create_msg(uint8_t id, uint8_t *data, uint32_t data_size, pdu_acl_t *acl); void pdu_release_hdr(pdu_header_t *hdr); void pdu_release_meta(pdu_metadata_t *meta); void pdu_release_acl(pdu_acl_t *acl); void pdu_release_msg(pdu_msg_t *pdu); void pdu_release_group(pdu_group_t *group); uint8_t *pdu_serialize_hdr(pdu_header_t *hdr, uint32_t *len); uint8_t *pdu_serialize_acl(pdu_acl_t *acl, uint32_t *len); uint8_t *pdu_serialize_msg(pdu_msg_t *msg, uint32_t *len); uint8_t *pdu_serialize_group(pdu_group_t *group, uint32_t *len); pdu_header_t *pdu_deserialize_hdr(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); pdu_acl_t *pdu_deserialize_acl(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); int pdu_add_msg_to_group(pdu_group_t *group, pdu_msg_t *msg); #endif /* DTNMPDU_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/msg/msg_def.h0000644000175000017500000000370512260400057017117 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file msg_def.h ** ** ** Description: Defines the data types associated with definition ** messages within the protocol. Also, identify the functions ** that pack and unpack these messages. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/24/12 E. Birrane Initial Implementation (in other files) ** 11/02/12 E. Birrane Redesign of messaging architecture. *****************************************************************************/ #ifndef MSG_DEF_H_ #define MSG_DEF_H_ #include #include "lyst.h" #include "shared/utils/nm_types.h" #include "shared/primitives/mid.h" #include "shared/primitives/def.h" #include "shared/msg/pdu.h" /* Definition messages */ #define MSG_TYPE_DEF_CUST_RPT (0x08) #define MSG_TYPE_DEF_COMP_DATA (0x09) #define MSG_TYPE_DEF_MACRO (0x0A) /* Serialize functions. */ uint8_t *def_serialize_gen(def_gen_t *def, uint32_t *len); /* Deserialize functions. */ def_gen_t *def_deserialize_gen(uint8_t *cursor, uint32_t size, uint32_t *bytes_used); #endif // MSG_DEF_H_ ion-3.2.0~dfsg1.orig/nm/shared/msg/msg_admin.c0000644000175000017500000006446112260400057017452 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file msg_admin.c ** ** Description: ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/21/12 E. Birrane Initial Implementation *****************************************************************************/ #include "platform.h" #include "ion.h" #include "shared/utils/utils.h" #include "shared/utils/nm_types.h" #include "shared/msg/msg_admin.h" /** * \brief serializes a register agent message into a buffer. * * \author Ed Birrane * * \note The returned message must be de-allocated from the memory pool. * * \return NULL - Failure * !NULL - The serialized message. * * \param[in] msg The message to serialize. * \param[out] len The length of the serialized message. */ uint8_t *msg_serialize_reg_agent(adm_reg_agent_t *msg, uint32_t *len) { Sdnv id; uint8_t *result = NULL; uint8_t *cursor = NULL; DTNMP_DEBUG_ENTRY("msg_serialize_reg_agent","(0x%x, 0x%x)", (unsigned long)msg, (unsigned long) len); /* Step 0: Sanity Checks. */ if((msg == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("msg_serialize_reg_agent","Bad Args",NULL); DTNMP_DEBUG_EXIT("msg_serialize_reg_agent","->NULL",NULL); return NULL; } /* * STEP 1: Figure out the size of the entire message. That includes the * length of the header, acl list, SDNV holding length, and data. */ int id_len = strlen(msg->agent_id.name); encodeSdnv(&id,id_len); *len = id.length + id_len; /* STEP 4: Allocate the serialized message. */ if((result = (uint8_t*)MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("msg_serialize_reg_agent","Can't alloc %d bytes", *len); *len = 0; DTNMP_DEBUG_EXIT("msg_serialize_reg_agent","->NULL",NULL); return NULL; } /* Step 5: Populate the serialized message. */ cursor = result; memcpy(cursor, id.text, id.length); cursor += id.length; memcpy(cursor, msg->agent_id.name, id_len); cursor += id_len; /* Step 6: Last sanity check. */ if((cursor - result) != *len) { DTNMP_DEBUG_ERR("msg_serialize_reg_agent","Wrote %d bytes but allcated %d", (unsigned long) (cursor - result), *len); *len = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("msg_serialize_reg_agent","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("msg_serialize_reg_agent","->0x%x",(unsigned long)result); return result; } /** * \brief serializes a report policy message into a buffer. * * \author Ed Birrane * * \note The returned message must be de-allocated from the memory pool. * * \return NULL - Failure * !NULL - The serialized message. * * \param[in] msg The message to serialize. * \param[out] len The length of the serialized message. */ uint8_t *msg_serialize_rpt_policy(adm_rpt_policy_t *msg, uint32_t *len) { uint8_t *result = NULL; uint8_t *cursor = NULL; DTNMP_DEBUG_ENTRY("msg_serialize_rpt_policy","(0x%x, 0x%x)", (unsigned long)msg, (unsigned long) len); /* Step 0: Sanity Checks. */ if((msg == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("msg_serialize_rpt_policy","Bad Args",NULL); DTNMP_DEBUG_EXIT("msg_serialize_rpt_policy","->NULL",NULL); return NULL; } /* * STEP 1: Figure out the size of the entire message. That includes the * length of the header, acl list, and 1 byte for the mask. */ *len = 1; /* STEP 4: Allocate the serialized message. */ if((result = (uint8_t*)MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("msg_serialize_rpt_policy","Can't alloc %d bytes", *len); *len = 0; DTNMP_DEBUG_EXIT("msg_serialize_rpt_policy","->NULL",NULL); return NULL; } /* Step 5: Populate the serialized message. */ cursor = result; memcpy(cursor, &(msg->mask),1); cursor += 1; /* Step 6: Last sanity check. */ if((cursor - result) != *len) { DTNMP_DEBUG_ERR("msg_serialize_rpt_policy","Wrote %d bytes but allcated %d", (unsigned long) (cursor - result), *len); *len = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("msg_serialize_rpt_policy","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("msg_serialize_rpt_policy","->0x%x",(unsigned long)result); return result; } /** * \brief serializes a status message into a buffer. * * \author Ed Birrane * * \note The returned message must be de-allocated from the memory pool. * * \return NULL - Failure * !NULL - The serialized message. * * \param[in] msg The message to serialize. * \param[out] len The length of the serialized message. */ uint8_t *msg_serialize_stat_msg(adm_stat_msg_t *msg, uint32_t *len) { uint8_t *result = NULL; uint8_t *cursor = NULL; uint8_t *code = NULL; uint32_t code_size = 0; uint8_t *list = NULL; uint32_t list_size = 0; Sdnv time; DTNMP_DEBUG_ENTRY("msg_serialize_stat_msg","(0x%x, 0x%x)", (unsigned long)msg, (unsigned long) len); /* Step 0: Sanity Checks. */ if((msg == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("msg_serialize_stat_msg","Bad Args",NULL); DTNMP_DEBUG_EXIT("msg_serialize_stat_msg","->NULL",NULL); return NULL; } /* STEP 3: Serialize the Code. */ if((code = mid_serialize(msg->code, &code_size)) == NULL) { DTNMP_DEBUG_ERR("msg_serialize_stat_msg","Can't serialize code.", NULL); DTNMP_DEBUG_EXIT("msg_serialize_stat_msg","->NULL",NULL); return NULL; } /* STEP 4: Serialize the MID Collection. */ if((list = midcol_serialize(msg->generators, &list_size)) == NULL) { DTNMP_DEBUG_ERR("msg_serialize_stat_msg","Can't serialize code.", NULL); MRELEASE(code); DTNMP_DEBUG_EXIT("msg_serialize_stat_msg","->NULL",NULL); return NULL; } /* Step 5: Build the timestamp SDNV. */ encodeSdnv(&time, msg->time); /* STEP 6: Figure out the size of the entire message. */ *len = code_size + list_size + time.length; /* STEP 7: Allocate the serialized message. */ if((result = (uint8_t*)MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("msg_serialize_stat_msg","Can't alloc %d bytes", *len); *len = 0; MRELEASE(code); MRELEASE(list); DTNMP_DEBUG_EXIT("msg_serialize_stat_msg","->NULL",NULL); return NULL; } /* Step 8: Populate the serialized message. */ cursor = result; memcpy(cursor,code,code_size); cursor += code_size; MRELEASE(code); memcpy(cursor, time.text, time.length); cursor += time.length; memcpy(cursor, list, list_size); cursor += list_size; MRELEASE(list); /* Step 9: Last sanity check. */ if((cursor - result) != *len) { DTNMP_DEBUG_ERR("msg_serialize_stat_msg","Wrote %d bytes but alloc %d", (unsigned long) (cursor - result), *len); *len = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("msg_serialize_stat_msg","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("msg_serialize_stat_msg","->0x%x",(unsigned long)result); return result; } /* Deserialize functions. */ /** * \brief Creates a register agent message from a buffer. * * \author Ed Birrane * * \note * - On failure (NULL return) we do NOT de-allocate the passed-in header. * * \return NULL - failure * !NULL - message. * * \param[in] cursor The buffer holding the message. * \param[in] size The remaining buffer size. * \param[out] bytes_used Bytes consumed in the deserialization. */ adm_reg_agent_t *msg_deserialize_reg_agent(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { Sdnv id; adm_reg_agent_t *result = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("msg_deserialize_reg_agent","(0x%x, %d, 0x%x)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((cursor == NULL) || (bytes_used == 0)) { DTNMP_DEBUG_ERR("msg_deserialize_reg_agent","Bad Args.",NULL); DTNMP_DEBUG_EXIT("msg_deserialize_reg_agent","->NULL",NULL); return NULL; } /* Step 1: Allocate the new message structure. */ if((result = (adm_reg_agent_t*)MTAKE(sizeof(adm_reg_agent_t))) == NULL) { DTNMP_DEBUG_ERR("msg_deserialize_reg_agent","Can't Alloc %d Bytes.", sizeof(adm_reg_agent_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("msg_deserialize_reg_agent","->NULL",NULL); return NULL; } else { memset(result,0,sizeof(adm_reg_agent_t)); } /* Step 2: Deserialize the message. */ /* Grab and check the size, as an SDNV */ int sdnv_len = 0; uvast sdnv_tmp = 0; sdnv_len = decodeSdnv(&(sdnv_tmp), cursor); if(sdnv_len > MAX_EID_LEN) { DTNMP_DEBUG_ERR("msg_deserialize_reg_agent", "EID size %d > max %d.", sdnv_tmp, MAX_EID_LEN); msg_release_reg_agent(result); *bytes_used = 0; DTNMP_DEBUG_EXIT("msg_deserialize_reg_agent","->NULL",NULL); return NULL; } else { cursor += sdnv_len; size -= sdnv_len; *bytes_used += sdnv_len; } // Copy EID. memcpy(result->agent_id.name,cursor,sdnv_tmp); cursor += sdnv_tmp; size -= sdnv_tmp; *bytes_used += sdnv_tmp; DTNMP_DEBUG_EXIT("msg_deserialize_reg_agent","->0x%x",(unsigned long)result); return result; } /** * \brief Creates a report policy message from a buffer. * * \author Ed Birrane * * \note * - On failure (NULL return) we do NOT de-allocate the passed-in header. * * \return NULL - failure * !NULL - message. * * \param[in] cursor The buffer holding the message. * \param[in] size The remaining buffer size. * \param[out] bytes_used Bytes consumed in the deserialization. */ adm_rpt_policy_t *msg_deserialize_rpt_policy(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { adm_rpt_policy_t *result = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("msg_deserialize_rpt_policy","(0x%x, %d, 0x%x)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((cursor == NULL) || (bytes_used == 0)) { DTNMP_DEBUG_ERR("msg_deserialize_rpt_policy","Bad Args.",NULL); DTNMP_DEBUG_EXIT("msg_deserialize_rpt_policy","->NULL",NULL); return NULL; } /* Step 1: Allocate the new message structure. */ if((result = (adm_rpt_policy_t*)MTAKE(sizeof(adm_rpt_policy_t))) == NULL) { DTNMP_DEBUG_ERR("msg_deserialize_rpt_policy","Can't Alloc %d Bytes.", sizeof(adm_rpt_policy_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("msg_deserialize_rpt_policy","->NULL",NULL); return NULL; } else { memset(result,0,sizeof(adm_rpt_policy_t)); } /* Step 2: Deserialize the message. */ /* Grab the mask */ result->mask = *cursor; cursor++; size--; *bytes_used += 1; DTNMP_DEBUG_EXIT("msg_deserialize_rpt_policy","->0x%x", (unsigned long)result); return result; } /** * \brief Creates a status message from a buffer. * * \author Ed Birrane * * \note * - On failure (NULL return) we do NOT de-allocate the passed-in header. * * \return NULL - failure * !NULL - message. * * \param[in] cursor The buffer holding the message. * \param[in] size The remaining buffer size. * \param[out] bytes_used Bytes consumed in the deserialization. */ adm_stat_msg_t *msg_deserialize_stat_msg(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { adm_stat_msg_t *result = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("msg_deserialize_stat_msg","(0x%x, %d, 0x%x)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((cursor == NULL) || (bytes_used == 0)) { DTNMP_DEBUG_ERR("msg_deserialize_stat_msg","Bad Args.",NULL); DTNMP_DEBUG_EXIT("msg_deserialize_stat_msg","->NULL",NULL); return NULL; } /* Step 1: Allocate the new message structure. */ if((result = (adm_stat_msg_t*)MTAKE(sizeof(adm_stat_msg_t))) == NULL) { DTNMP_DEBUG_ERR("msg_deserialize_stat_msg","Can't Alloc %d Bytes.", sizeof(adm_stat_msg_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("msg_deserialize_stat_msg","->NULL",NULL); return NULL; } else { memset(result,0,sizeof(adm_stat_msg_t)); } /* Step 2: Deserialize the message. */ /* Grab the mask */ if((result->code = mid_deserialize(cursor,size,&bytes)) == NULL) { DTNMP_DEBUG_ERR("msg_deserialize_stat_msg","Can't get code MID.",NULL); *bytes_used = 0; msg_release_stat_msg(result); DTNMP_DEBUG_EXIT("msg_deserialize_stat_msg","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } /* Grab the timestamp */ uvast val = 0; if((bytes = utils_grab_sdnv(cursor, size, &val)) == 0) { DTNMP_DEBUG_ERR("msg_deserialize_stat_msg","Can't get timestamp.",NULL); *bytes_used = 0; msg_release_stat_msg(result); DTNMP_DEBUG_EXIT("msg_deserialize_stat_msg","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; result->time = val; } /* Grab the Lyst. */ if((result->generators = midcol_deserialize(cursor,size,&bytes)) == NULL) { DTNMP_DEBUG_ERR("msg_deserialize_stat_msg","Can't get generators.",NULL); *bytes_used = 0; msg_release_stat_msg(result); DTNMP_DEBUG_EXIT("msg_deserialize_stat_msg","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("msg_deserialize_stat_msg","->0x%x", (unsigned long)result); return result; } /******* prod_rule *createProdRule(pdu* cur_pdu) { unsigned char* cursor; int sdnv_len = 0; unsigned long sdnv_tmp = 0; prod_rule *rule; DTNMP_DEBUG_PROC("+ PDU: createRule", NULL); / * Step 0: Sanity check the pdu type to ensure it contains a rule * / if(cur_pdu->hdr.type != MSG_TYPE_CTRL_PERIOD_PROD) { DTNMP_DEBUG_ERR("x PDU: Cannot create rule from msg of type %d", cur_pdu->hdr.type); DTNMP_DEBUG_PROC("- PDU: createRule -> NULL", NULL); return NULL; } / * Step 1: Allocate the new rule. * / if((rule = (prod_rule*) MTAKE(sizeof(prod_rule))) == NULL) { DTNMP_DEBUG_ERR("x PDU: Unable to allocate new rule.", NULL); DTNMP_DEBUG_PROC("- PDU: createRule -> NULL", NULL); return NULL; } rule->mids = lyst_create(); cursor = cur_pdu->content; DTNMP_DEBUG_INFO("i PDU: Cursor is %x", (unsigned long) cursor); / * Step 2: Extract the Offset for the Rule. * / if((sdnv_len = decodeSdnv(&sdnv_tmp, cursor)) == 0) { DTNMP_DEBUG_ERR("x PDU: No offset field in rule msg.", NULL); lyst_destroy(rule->mids); MRELEASE(rule); DTNMP_DEBUG_PROC("- PDU: createRule -> NULL", NULL); return NULL; } rule->offset = sdnv_tmp; cursor += sdnv_len; DTNMP_DEBUG_INFO("i PDU: Rule has offset value of %d", rule->offset); / * Step 3: Extract the Period for the Rule. * / if((sdnv_len = decodeSdnv(&(sdnv_tmp), cursor)) == 0) { DTNMP_DEBUG_ERR("x PDU: No period field in rule msg.", NULL); lyst_destroy(rule->mids); MRELEASE(rule); DTNMP_DEBUG_PROC("- PDU: createRule -> NULL", NULL); return NULL; } //rule->interval_ticks = ntohl(sdnv_tmp); rule->interval_ticks = sdnv_tmp; rule->countdown_ticks = rule->interval_ticks; cursor += sdnv_len; DTNMP_DEBUG_INFO("i PDU: Rule has interval value of %d", rule->interval_ticks); / * Step 4: Extract the # Evaluations for this Rule * / if((sdnv_len = decodeSdnv(&(sdnv_tmp), cursor)) == 0) { DTNMP_DEBUG_ERR("x PDU: No eval count field in rule msg.", NULL); lyst_destroy(rule->mids); MRELEASE(rule); DTNMP_DEBUG_PROC("- PDU: createRule -> NULL", NULL); return NULL; } //rule->num_evals = ntohl(sdnv_tmp); rule->num_evals = sdnv_tmp; if(rule->num_evals == 0) { rule->num_evals = DTNMP_RULE_EXEC_ALWAYS; } cursor += sdnv_len; DTNMP_DEBUG_INFO("i PDU: Rule has num evals value of %d", rule->num_evals); / * Step 5: Grab the list of MIDs to be produced by this rule. * / mid_t *cur_mid = NULL; unsigned long mid_used = 0; DTNMP_DEBUG_INFO("cursor %x content %x data is %x.", (unsigned long)cursor, (unsigned long) cur_pdu->content, (unsigned long) cur_pdu->data_size); while(cursor < (cur_pdu->content + cur_pdu->data_size)) { cur_mid = build_mid(cursor, (cur_pdu->content + cur_pdu->data_size) - cursor, &mid_used); if(cur_mid != NULL) { char *mid_str = mid_string(cur_mid); lyst_insert_last(rule->mids, cur_mid); cursor += mid_used; DTNMP_DEBUG_INFO("i PDU: Added MID %s to this RUle.", mid_str); MRELEASE(mid_str); } else { DTNMP_DEBUG_ERR("x PDU: Unknown MID.", NULL); lyst_destroy(rule->mids); MRELEASE(rule); return NULL; } } if(cursor != (cur_pdu->content + cur_pdu->data_size)) { DTNMP_DEBUG_WARN("w MID: Unexpected size mismatch: cursor (%x) end data (%x)", (unsigned long) cursor, (unsigned long) (cur_pdu->content + cur_pdu->data_size)); } strcpy(rule->sender.name, cur_pdu->meta.senderEid.name); DTNMP_DEBUG_INFO("i PDU: PDU sender EID is %s", rule->sender.name); DTNMP_DEBUG_PROC("- PDU: createProdRule -> %x", (unsigned long) rule); return rule; } nm_custom_report* createCustomReport(pdu *cur_pdu) { unsigned char* cursor; int sdnv_len = 0; unsigned long sdnv_tmp = 0; nm_custom_report *report; mid_t *cur_mid = NULL; unsigned long mid_used = 0; char *mid_str = NULL; DTNMP_DEBUG_PROC("+ PDU: createCustomReport(0x%x)", (unsigned long) cur_pdu); / * Step 0: Sanity check the pdu type to ensure it contains a rule * / if(cur_pdu->hdr.type != MSG_TYPE_DEF_CUST_RPT) { DTNMP_DEBUG_ERR("x PDU: Cannot create custom report from msg of type %d", cur_pdu->hdr.type); DTNMP_DEBUG_PROC("- PDU: createCustomReport -> NULL", NULL); return NULL; } / * Step 1: Allocate the new custom report definition. * / if((report = (nm_custom_report*) MTAKE(sizeof(nm_custom_report))) == NULL) { DTNMP_DEBUG_ERR("x PDU: Unable to allocate new custom report definition.", NULL); DTNMP_DEBUG_PROC("- PDU: createRule -> NULL", NULL); return NULL; } report->mids = lyst_create(); cursor = cur_pdu->content; DTNMP_DEBUG_INFO("i PDU: Cursor is %x", (unsigned long) cursor); / * Step 2: Extract the custom report ID. * / report->report_id = build_mid(cursor, (cur_pdu->content + cur_pdu->data_size) - cursor, &mid_used); mid_str = mid_string(report->report_id); DTNMP_DEBUG_INFO("i PDU: Report has ID of %s. Used is %d.", mid_str, mid_used); MRELEASE(mid_str); cursor += mid_used; / * Step 3: Grab the list of MIDs to be produced by this rule. * / while(cursor < (cur_pdu->content + cur_pdu->data_size)) { cur_mid = build_mid(cursor, (cur_pdu->content + cur_pdu->data_size) - cursor, &mid_used); if(cur_mid != NULL) { char *name = mid_string(cur_mid); lyst_insert_last(report->mids, cur_mid); cursor += mid_used; DTNMP_DEBUG_INFO("i PDU: Added MID %s of size %d to report.", name, mid_used); MRELEASE(name); } } if(cursor != (cur_pdu->content + cur_pdu->data_size)) { DTNMP_DEBUG_WARN("w MID: Unexpected size mismatch: cursor (%x) end data (%x)", (unsigned long) cursor, (unsigned long) (cur_pdu->content + cur_pdu->data_size)); } strcpy(report->sender.name, cur_pdu->meta.senderEid.name); DTNMP_DEBUG_INFO("i PDU: PDU sender EID is %s", report->sender.name); DTNMP_DEBUG_PROC("- PDU: createProdRule -> %x", (unsigned long) report); return report; } nm_report *createDataReport(pdu *cur_pdu) { unsigned char* cursor; int sdnv_len = 0; unsigned long sdnv_tmp = 0; nm_report *report; DTNMP_DEBUG_PROC("+ PDU: createDataReport(0x%x)", (unsigned long)cur_pdu); / * Step 0: Sanity check the pdu type to ensure it contains a rule * / if(cur_pdu->hdr.type != MSG_TYPE_RPT_DATA_RPT) { DTNMP_DEBUG_ERR("x PDU: Cannot create report from msg of type %d", cur_pdu->hdr.type); DTNMP_DEBUG_PROC("- PDU: createDataReport -> NULL", NULL); return NULL; } / * Step 1: Allocate the new report. * / if((report = (nm_report*) MTAKE(sizeof(nm_report))) == NULL) { DTNMP_DEBUG_ERR("x PDU: Unable to allocate new report of size %d.", sizeof(nm_report)); DTNMP_DEBUG_PROC("- PDU: createDataReport -> NULL", NULL); return NULL; } report->length = 0; report->report_data = lyst_create(); cursor = cur_pdu->content; DTNMP_DEBUG_INFO("i PDU: Cursor is %x", (unsigned long) cursor); / * Step 2: Extract the Report Timestamp * / if((sdnv_len = decodeSdnv(&(sdnv_tmp), cursor)) == 0) { DTNMP_DEBUG_ERR("x PDU: No timestamp field in report msg.", NULL); lyst_destroy(report->report_data); MRELEASE(report); DTNMP_DEBUG_PROC("- PDU: createDataReport -> NULL", NULL); return NULL; } report->timestamp = sdnv_tmp; cursor += sdnv_len; DTNMP_DEBUG_INFO("i PDU: Report has timestamp of %ld", report->timestamp); / * Step 3: Grab the data entries contained in this report. * / nm_report_entry *cur_entry = NULL; unsigned long mid_size = 0; char *mid_str; while(cursor < (cur_pdu->content + cur_pdu->data_size)) { / * Allocate the entry * / cur_entry = (nm_report_entry*) MTAKE(sizeof(nm_report_entry)); / * Grab the MID * / if((cur_entry->mid = build_mid(cursor, (cur_pdu->content + cur_pdu->data_size) - cursor, &mid_size)) == NULL) { DTNMP_DEBUG_ERR("x PDU: Unable to build MID!", NULL); MRELEASE(report); DTNMP_DEBUG_PROC("- PDU: createDataReport -> NULL", NULL); return NULL; } cursor += mid_size; report->length += mid_size; DTNMP_DEBUG_INFO("i PDU: MID size is %d", mid_size); / * Grab the data length. * / sdnv_len = decodeSdnv(&(sdnv_tmp), cursor); cur_entry->data_size = sdnv_tmp; report->length += sdnv_tmp; cursor += sdnv_len; DTNMP_DEBUG_INFO("i PDU: Got data size of %d", cur_entry->data_size); / * Grab the data * / cur_entry->data = (uint8_t*) MTAKE(cur_entry->data_size); memcpy(cur_entry->data, cursor, cur_entry->data_size); cursor += cur_entry->data_size; mid_str = mid_string(cur_entry->mid); DTNMP_DEBUG_INFO("i PDU: Added entry for mid %s of size %d", mid_str, cur_entry->data_size); MRELEASE(mid_str); / * Add the entry to the entry list. * / lyst_insert_last(report->report_data, cur_entry); } if(cursor != (cur_pdu->content + cur_pdu->data_size)) { DTNMP_DEBUG_WARN("w MID: Unexpected size mismatch: cursor (%x) end data (%x)", (unsigned long) cursor, (unsigned long) (cur_pdu->content + cur_pdu->data_size)); } strcpy(report->recipient.name, cur_pdu->meta.recipientEid.name); DTNMP_DEBUG_PROC("- PDU: createProdRule -> %x", (unsigned long) report); return report; } uint8_t *buildProdRulePDU(int offset, int period, int evals, Lyst mids, int mid_size, int *msg_len) { uint8_t *pdu; Sdnv offset_tmp; Sdnv period_tmp; Sdnv evals_tmp; uint32_t length = 0; LystElt elt; int idx = 0; DTNMP_DEBUG_PROC("+ PDU: buildProdRulePDU(%d, %d, %d, 0x%x", offset, period, evals, (unsigned long)mids); / * Translate the SDNVs * / encodeSdnv(&offset_tmp,offset); encodeSdnv(&period_tmp,period); encodeSdnv(&evals_tmp, evals); / * Figure out the length of the resulting buffer * / length = 1; / * Message Type. * / length += offset_tmp.length; length += period_tmp.length; length += evals_tmp.length; length += mid_size; if((pdu = (uint8_t*) MTAKE(length)) == NULL) { DTNMP_DEBUG_ERR("x PDU: Failed allocating pdu of size %d", length); return NULL; } idx = 0; pdu[idx++] = (uint8_t) MSG_TYPE_CTRL_PERIOD_PROD; memcpy(&(pdu[idx]), offset_tmp.text, offset_tmp.length); idx += offset_tmp.length; memcpy(&(pdu[idx]), period_tmp.text, period_tmp.length); idx += period_tmp.length; memcpy(&(pdu[idx]), evals_tmp.text, evals_tmp.length); idx += evals_tmp.length; for (elt = lyst_first(mids); elt; elt = lyst_next(elt)) { nm_adu_entry *entry = (nm_adu_entry*) lyst_data(elt); if((idx + entry->mid_len) > length) { DTNMP_DEBUG_ERR("x PDU: Invalid sizes. Length %d, idx+mid %d", length, idx + entry->mid_len); MRELEASE(pdu); return NULL; } memcpy(&pdu[idx], entry->mid, entry->mid_len); idx += entry->mid_len; } *msg_len = length; DTNMP_DEBUG_PROC("- PDU: buildProdRulePDU --> (0x%x)", pdu); return pdu; } uint8_t *buildReportDefPDU(mid_t *report_id, Lyst mids, uint32_t mid_size, int *msg_len) { uint8_t *pdu = NULL; uint32_t idx = 0; LystElt elt; DTNMP_DEBUG_INFO("i report_id size %d mis_size %d i %d", report_id->raw_size, mid_size, 1); *msg_len = report_id->raw_size + mid_size + 1; pdu = (uint8_t *) MTAKE(*msg_len); idx = 0; pdu[idx++] = (uint8_t) MSG_TYPE_DEF_CUST_RPT; memcpy(&(pdu[idx]), report_id->raw, report_id->raw_size); idx += report_id->raw_size; for (elt = lyst_first(mids); elt; elt = lyst_next(elt)) { mid_t *cur_mid = (mid_t*) lyst_data(elt); char *mid_str = NULL; if((idx + cur_mid->raw_size) > *msg_len) { DTNMP_DEBUG_ERR("x PDU: Invalid sizes. Length %d, idx+mid %d", *msg_len, idx + cur_mid->raw_size); MRELEASE(pdu); return NULL; } mid_str = mid_string(cur_mid); DTNMP_DEBUG_INFO("i PFU: Adding mid %s to custom report.", mid_str); MRELEASE(mid_str); memcpy(&pdu[idx], cur_mid->raw, cur_mid->raw_size); idx += cur_mid->raw_size; } DTNMP_DEBUG_PROC("- PDU: buildProdRulePDU --> (0x%x)", pdu); return pdu; } ***/ ion-3.2.0~dfsg1.orig/nm/shared/msg/msg_def.c0000644000175000017500000001321712260400057017111 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file msg_def.c ** ** Description: ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 11/02/12 E. Birrane Initial Implementation *****************************************************************************/ #include "platform.h" #include "ion.h" #include "shared/primitives/def.h" #include "shared/msg/msg_def.h" /** * \brief serializes a definition message into a buffer. * * \author Ed Birrane * * \note The returned message must be de-allocated from the memory pool. * * \return NULL - Failure * !NULL - The serialized message. * * \param[in] msg The message to serialize. * \param[out] len The length of the serialized message. */ uint8_t *def_serialize_gen(def_gen_t *def, uint32_t *len) { uint8_t *result = NULL; uint8_t *cursor = NULL; uint8_t *id = NULL; uint32_t id_len = 0; uint8_t *contents = NULL; uint32_t contents_len = 0; DTNMP_DEBUG_ENTRY("def_serialize_gen","(0x%x, 0x%x)", (unsigned long)def, (unsigned long) len); /* Step 0: Sanity Checks. */ if((def == NULL) || (len == NULL)) { DTNMP_DEBUG_ERR("def_serialize_gen","Bad Args",NULL); DTNMP_DEBUG_EXIT("def_serialize_gen","->NULL",NULL); return NULL; } *len = 0; /* STEP 1: Serialize the ID. */ if((id = mid_serialize(def->id, &id_len)) == NULL) { DTNMP_DEBUG_ERR("def_serialize_gen","Can't serialize hdr.",NULL); DTNMP_DEBUG_EXIT("def_serialize_gen","->NULL",NULL); return NULL; } /* STEP 2: Serialize the Contents. */ if((contents = midcol_serialize(def->contents, &contents_len)) == NULL) { DTNMP_DEBUG_ERR("def_serialize_gen","Can't serialize hdr.",NULL); MRELEASE(id); DTNMP_DEBUG_EXIT("def_serialize_gen","->NULL",NULL); return NULL; } /* Step 5: Figure out the length. */ *len = id_len + contents_len; /* STEP 6: Allocate the serialized message. */ if((result = (uint8_t*)MTAKE(*len)) == NULL) { DTNMP_DEBUG_ERR("def_serialize_gen","Can't alloc %d bytes", *len); *len = 0; MRELEASE(id); MRELEASE(contents); DTNMP_DEBUG_EXIT("def_serialize_gen","->NULL",NULL); return NULL; } /* Step 7: Populate the serialized message. */ cursor = result; memcpy(cursor, id, id_len); cursor += id_len; MRELEASE(id); memcpy(cursor, contents, contents_len); cursor += contents_len; MRELEASE(contents); /* Step 6: Last sanity check. */ if((cursor - result) != *len) { DTNMP_DEBUG_ERR("def_serialize_gen","Wrote %d bytes but allcated %d", (unsigned long) (cursor - result), *len); *len = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("def_serialize_gen","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("def_serialize_gen","->0x%x",(unsigned long)result); return result; } /* Deserialize functions. */ /** * \brief Creates a definition message from a buffer. * * \author Ed Birrane * * \note * - On failure (NULL return) we do NOT de-allocate the passed-in header. * * \return NULL - failure * !NULL - message. * * \param[in] cursor The buffer holding the message. * \param[in] size The remaining buffer size. * \param[out] bytes_used Bytes consumed in the deserialization. */ def_gen_t *def_deserialize_gen(uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { def_gen_t *result = NULL; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("def_deserialize_gen","(0x%x, %d, 0x%x)", (unsigned long)cursor, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((cursor == NULL) || (bytes_used == 0)) { DTNMP_DEBUG_ERR("def_deserialize_gen","Bad Args.",NULL); DTNMP_DEBUG_EXIT("def_deserialize_gen","->NULL",NULL); return NULL; } /* Step 1: Allocate the new message structure. */ if((result = (def_gen_t*)MTAKE(sizeof(def_gen_t))) == NULL) { DTNMP_DEBUG_ERR("def_deserialize_gen","Can't Alloc %d Bytes.", sizeof(def_gen_t)); *bytes_used = 0; DTNMP_DEBUG_EXIT("def_deserialize_gen","->NULL",NULL); return NULL; } else { memset(result,0,sizeof(def_gen_t)); } /* Step 2: Deserialize the message. */ /* Grab the ID MID. */ if((result->id = mid_deserialize(cursor, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("def_deserialize_gen","Can't grab ID MID.", sizeof(def_gen_t)); *bytes_used = 0; def_release_gen(result); DTNMP_DEBUG_EXIT("def_deserialize_gen","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } /* Grab the list of contents. */ if((result->contents = midcol_deserialize(cursor, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("def_deserialize_gen","Can't grab contents.",NULL); *bytes_used = 0; def_release_gen(result); DTNMP_DEBUG_EXIT("def_deserialize_gen","->NULL",NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } DTNMP_DEBUG_EXIT("def_deserialize_gen","->0x%x",(unsigned long)result); return result; } ion-3.2.0~dfsg1.orig/nm/shared/primitives/0000755000175000017500000000000012260400057016742 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/shared/primitives/rules.c0000644000175000017500000001534612260400057020251 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file msg_reports.c ** ** ** Description: ** **\todo Add more checks for overbounds reads on deserialization. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 11/04/12 E. Birrane Redesign of messaging architecture. ** 06/24/13 E. Birrane Migrated from uint32_t to time_t. *****************************************************************************/ #include "platform.h" #include "shared/utils/utils.h" #include "shared/msg/pdu.h" #include "shared/msg/msg_reports.h" #include "shared/msg/msg_ctrl.h" #include "shared/primitives/mid.h" #include "shared/primitives/rules.h" /* Create functions. */ rule_time_prod_t *rule_create_time_prod_entry(time_t time, uvast count, uvast period, Lyst contents) { rule_time_prod_t *result = NULL; DTNMP_DEBUG_ENTRY("rule_create_time_prod_entry","(%d, %d, %d, 0x%x)", time, count, period, (unsigned long) contents); /* Step 0: Sanity Check. */ if(contents == NULL) { DTNMP_DEBUG_ERR("rule_create_time_prod_entry","Bad Args.",NULL); DTNMP_DEBUG_EXIT("rule_create_time_prod_entry","->NULL",NULL); return NULL; } /* Step 1: Allocate the message. */ if((result = (rule_time_prod_t*)MTAKE(sizeof(rule_time_prod_t))) == NULL) { DTNMP_DEBUG_ERR("rule_create_time_prod_entry","Can't alloc %d bytes.", sizeof(rule_time_prod_t)); DTNMP_DEBUG_EXIT("rule_create_time_prod_entry","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->time = time; result->period = period; result->count = count; result->mids = contents; DTNMP_DEBUG_EXIT("rule_create_time_prod_entry","->0x%x",result); return result; } rule_pred_prod_t *rule_create_pred_prod_entry(time_t time, Lyst predicate, uvast count, Lyst contents) { /* \todo Implement this. */ return NULL; } ctrl_exec_t *ctrl_create_exec(time_t time, Lyst contents) { ctrl_exec_t *result = NULL; DTNMP_DEBUG_ENTRY("ctrl_create_exec","(%d, 0x%x)", time, (unsigned long) contents); /* Step 0: Sanity Check. */ if(contents == NULL) { DTNMP_DEBUG_ERR("ctrl_create_exec","Bad Args.",NULL); DTNMP_DEBUG_EXIT("ctrl_create_exec","->NULL",NULL); return NULL; } /* Step 1: Allocate the message. */ if((result = (ctrl_exec_t*)MTAKE(sizeof(ctrl_exec_t))) == NULL) { DTNMP_DEBUG_ERR("ctrl_create_exec","Can't alloc %d bytes.", sizeof(ctrl_exec_t)); DTNMP_DEBUG_EXIT("ctrl_create_exec","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->time = time; result->contents = contents; DTNMP_DEBUG_EXIT("ctrl_create_exec","->0x%x",result); return result; } /* Release functions.*/ void rule_release_time_prod_entry(rule_time_prod_t *msg) { if(msg != NULL) { midcol_destroy(&(msg->mids)); MRELEASE(msg); } } void rule_release_pred_prod_entry(rule_pred_prod_t *msg) { /* \todo Implement this. */ return; } void ctrl_release_exec(ctrl_exec_t *msg) { if(msg != NULL) { midcol_destroy(&(msg->contents)); MRELEASE(msg); } } void rule_time_clear_lyst(Lyst *list, ResourceLock *mutex, int destroy) { LystElt elt; rule_time_prod_t *entry = NULL; DTNMP_DEBUG_ENTRY("rule_time_clear_lyst","(0x%x, 0x%x, %d)", (unsigned long) list, (unsigned long) mutex, destroy); if((list == NULL) || (*list == NULL)) { DTNMP_DEBUG_ERR("rule_time_clear_lyst","Bad Params.", NULL); return; } if(mutex != NULL) { lockResource(mutex); } /* Free any reports left in the reports list. */ for (elt = lyst_first(*list); elt; elt = lyst_next(elt)) { /* Grab the current item */ if((entry = (rule_time_prod_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("rule_time_clear_lyst","Can't get report from lyst!", NULL); } else { rule_release_time_prod_entry(entry); } } lyst_clear(*list); if(destroy != 0) { lyst_destroy(*list); *list = NULL; } if(mutex != NULL) { unlockResource(mutex); } DTNMP_DEBUG_EXIT("rule_time_clear_lyst","->.",NULL); } void rule_pred_clear_lyst(Lyst *list, ResourceLock *mutex, int destroy) { LystElt elt; rule_pred_prod_t *entry = NULL; DTNMP_DEBUG_ENTRY("rule_pred_clear_lyst","(0x%x, 0x%x, %d)", (unsigned long) list, (unsigned long) mutex, destroy); if((list == NULL) || (*list == NULL)) { DTNMP_DEBUG_ERR("rule_pred_clear_lyst","Bad Params.", NULL); return; } if(mutex != NULL) { lockResource(mutex); } /* Free any reports left in the reports list. */ for (elt = lyst_first(*list); elt; elt = lyst_next(elt)) { /* Grab the current item */ if((entry = (rule_pred_prod_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("rule_pred_clear_lyst","Can't get report from lyst!", NULL); } else { rule_release_pred_prod_entry(entry); } } lyst_clear(*list); if(destroy != 0) { lyst_destroy(*list); *list = NULL; } if(mutex != NULL) { unlockResource(mutex); } DTNMP_DEBUG_EXIT("rule_pred_clear_lyst","->.",NULL); } void ctrl_clear_lyst(Lyst *list, ResourceLock *mutex, int destroy) { LystElt elt; ctrl_exec_t *entry = NULL; DTNMP_DEBUG_ENTRY("ctrl_clear_lyst","(0x%x, 0x%x, %d)", (unsigned long) list, (unsigned long) mutex, destroy); if((list == NULL) || (*list == NULL)) { DTNMP_DEBUG_ERR("ctrl_clear_lyst","Bad Params.", NULL); return; } if(mutex != NULL) { lockResource(mutex); } /* Free any reports left in the reports list. */ for (elt = lyst_first(*list); elt; elt = lyst_next(elt)) { /* Grab the current item */ if((entry = (ctrl_exec_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("ctrl_clear_lyst","Can't get report from lyst!", NULL); } else { ctrl_release_exec(entry); } } lyst_clear(*list); if(destroy != 0) { lyst_destroy(*list); *list = NULL; } if(mutex != NULL) { unlockResource(mutex); } DTNMP_DEBUG_EXIT("ctrl_clear_lyst","->.",NULL); } ion-3.2.0~dfsg1.orig/nm/shared/primitives/mid.c0000644000175000017500000013526412260400057017672 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file mid.c ** ** Subsystem: ** Network Management Utilities ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for the identification and ** processing of DTNMP Managed Identifiers (MIDs). ** ** Notes: ** \todo 1. Need to make sure that all serialize and deserialize methods ** do regular bounds checking whenever writing and often when ** reading. ** ** Assumptions: ** 1. We limit the size of an OID in the system to reduce the amount ** of pre-allocated memory in this embedded system. Non-embedded ** implementations may wish to dynamically allocate MIDs as they are ** received. ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/21/11 E. Birrane Code comments and functional updates. ** 10/22/12 E. Birrane Update to latest version of DTNMP. Cleanup. ** 06/25/13 E. Birrane New spec. rev. Remove priority from MIDs *****************************************************************************/ #include "platform.h" #include "shared/utils/utils.h" #include "shared/primitives/mid.h" /****************************************************************************** * * \par Function Name: mid_add_param * * \par Adds a parameter to the parameterized OID within a MID. * * \retval 0 Failure * !0 Success * * \param[in,out] mid The MID whose OID is getting a new param. * \param[in] value The value of the new parameter * \param[in] len The length, in bytes, of the new parameter. * * \par Notes: * 1. The new parameter is allocated into the new OID and, upon exit, * the passed-in value may be released if necessary. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation, *****************************************************************************/ int mid_add_param(mid_t *mid, uint8_t *value, uint32_t len) { int result = 0; DTNMP_DEBUG_ENTRY("mid_add_param","(%#llx, %#llx, %ld)", mid, value, len); /* Step 0: Sanity Check.*/ if((mid == NULL) || (value == NULL) || (len == 0)) { DTNMP_DEBUG_ERR("mid_add_param","Bad Args", NULL); DTNMP_DEBUG_EXIT("mid_add_param","->0.",NULL); return 0; } /* Step 1: Add to the OID. */ result = oid_add_param(mid->oid, value, len); DTNMP_DEBUG_EXIT("mid_add_param","->%d.",result); return result; } /****************************************************************************** * * \par Function Name: mid_clear * * \par Resets the values associated with a MID. Basically, a structure-aware * bzero. * * \retval void * * \param[in,out] mid The MID being cleared. * * \par Notes: * 1. Clearing a MID is different than destroying a MID. This just clears * allocated members. The MID itself may be re-used. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/12 E. Birrane Initial implementation, *****************************************************************************/ void mid_clear(mid_t *mid) { DTNMP_DEBUG_ENTRY("mid_clear","(%#llx)", (unsigned long) mid); if(mid == NULL) { DTNMP_DEBUG_ERR("mid_clear","Clearing NULL MID.", NULL); DTNMP_DEBUG_EXIT("mid_clear","->NULL.",NULL); return; } if(mid->raw != NULL) { MRELEASE(mid->raw); mid->raw = NULL; } if(mid->oid != NULL) { oid_release(mid->oid); mid->oid = NULL; } memset(mid, 0, sizeof(mid_t)); DTNMP_DEBUG_EXIT("mid_clear","", NULL); } /****************************************************************************** * * \par Function Name: mid_compare * * \par Determines equivalence of two MIDs. * * \retval -1,<0: Error or mid1 < mid2 * 0 : mid1 == mid2 * >0 : mid1 > mid2 * * \param[in] mid1 First MID being compared. * \param[in] mid2 Second MID being compared. * \param[in] use_parms Whether to compare OID paramaters as well. * * \par Notes: * 1. This function should only check for equivalence (== 0), not order * since we do not differentiate between mid1 < mid2 and error. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/12 E. Birrane Initial implementation, * 06/25/13 E. Birrane Removed references to priority field. *****************************************************************************/ int mid_compare(mid_t *mid1, mid_t *mid2, uint8_t use_parms) { int result = 1; DTNMP_DEBUG_ENTRY("mid_compare","(%#llx, %#llx)", (unsigned long) mid1, (unsigned long) mid2); if((mid1 == NULL) || (mid2 == NULL)) { return -1; } /* \todo: Cleanup */ if(use_parms != 0) { if(mid1->raw_size != mid2->raw_size) { return -1; } } /* For now, we can just compare the raw version of the mid */ /*result = memcmp(mid1->raw, mid2->raw, mid1->raw_size);*/ /* Step 3: Check if flag and MID length bytes match. */ if((mid1->flags == mid2->flags) && (mid1->issuer == mid2->issuer) && (mid1->tag == mid2->tag)) { result = oid_compare(mid1->oid, mid2->oid, use_parms); } DTNMP_DEBUG_EXIT("mid_compare","->%d.", result); return result; } /****************************************************************************** * * \par Function Name: mid_construct * * \par Constructs a MID object from arguments. * * \retval NULL - Failure * !NULL - The constructed MID * * \param[in] type The type of MID * \param[in] cat The MID category * \param[in] issuer The MID issuer, or NULL for no issuer. * \param[in] tag The MID tag, or NULL for no tag. * \param[in] oid The OID encapsulated in the MID. * * \par Notes: * 1. The returned MID is allocated and must be freed when no longer needed. * 2. The passed-in OID is *deep copied* and may be released before releasing * the MID. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/12 E. Birrane Initial implementation, * 06/17/13 E. Birrane Updated to ION 3.1.3, switched to uvast * 06/25/13 E. Birrane Removed references to priority field. *****************************************************************************/ mid_t *mid_construct(uint8_t type, uint8_t cat, uvast *issuer, uvast *tag, oid_t *oid) { mid_t *mid = NULL; DTNMP_DEBUG_ENTRY("mid_construct","(%#llx, %#llx, %#llx, %#llx, %#llx", type, cat, (unsigned long) issuer, (unsigned long) tag, (unsigned long) oid); /* Step 0: Sanity Check */ if(oid == NULL) { DTNMP_DEBUG_ERR("mid_construct","Bad Args.", NULL); DTNMP_DEBUG_EXIT("mid_construct","->NULL",NULL); return NULL; } /* Step 1: Allocate the MID. */ if((mid = (mid_t *)MTAKE(sizeof(mid_t))) == NULL) { DTNMP_DEBUG_ERR("mid_construct","Can't allocate %d bytes.", sizeof(mid_t)); DTNMP_DEBUG_EXIT("mid_construct","->NULL",NULL); return NULL; } /* Step 2: Populate the MID. */ /* Flag */ mid->flags = (oid->type & 0x03) << 6; mid->flags |= (tag != NULL) ? 0x20 : 0x00; mid->flags |= (issuer != NULL) ? 0x10 : 0x00; mid->flags |= (cat & 0x03) << 2; mid->flags |= (type & 0x03); /* Shallow copies */ mid->type = type; mid->category = cat; mid->issuer = (issuer != NULL) ? *issuer : 0; mid->tag = (tag != NULL) ? *tag : 0; if((mid->oid = oid_copy(oid)) == NULL) { DTNMP_DEBUG_ERR("mid_construct","Failed to copy OID.",NULL); MRELEASE(mid); DTNMP_DEBUG_EXIT("mid_construct","->NULL",NULL); return NULL; } /* Step 3: Build the serialized MID. */ if (mid_internal_serialize(mid) == 0) { DTNMP_DEBUG_ERR("mid_construct","Failed to serialize MID.",NULL); mid_release(mid); DTNMP_DEBUG_EXIT("mid_construct","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("mid_construct","->0x%x",(unsigned long)mid); return mid; } /****************************************************************************** * * \par Function Name: mid_copy * * \par Duplicates a MID object. * * \retval NULL - Failure * !NULL - The copied MID * * \param[in] src_mid The MID being copied. * * \par Notes: * 1. The returned MID is allocated and must be freed when no longer needed. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/12 E. Birrane Initial implementation, *****************************************************************************/ mid_t *mid_copy(mid_t *src_mid) { mid_t *result = 0; DTNMP_DEBUG_ENTRY("mid_copy","(%#llx)", (unsigned long) src_mid); /* Step 0: Sanity Check */ if(src_mid == NULL) { DTNMP_DEBUG_ERR("mid_copy","Cannot copy from NULL source MID.", NULL); DTNMP_DEBUG_EXIT("mid_copy","->NULL",NULL); return NULL; } /* Step 1: Allocate the new MID. */ if((result = (mid_t *)MTAKE(sizeof(mid_t))) == NULL) { DTNMP_DEBUG_ERR("mid_copy","Can't allocate %d bytes", sizeof(mid_t)); DTNMP_DEBUG_EXIT("mid_copy","->NULL",NULL); return NULL; } /* Step 2: Start with a shallow copy. */ memcpy(result, src_mid, sizeof(mid_t)); /* Step 3: Now, deep copy the pointers. */ result->oid = oid_copy(src_mid->oid); if((result->raw = (uint8_t *)MTAKE(src_mid->raw_size)) == NULL) { DTNMP_DEBUG_ERR("mid_copy","Can't allocate %d bytes", src_mid->raw_size); MRELEASE(result->oid); MRELEASE(result); DTNMP_DEBUG_EXIT("mid_copy","->NULL",NULL); return NULL; } memcpy(result->raw, src_mid->raw, src_mid->raw_size); DTNMP_DEBUG_EXIT("mid_copy","->%d", result); return result; } /****************************************************************************** * * \par Function Name: mid_deserialize * * \par Extracts a MID from a byte buffer. * * \retval NULL - Failure * !NULL - The created/deserialized MID. * * \param[in] buffer The byte buffer holding the MID data * \param[in] buffer_size The # bytes available in the buffer * \param[out] bytes_used The # of bytes consumed in the deserialization. * * \par Notes: * \todo: Allow a NULL bytes_used for cases where we are not deserializing * from a larger stream. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/12 E. Birrane Initial implementation, * 06/25/13 E. Birrane Removed references to priority field. *****************************************************************************/ mid_t *mid_deserialize(unsigned char *buffer, uint32_t buffer_size, uint32_t *bytes_used) { mid_t *result = NULL; unsigned char *cursor = NULL; int sdnv_len = 0; uint32_t cur_bytes = 0; uint32_t bytes_left=0; DTNMP_DEBUG_ENTRY("mid_deserialize","(%#llx, %d, %#llx)", (unsigned long) buffer, (unsigned long) buffer_size, (unsigned long) bytes_used); *bytes_used = 0; /* Step 1: Sanity checks. */ if((buffer == NULL) || (buffer_size == 0) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("mid_deserialize","Bad params.",NULL); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { *bytes_used = 0; cursor = buffer; bytes_left = buffer_size; } /* Step 2: Allocate/Zero the MID. */ if((result = (mid_t *) MTAKE(sizeof(mid_t))) == NULL) { DTNMP_DEBUG_ERR("mid_deserialize","Cannot allocate MID of size %d", sizeof(mid_t)); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { memset(result,0,sizeof(mid_t)); } /* Step 3: Grab the MID flag */ if(utils_grab_byte(cursor, bytes_left, &(result->flags)) != 1) { DTNMP_DEBUG_ERR("mid_deserialize","Can't grab flag byte.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { cursor += 1; bytes_left -= 1; *bytes_used += 1; } /* Step 4: Break out flag...*/ result->type = MID_GET_FLAG_TYPE(result->flags); result->category = MID_GET_FLAG_CAT(result->flags); /* Step 5: Grab issuer, if present. Issuers MUST exist for non-atomic.*/ if(MID_GET_FLAG_ISS(result->flags)) { cur_bytes = utils_grab_sdnv(cursor, bytes_left, &(result->issuer)); if( cur_bytes == 0) { DTNMP_DEBUG_ERR("mid_deserialize","Can't grab issuer.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { cursor += cur_bytes; bytes_left -= cur_bytes; *bytes_used += cur_bytes; } } /* Step 6: Grab the OID. */ switch(MID_GET_FLAG_OID(result->flags)) { case OID_TYPE_FULL: result->oid = oid_deserialize_full(cursor, bytes_left, &cur_bytes); break; case OID_TYPE_PARAM: result->oid = oid_deserialize_param(cursor, bytes_left, &cur_bytes); break; case OID_TYPE_COMP_FULL: result->oid = oid_deserialize_comp(cursor, bytes_left, &cur_bytes); break; case OID_TYPE_COMP_PARAM: result->oid = oid_deserialize_comp_param(cursor, bytes_left, &cur_bytes); break; default: result->oid = NULL; cur_bytes = 0; break; } if(result->oid == NULL) { DTNMP_DEBUG_ERR("mid_deserialize","Can't grab oid.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { cursor += cur_bytes; bytes_left -= cur_bytes; *bytes_used += cur_bytes; result->oid->type = MID_GET_FLAG_OID(result->flags); } /* Step 7: Populate Tag if preset. */ if(MID_GET_FLAG_TAG(result->flags)) { cur_bytes = utils_grab_sdnv(cursor, bytes_left, &(result->tag)); if( cur_bytes == 0) { DTNMP_DEBUG_ERR("mid_deserialize","Can't grab tag.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { cursor += cur_bytes; bytes_left -= cur_bytes; *bytes_used += cur_bytes; } } /* Step 8: Is this a sane MID? */ if(mid_sanity_check(result) == 0) { DTNMP_DEBUG_ERR("mid_deserialize","Flags Sanity Check Failed.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } /* Step 9: Copy MID into the raw value. */ if((result->raw = (unsigned char *) MTAKE(*bytes_used)) == NULL) { DTNMP_DEBUG_ERR("mid_deserialize","Can't TAKE raw mid of size (%d)", *bytes_used); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } memcpy(result->raw, buffer, *bytes_used); result->raw_size = *bytes_used; DTNMP_DEBUG_EXIT("mid_deserialize","-> %#llx", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: mid_internal_serialize * * \par populates the raw value of a MID with it's serialized representation. * * \par Since MIDs are used heavily in the agent, and since they are received in * a serialized form, it is efficient to keep the serialized version of the mid * to avoid having to re-calculate it. However, when the MID changes, or when * software generates the MID initially, the serialized representation must * be created. * * \par * +--------+--------+--------+--------+ * | Flags | Issuer | OID | Tag | * | [BYTE] | [SDNV] | [SDNV] | [SDNV] | * | | (opt.) | | (opt) | * +--------+--------+--------+--------+ * * \retval 0 - Failure * !0 - Success serializing the MID. * * \param[in,out] mid The MID being serialized * * \par Notes: * 1. The serialized version of the MID exists on the memory pool and must be * released when finished. * 2. Note that the issuer and tag are capped in this implementation. * 3. On error, the state of the mid->raw content is unknown. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/12 E. Birrane Initial implementation, * 06/25/13 E. Birrane Removed references to priority field. *****************************************************************************/ int mid_internal_serialize(mid_t *mid) { Sdnv iss; Sdnv tag; uint32_t oid_size = 0; uint8_t *oid_val = NULL; uint8_t *cursor = NULL; DTNMP_DEBUG_ENTRY("mid_internal_serialize","(%#llx)",(unsigned long) mid); /* Step 0: Sanity Check. */ if(mid == NULL) { DTNMP_DEBUG_ERR("mid_internal_serialize","Bad args.",NULL); DTNMP_DEBUG_EXIT("mid_internal_serialize","->0",NULL); return 0; } /* Step 1: Serialize the OID for sizing. */ if((oid_val = oid_serialize(mid->oid, &oid_size)) == NULL) { DTNMP_DEBUG_ERR("mid_internal_serialize","Can't serialize OID.",NULL); DTNMP_DEBUG_EXIT("mid_internal_serialize","->0",NULL); return 0; } /* Step 2: If there is a serialized version of the MID already, wipe it.*/ if(mid->raw != NULL) { MRELEASE(mid->raw); mid->raw = NULL; } mid->raw_size = 0; /* Step 3: Build the SDNVs. */ encodeSdnv(&iss, mid->issuer); encodeSdnv(&tag, mid->tag); /* Step 4: Figure out the size of the serialized MID. */ mid->raw_size = 1 + oid_size; /* Add issuer if present. */ if(MID_GET_FLAG_ISS(mid->flags)) { mid->raw_size += iss.length; } /* Add tag if present. */ if(MID_GET_FLAG_TAG(mid->flags)) { mid->raw_size += tag.length; } /* Step 5: Allocate space for the serialized MID. */ if((mid->raw = (uint8_t *)MTAKE(mid->raw_size)) == NULL) { DTNMP_DEBUG_ERR("mid_internal_serialize","Can't alloc %d bytes.", mid->raw_size); mid->raw_size = 0; MRELEASE(oid_val); DTNMP_DEBUG_EXIT("mid_internal_serialize","->0",NULL); return 0; } /* Step 6: Populate the serialized MID. */ cursor = mid->raw; *cursor = mid->flags; cursor++; /* Add issuer if present. */ if(MID_GET_FLAG_ISS(mid->flags)) { memcpy(cursor, iss.text, iss.length); cursor += iss.length; } /* Copy the OID. */ memcpy(cursor,oid_val, oid_size); cursor += oid_size; /* Add tag if present. */ if(MID_GET_FLAG_TAG(mid->flags)) { memcpy(cursor, tag.text, tag.length); cursor += tag.length; } /* Step 7: Final sanity check. */ if((cursor - mid->raw) != mid->raw_size) { DTNMP_DEBUG_ERR("mid_internal_serialize","Copied %d bytes, expected %d bytes.", (cursor - mid->raw), mid->raw_size); mid->raw_size = 0; MRELEASE(mid->raw); mid->raw = NULL; MRELEASE(oid_val); DTNMP_DEBUG_EXIT("mid_internal_serialize","->0",NULL); return 0; } DTNMP_DEBUG_EXIT("mid_internal_serialize","->1",NULL); return 1; } /****************************************************************************** * * \par Function Name: mid_pretty_print * * \par Purpose: Builds a string representation of the MID suitable for * diagnostic viewing. * * \retval NULL: Failure to construct a string representation of the MID. * !NULL: The string representation of the MID string. * * \param[in] mid The MID whose string representation is being created. * * \par Notes: * 1. This is a slow, wasteful function and should not be called in * embedded systems. For something to dump in a log, try the function * mid_to_string instead. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, * 06/25/13 E. Birrane Removed references to priority field. *****************************************************************************/ char *mid_pretty_print(mid_t *mid) { int size = 0; int oid_size = 0; int raw_size = 0; char *oid_str = NULL; char *raw_str; char *result = NULL; char *cursor = NULL; DTNMP_DEBUG_ENTRY("mid_pretty_print","(%#llx)", (unsigned long) mid); /* Step 0: Sanity Check. */ if(mid == NULL) { DTNMP_DEBUG_ERR("mid_pretty_print","NULL MID.",NULL); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL.",NULL); return NULL; } /* Step 1: Grab the pretty-print of the encapsulated OID. We will need to * do this anyway and it will help with the sizing. */ if(mid->oid != NULL) { oid_str = oid_pretty_print(mid->oid); oid_size = strlen((char *)oid_str) + 1; } if(oid_str == NULL) { oid_size = strlen("NULL_OID") + 1; if((oid_str = (char *) MTAKE(oid_size)) != NULL) { memset(oid_str,0,oid_size); strncpy((char *)oid_str,"NULL OID",oid_size); } else { DTNMP_DEBUG_ERR("mid_pretty_print","Can't alloc %d bytes for OID.", oid_size); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL.",NULL); return NULL; } } /* Step 2: Grab the raw version of the MID string. */ if((raw_str = mid_to_string(mid)) == NULL) { raw_size = strlen("NO RAW!") + 1; if((raw_str = (char *) MTAKE(raw_size)) != NULL) { memset(raw_str, 0, raw_size); strncpy(raw_str,"NO RAW!", raw_size); } else { DTNMP_DEBUG_ERR("mid_pretty_print","Can't alloc %d bytes for RAW.", raw_size); MRELEASE(oid_str); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL.",NULL); return NULL; } } else { raw_size = strlen((char*)raw_str) + 1; } /* Step 3: Guestimate size. This is, at best, a dark art and prone to * exaggeration. Numerics are assumed to take 5 bytes, unless I * think they will take 3 instead (indices vs. values). Other * values are based on constant strings in the function. One must * update this calculation if one changes string constants, else * one will be sorry. */ size = 28 + /* BANNER------ */ 14 + /* Flag : <...> */ 18 + /* Type : <...> */ 17 + /* Cat : <...> */ 17 + /* ISS : <...> */ 7 + oid_size + /* OID : <...> */ 17 + /* Tag : <...> */ 7 + raw_size + /* Raw : <...> */ 28; /* BANNER ----- */ /* Step 4: Allocate the string. */ if((result = (char*)MTAKE(size)) == NULL) { DTNMP_DEBUG_ERR("mid_pretty_print", "Can't alloc %d bytes.", size); MRELEASE(oid_str); MRELEASE(raw_str); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL",NULL); return NULL; } else { memset(result,0,size); } /* Step 5: Populate the allocated string. Keep an eye on the size. */ cursor = result; cursor += sprintf(cursor,"MID:\n---------------------\nFlag: %#x",mid->flags); cursor += sprintf(cursor,"\nType : "); switch(mid->type) { case 0: cursor += sprintf(cursor,"DATA\n"); break; case 1: cursor += sprintf(cursor,"CONTROL\n"); break; case 2: cursor += sprintf(cursor,"LITERAL\n"); break; case 3: cursor += sprintf(cursor,"OPERATOR\n"); break; default: cursor += sprintf(cursor,"UNKNOWN\n"); break; } cursor += sprintf(cursor,"Cat: "); switch(mid->category) { case 0: cursor += sprintf(cursor,"ATOMIC\n"); break; case 1: cursor += sprintf(cursor,"COMPUTED\n"); break; case 2: cursor += sprintf(cursor,"COLLECTION\n"); break; default: cursor += sprintf(cursor,"UNKNOWN\n"); break; } if(MID_GET_FLAG_ISS(mid->flags)) { cursor += sprintf(cursor,UVAST_FIELDSPEC"\n",mid->issuer); } else { cursor += sprintf(cursor,"None.\n"); } cursor += sprintf(cursor,"OID : %s", oid_str); MRELEASE(oid_str); if(MID_GET_FLAG_TAG(mid->flags)) { cursor += sprintf(cursor,UVAST_FIELDSPEC"\n",mid->tag); } else { cursor += sprintf(cursor,"None.\n"); } cursor += sprintf(cursor,"RAW : %s", raw_str); MRELEASE(raw_str); /* Step 6: Sanity check. */ if((cursor - result) > size) { DTNMP_DEBUG_ERR("mid_pretty_print", "OVERWROTE! Alloc %d, wrote %llu.", size, (cursor-result)); MRELEASE(result); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL",NULL); return NULL; } DTNMP_DEBUG_INFO("mid_pretty_print","Wrote %llu into %d string.", (cursor -result), size); DTNMP_DEBUG_EXIT("mid_pretty_print","->%#llx",result); return result; } /****************************************************************************** * * \par Function Name: mid_release * * \par Purpose: Frees resources associated with a MID * * \param[in,out] mid The MID being released. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, *****************************************************************************/ void mid_release(mid_t *mid) { DTNMP_DEBUG_ENTRY("mid_release", "(%#llx)", (unsigned long) mid); if(mid != NULL) { mid_clear(mid); MRELEASE(mid); mid = NULL; } DTNMP_DEBUG_EXIT("mid_release", "-> NULL", NULL); } /****************************************************************************** * * \par Function Name: mid_sanity_check * * \par Purpose: Evaluates the consistency of MID member values. * * \retval 0: The MID failed its check. * !0: The MID passed its check. * * \param[in] mid The MID being released. * * \par Notes: * 1. This function keeps going after first sanity failure to collect * all MID problems in the error log. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, * 06/25/13 E. Birrane Removed references to priority field. Removed * type/cat checks as spec allows many new combos. *****************************************************************************/ int mid_sanity_check(mid_t *mid) { int result = 1; DTNMP_DEBUG_ENTRY("mid_sanity_check","(%#llx)", (unsigned long) mid); /* NULL Checks */ if(mid == NULL) { DTNMP_DEBUG_ERR("mid_sanity_check","NULL mid.", NULL); return 0; } /* Range Checks */ if(mid->type > 3) { DTNMP_DEBUG_ERR("mid_sanity_check","Type out of range (%d)", mid->type); result = 0; } if(mid->category > 2) { DTNMP_DEBUG_ERR("mid_sanity_check","Cat. out of range (%d)", mid->category); result = 0; } if(mid->oid == NULL) { DTNMP_DEBUG_ERR("mid_sanity_check","NULL OID.",NULL); result = 0; } else if(mid->oid->type > 3) { DTNMP_DEBUG_ERR("mid_sanity_check","OID type out of range (%d)", mid->oid->type); result = 0; } /* Type/Category Checks */ if ( ((mid->type == MID_TYPE_CONTROL) && (mid->category == MID_CAT_COMPUTED)) || ((mid->type == MID_TYPE_LITERAL) && (mid->category != MID_CAT_ATOMIC)) || ((mid->type == MID_TYPE_OPERATOR) && (mid->category != MID_CAT_ATOMIC)) ) { DTNMP_DEBUG_ERR("mid_sanity_check","Bad type(%d)/cat.(%d) combo.", mid->type, mid->category); result = 0; } DTNMP_DEBUG_EXIT("mid_sanity_check","-> %d", result); return result; } /****************************************************************************** * * \par Function Name: mid_serialize * * \par Purpose: Returns a serialized version of the MID. * * \retval NULL - Failure * !NULL - The serialized MID. * * \param[in,out] mid The MID being serialized * \param[out] size The # bytes of the serialized MID. * * \par Notes: * 1. The serialized version of the MID exists on the memory pool and must be * released when finished. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, *****************************************************************************/ uint8_t *mid_serialize(mid_t *mid, uint32_t *size) { uint8_t *result = NULL; DTNMP_DEBUG_ENTRY("mid_serialize","(%#llx, %#llx)", (unsigned long) mid, (unsigned long) size); /* Step 0: Sanity Check. */ if((mid == NULL) || (size == NULL)) { DTNMP_DEBUG_ERR("mid_serialize","Bad args.", NULL); DTNMP_DEBUG_EXIT("mid_serialize","->NULL", NULL); return NULL; } /* Step 1: Make sure the MID is serialized. */ if((mid->raw == NULL) || (mid->raw_size == 0)) { if(mid_internal_serialize(mid) == 0) { DTNMP_DEBUG_ERR("mid_serialize","Can't serialize mid.", NULL); *size = 0; DTNMP_DEBUG_EXIT("mid_serialize","->NULL", NULL); return NULL; } } *size = mid->raw_size; /* Step 2: Allocate result. */ if((result = (uint8_t*) MTAKE(*size)) == NULL) { DTNMP_DEBUG_ERR("mid_serialize","Can't alloc %d bytes.", *size); *size = 0; DTNMP_DEBUG_EXIT("mid_serialize","->NULL", NULL); return NULL; } /* Step 3: Copy in the result. */ memcpy(result, mid->raw, mid->raw_size); DTNMP_DEBUG_EXIT("mid_serialize","->%#llx", (unsigned long)result); return result; } /****************************************************************************** * * \par Function Name: mid_to_string * * \par Purpose: Create a string representation of the MID. * * \retval NULL - Failure * !NULL - The string representation of the raw MID. * * \param[in] mid The MID whose string representation is being calculated. * * \par Notes: * 1. The string is dynamically allocated from the memory pool and must * be deallocated when no longer needed. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, *****************************************************************************/ char *mid_to_string(mid_t *mid) { char *result = NULL; DTNMP_DEBUG_ENTRY("mid_to_string","(%#llx)",(unsigned long) mid); /* For now, we just show the raw MID. */ result = utils_hex_to_string(mid->raw, mid->raw_size); DTNMP_DEBUG_EXIT("mid_to_string","->%s.", result); return result; } /****************************************************************************** * * \par Function Name: midcol_copy * * \par Purpose: Copies a MID collection * * \retval NULL - Failure * !NULL - The copied MID collection * * \param[in] mids MID collection to be copied. * * \par Notes: * 1. This is a deep copy. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, *****************************************************************************/ Lyst midcol_copy(Lyst mids) { Lyst result = NULL; LystElt elt; mid_t *cur_mid = NULL; mid_t *new_mid = NULL; DTNMP_DEBUG_ENTRY("midcol_copy","(%#llx)",(unsigned long) mids); /* Step 0: Sanity Check. */ if(mids == NULL) { DTNMP_DEBUG_ERR("midcol_copy","Bad Args.",NULL); DTNMP_DEBUG_EXIT("midcol_copy","->NULL.",NULL); return NULL; } /* Build the Lyst. */ if((result = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("midcol_copy","Unable to create lyst.",NULL); DTNMP_DEBUG_EXIT("midcol_copy","->NULL.",NULL); return NULL; } /* Walking copy. */ int success = 1; for(elt = lyst_first(mids); elt; elt = lyst_next(elt)) { cur_mid = (mid_t *) lyst_data(elt); if((new_mid = mid_copy(cur_mid)) == NULL) { DTNMP_DEBUG_ERR("midcol_copy","Fsiled to copy MID.",NULL); midcol_destroy(&result); DTNMP_DEBUG_EXIT("midcol_copy","->NULL.",NULL); return NULL; } else { lyst_insert_last(result,mid_copy(cur_mid)); } } DTNMP_DEBUG_EXIT("midcol_copy","->%#llx.",(unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: midcol_destroy * * \par Purpose: Destroy MID collection in a Lyst. * * \retval NULL - Failure * !NULL - The copied MID collection * * \param[in,out] mids The lyst being destroyed. * * \par Notes: * 1. We pass a double pointer for the honor of making sure the lyst is set * to NULL when finished. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, *****************************************************************************/ void midcol_destroy(Lyst *mids) { LystElt elt; mid_t *cur_mid = NULL; DTNMP_DEBUG_ENTRY("midcol_destroy","(%#llx)", (unsigned long) mids); /* * Step 0: Make sure we even have a lyst. Not an error if not, since we * are destroying anyway. */ if((mids == NULL) || (*mids == NULL)) { DTNMP_DEBUG_ERR("midcol_destroy","Bad Args.",NULL); DTNMP_DEBUG_EXIT("midcol_destroy","->.", NULL); return; } /* Step 1: Walk through the MIDs releasing as you go. */ for(elt = lyst_first(*mids); elt; elt = lyst_next(elt)) { cur_mid = (mid_t *) lyst_data(elt); if(cur_mid != NULL) { mid_release(cur_mid); } } /* Step 2: Destroy and zero out the lyst. */ lyst_destroy(*mids); *mids = NULL; DTNMP_DEBUG_EXIT("midcol_destroy","->.", NULL); } /****************************************************************************** * * \par Function Name: midcol_deserialize * * \par Purpose: Deserialize a MID collection into a Lyst. * * \retval NULL - Failure * !NULL - The created Lyst. * * \param[in] buffer The buffer holding the MC. * \param[in] buffer_size The size of the buffer, in bytes. * \param[out] bytes_used The # bytes consumed in the deserialization. * * \par Notes: * 1. The created Lyst must be freed when done. * 2. Reminder: A Lyst is a pointer to a LystStruct. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, * 06/17/13 E. Birrane Updated to ION 3.1.3, moved to uvast *****************************************************************************/ Lyst midcol_deserialize(unsigned char *buffer, uint32_t buffer_size, uint32_t *bytes_used) { unsigned char *cursor = NULL; Lyst result = NULL; uint32_t bytes = 0; uvast num = 0; mid_t *cur_mid = NULL; uint32_t i = 0; DTNMP_DEBUG_ENTRY("midcol_deserialize","(%#llx,%d,%#llx)", (unsigned long) buffer, buffer_size, (unsigned long) bytes_used); /* Step 0: Sanity Check. */ if((buffer == NULL) || (buffer_size == 0) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("mid_deserialize_mc","Bad Args", NULL); DTNMP_DEBUG_EXIT("mid_deserialize_mc","->NULL",NULL); return NULL; } *bytes_used = 0; cursor = buffer; /* Step 1: Create the Lyst. */ if((result = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("midcol_deserialize","Can't create lyst.", NULL); DTNMP_DEBUG_EXIT("midcol_deserialize","->NULL",NULL); return NULL; } /* Step 2: Grab # MIDs in the collection. */ if((bytes = utils_grab_sdnv(cursor, buffer_size, &num)) == 0) { DTNMP_DEBUG_ERR("midcol_deserialize","Can't parse SDNV.", NULL); lyst_destroy(result); DTNMP_DEBUG_EXIT("midcol_deserialize","->NULL",NULL); return NULL; } else { cursor += bytes; buffer_size -= bytes; *bytes_used += bytes; } /* Step 3: Grab Mids. */ for(i = 0; i < num; i++) { /* Deserialize ith MID. */ if((cur_mid = mid_deserialize(cursor, buffer_size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("mid_deserialize_mc","Can't grab MID #%d.", i); midcol_destroy(&result); DTNMP_DEBUG_EXIT("mid_deserialize_mc","->NULL",NULL); return NULL; } else { cursor += bytes; buffer_size -= bytes; *bytes_used += bytes; } /* Drop it in the lyst in order. */ lyst_insert_last(result, cur_mid); } DTNMP_DEBUG_EXIT("midcol_deserialize","->%#llx",(unsigned long)result); return result; } /****************************************************************************** * * \par Function Name: midcol_pretty_print * * \par Purpose: Builds a string representation of a MID collection suitable for * diagnostic viewing. * * \retval NULL: Failure to construct a string representation of the MID coll. * !NULL: The string representation of the MID coll string. * * \param[in] mc The MID collection whose string rep is being created. * * \par Notes: * 1. This is a slow, wasteful function and should not be called in * embedded systems. For something to dump in a log, try the function * midcol_to_string instead. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, *****************************************************************************/ char *midcol_pretty_print(Lyst mc) { LystElt elt; char *result = NULL; char *cursor = NULL; int num_items = 0; int i = 0; char **mid_strs = NULL; int tot_size = 0; DTNMP_DEBUG_ENTRY("midcol_pretty_print","(%#llx)", (unsigned long) mc); /* Step 0: Sanity Check. */ if(mc == NULL) { DTNMP_DEBUG_ERR("midcol_pretty_print","Bad Args.", NULL); DTNMP_DEBUG_EXIT("midcol_pretty_print","->NULL", NULL); return NULL; } /* Step 1: Grab the number of MIDs in the collection, and pre-allocate * space to store their printed information. */ num_items = (int) lyst_length(mc); mid_strs = (char**) MTAKE(num_items * sizeof(char*)); if(mid_strs == NULL) { DTNMP_DEBUG_ERR("midcol_pretty_print","Can't alloc %d bytes.", num_items * sizeof(char *)); DTNMP_DEBUG_EXIT("midcol_pretty_print","->NULL",NULL); return NULL; } /* Step 2: Grab the pretty-print of individual MIDs. We need this anyway * and it will help us get the sizing right. */ for(elt = lyst_first(mc); (elt && (i < num_items)); elt=lyst_next(elt)) { mid_t *cur_mid = (mid_t*) lyst_data(elt); mid_strs[i] = mid_pretty_print(cur_mid); tot_size += strlen(mid_strs[i]); i++; } /* Step 3: Calculate size of the MID collection print and allocate it. */ tot_size += 28 + /* HEADER and ---'s */ 28 + /* Trailer ---'s */ num_items; /* newline per MID. */ if((result = (char *) MTAKE(tot_size)) == NULL) { DTNMP_DEBUG_ERR("midcol_pretty_print","Can't alloc %d bytes.", tot_size); for(i = 0; i < num_items; i++) { MRELEASE(mid_strs[i]); } MRELEASE(mid_strs); DTNMP_DEBUG_EXIT("midcol_pretty_print","->NULL",NULL); return NULL; } else { cursor = result; } /* Step 4: Fill in the MID collection string. */ cursor += sprintf(cursor,"MID COLLECTION:\n-------------\n"); for(i = 0; i < num_items; i++) { cursor += sprintf(cursor,"%s\n",mid_strs[i]); MRELEASE(mid_strs[i]); } cursor += sprintf(cursor,"--------------\n"); MRELEASE(mid_strs); /* Step 5: Sanity check. */ if((cursor - result) > tot_size) { DTNMP_DEBUG_ERR("midcol_pretty_print", "OVERWROTE! Alloc %d, wrote %llu.", tot_size, (cursor-result)); MRELEASE(result); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL",NULL); return NULL; } DTNMP_DEBUG_INFO("midcol_pretty_print","Wrote %llu into %d string.", (cursor -result), tot_size); DTNMP_DEBUG_EXIT("midcol_pretty_print","->%#llx",result); return result; } /****************************************************************************** * * \par Function Name: midcol_to_string * * \par Purpose: Create a string representation of a MID collection. * * \retval NULL - Failure * !NULL - The string representation of the MID collection. * * \param[in] mc The collection whose string representation is being calculated. * * \par Notes: * 1. The string is dynamically allocated from the memory pool and must * be deallocated when no longer needed. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/23/12 E. Birrane Initial implementation, *****************************************************************************/ char *midcol_to_string(Lyst mc) { LystElt elt; char *result = NULL; char *cursor = NULL; int num_items = 0; int i = 0; char **mid_strs = NULL; int tot_size = 0; DTNMP_DEBUG_ENTRY("midcol_to_string","(%#llx)", (unsigned long) mc); /* Step 0: Sanity Check. */ if(mc == NULL) { DTNMP_DEBUG_ERR("midcol_to_string","Bad Args.", NULL); DTNMP_DEBUG_EXIT("midcol_to_string","->NULL", NULL); return NULL; } /* Step 1: Grab the number of MIDs in the collection, and pre-allocate * space to store their printed information. */ num_items = (int) lyst_length(mc); mid_strs = (char**) MTAKE(num_items * sizeof(char*)); if(mid_strs == NULL) { DTNMP_DEBUG_ERR("midcol_to_string","Can't alloc %d bytes.", num_items * sizeof(char *)); DTNMP_DEBUG_EXIT("midcol_to_string","->NULL",NULL); return NULL; } /* Step 2: Grab the pretty-print of individual MIDs. We need this anyway * and it will help us get the sizing right. */ for(elt = lyst_first(mc); (elt && (i < num_items)); elt=lyst_next(elt)) { mid_t *cur_mid = (mid_t*) lyst_data(elt); mid_strs[i] = mid_to_string(cur_mid); tot_size += strlen(mid_strs[i]); i++; } /* Step 3: Calculate size of the MID collection print and allocate it. */ tot_size += 5 + /* "MC : " */ 2 + /* trailer */ num_items; /* space between MIDs. */ if((result = (char *) MTAKE(tot_size)) == NULL) { DTNMP_DEBUG_ERR("midcol_to_string","Can't alloc %d bytes.", tot_size); for(i = 0; i < num_items; i++) { MRELEASE(mid_strs[i]); } MRELEASE(mid_strs); DTNMP_DEBUG_EXIT("midcol_to_string","->NULL",NULL); return NULL; } else { cursor = result; } /* Step 4: Fill in the MID collection string. */ cursor += sprintf(cursor,"MC : "); for(i = 0; i < num_items; i++) { cursor += sprintf(cursor,"%s ",mid_strs[i]); MRELEASE(mid_strs[i]); } cursor += sprintf(cursor,".\n"); MRELEASE(mid_strs); /* Step 5: Sanity check. */ if((cursor - result) > tot_size) { DTNMP_DEBUG_ERR("midcol_to_string", "OVERWROTE! Alloc %d, wrote %llu.", tot_size, (cursor-result)); MRELEASE(result); DTNMP_DEBUG_EXIT("mid_to_string","->NULL",NULL); return NULL; } DTNMP_DEBUG_INFO("midcol_to_string","Wrote %llu into %d string.", (cursor -result), tot_size); DTNMP_DEBUG_EXIT("midcol_to_string","->%#llx",result); return result; } /****************************************************************************** * * \par Function Name: midcol_serialize * * \par Purpose: Serialize a MID collection. * * \retval NULL - Failure * !NULL - Serialized MC. * * \param[in] mids The list of MIDs comprising the collection. * \param[out] size The number of bytes of serialized MC. * * \par Notes: * 1. The serialized collection is allocated on the memory pool and must * be returned when no longer needed. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/23/12 E. Birrane Initial implementation, *****************************************************************************/ uint8_t *midcol_serialize(Lyst mids, uint32_t *size) { uint8_t *result = NULL; Sdnv num_sdnv; LystElt elt; DTNMP_DEBUG_ENTRY("midcol_serialize","(%#llx, %#llx)", (unsigned long) mids, (unsigned long) size); /* Step 0: Sanity Check */ if((mids == NULL) || (size == NULL)) { DTNMP_DEBUG_ERR("midcol_serialize","Bad args.", NULL); DTNMP_DEBUG_EXIT("midcol_serialize","->NULL",NULL); return NULL; } /* Step 1: Calculate the size. */ /* Consider the size of the SDNV holding # MIDS.*/ encodeSdnv(&num_sdnv, lyst_length(mids)); *size = num_sdnv.length; /* Walk through each MID, make sure it is serialized, and look at size. */ for(elt = lyst_first(mids); elt; elt = lyst_next(elt)) { mid_t *cur_mid = (mid_t *) lyst_data(elt); if(cur_mid != NULL) { if((cur_mid->raw == NULL) || (cur_mid->raw_size == 0)) { /* \todo check return code. */ mid_internal_serialize(cur_mid); } if((cur_mid->raw == NULL) || (cur_mid->raw_size == 0)) { DTNMP_DEBUG_WARN("midcol_serialize","MID didn't serialize.", NULL); } else { *size += cur_mid->raw_size; } } else { DTNMP_DEBUG_WARN("midcol_serialize","Found NULL MID?", NULL); } } /* Step 3: Allocate the space for the serialized list. */ if((result = (uint8_t*) MTAKE(*size)) == NULL) { DTNMP_DEBUG_ERR("midcol_serialize","Can't alloc %d bytes", *size); *size = 0; DTNMP_DEBUG_EXIT("midcol_serialize","->NULL",NULL); return NULL; } /* Step 4: Walk through list again copying as we go. */ uint8_t *cursor = result; /* COpy over the number of MIDs in the collection. */ memcpy(cursor, num_sdnv.text, num_sdnv.length); cursor += num_sdnv.length; for(elt = lyst_first(mids); elt; elt = lyst_next(elt)) { mid_t *cur_mid = (mid_t *) lyst_data(elt); if(cur_mid != NULL) { if((cur_mid->raw != NULL) && (cur_mid->raw_size > 0)) { memcpy(cursor,cur_mid->raw, cur_mid->raw_size); cursor += cur_mid->raw_size; } } else { DTNMP_DEBUG_WARN("midcol_serialize","Found NULL MID?", NULL); } } /* Step 5: Final sanity check. */ if((cursor - result) != *size) { DTNMP_DEBUG_ERR("midcol_serialize","Wrote %d bytes not %d bytes", (cursor - result), *size); *size = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("midcol_serialize","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("midcol_serialize","->%#llx",(unsigned long) result); return result; } ion-3.2.0~dfsg1.orig/nm/shared/primitives/rules.h0000644000175000017500000001512512260400057020251 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file rules.h ** ** ** Description: ** **\todo Right now this is a dumping ground for common utilities across **\todo agent and manager. Need to make this a little more eloquent. ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 11/08/12 E. Birrane Redesign of messaging architecture. ** 06/24/13 E. Birrane Migrated from uint32_t to time_t. *****************************************************************************/ #ifndef _RULES_H_ #define _RULES_H_ #include "lyst.h" #include "shared/utils/nm_types.h" #include "shared/primitives/mid.h" /*#include "shared/msg/pdu.h" #include "shared/msg/msg_def.h" #include "shared/msg/msg_reports.h" */ /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ #define DTNMP_RULE_EXEC_ALWAYS (-1) #define CONTROL_ACTIVE (1) #define CONTROL_INACTIVE (0) /* * +--------------------------------------------------------------------------+ * | MACROS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ typedef struct { Object itemObj; /**> Serialized rule in an SDR. */ uint32_t size; /**> Size of rule in ruleObj. */ /* Descriptor Information. */ int64_t num_evals; /**> # times left to eval rule. */ uint32_t interval_ticks; /**> # 1Hz ticks between evals. */ eid_t sender; /**> Who sent this rule def. */ /* Below is not kept in the SDR. */ Object descObj; /** > This descriptor in SDR. */ } rule_time_prod_desc_t; /** * Associated Message Type(s): MSG_TYPE_CTRL_PERIOD_PROD * * Purpose: * * +--------+------------+--------+---------+ * | Start | Period (s) | Count | Results | * | (TS) | (SDNV) | (SDNV) | (MC) | * +--------+------------+--------+---------+ */ typedef struct { time_t time; /**> The time to start the production. */ uvast period; /**> The delay between productions. */ uvast count; /**> The # times to produce the message. */ Lyst mids; /**> The MIDs to include in the report. */ /* Below is not serialized. */ uint32_t countdown_ticks; /**> # ticks before next eval. */ rule_time_prod_desc_t desc; /**> SDR descriptor. */ } rule_time_prod_t; typedef struct { Object itemObj; /**> Serialized rule in an SDR. */ uint32_t size; /**> Size of rule in ruleObj. */ /* Descriptor Information. */ int64_t num_evals; /**> # times left to eval rule. */ uint32_t interval_ticks; /**> # 1Hz ticks between evals. */ eid_t sender; /**> Who sent this rule def. */ /* Below is not kept in the SDR. */ Object descObj; /** > This descriptor in SDR. */ } rule_pred_prod_descr_t; /** * Associated Message Type(s): MSG_TYPE_CTRL_PRED_PROD * * Purpose: * * +--------+-----------+--------+---------+ * | Start | Predicate | Count | Results | * | (TS) | (MC) | (SDNV) | (MC) | * +--------+-----------+--------+---------+ */ typedef struct { time_t time; /**> The time to start the production. */ Lyst predicate; /**> The predicate driving report production.*/ uvast count; /**> The # times to produce the message. */ Lyst contents; /**> The MIDs to include in the report. */ /* Below is not serialized. */ uint32_t countdown_ticks; /**> # ticks before next eval. */ rule_pred_prod_descr_t descObj; /**> SDR descriptor */ } rule_pred_prod_t; typedef struct { Object itemObj; /**> Serialized ctrl in an SDR. */ uint32_t size; /**> Size of ctrl in ctrlObj. */ /* Descriptor Information. */ eid_t sender; /**> Who sent this ctrl def. */ uint8_t state; /**> 0: INACTIVE, 1, ACTIVE */ /* Below is not kept in the SDR. */ Object descObj; /** > This descriptor in SDR. */ } ctrl_exec_desc_t; /** * Associated Message Type(s): MSG_TYPE_CTRL_PERF_CTRL * * Purpose: Runs a control on the agent. * * +-------+-----------+ * | Start | Controls | * | (TS) | (MC) | * +-------+-----------+ */ typedef struct { time_t time; /**> The time to run the control. */ Lyst contents; /**> The controls (macro) to run. */ /* Below is not serialized. */ uint32_t countdown_ticks; /**> # ticks before next eval. */ ctrl_exec_desc_t desc; /**> SDR descriptor. */ } ctrl_exec_t; /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ /* Create functions. */ rule_time_prod_t *rule_create_time_prod_entry(time_t time, uvast count, uvast period, Lyst contents); rule_pred_prod_t *rule_create_pred_prod_entry(time_t time, Lyst predicate, uvast count, Lyst contents); ctrl_exec_t *ctrl_create_exec(time_t time, Lyst contents); /* Release functions.*/ void rule_release_time_prod_entry(rule_time_prod_t *msg); void rule_release_pred_prod_entry(rule_pred_prod_t *msg); void ctrl_release_exec(ctrl_exec_t *msg); /* Lyst functions. */ void rule_time_clear_lyst(Lyst *list, ResourceLock *mutex, int destroy); void rule_pred_clear_lyst(Lyst *list, ResourceLock *mutex, int destroy); void ctrl_clear_lyst(Lyst *list, ResourceLock *mutex, int destroy); #endif // _RULES_H_ ion-3.2.0~dfsg1.orig/nm/shared/primitives/oid.h0000644000175000017500000001621612260400057017674 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: oid.h ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for the identification and ** processing of Object Identifiers (OIDs) and the OID nickname ** database. ** ** Notes: ** 1. In the current implementation, the nickname database is not ** persistent. ** 2. We do not support a "create" function for OIDs as, so far, any ** need to create OIDs can be met by calling the appropriate ** deserialize function. ** ** Assumptions: ** 1. We limit the size of an OID in the system to reduce the amount ** of pre-allocated memory in this embedded system. Non-embedded ** implementations may wish to dynamically allocate MIDs as they are ** received. ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/27/12 E. Birrane Initial Implementation ** 11/13/12 E. Birrane Technical review, comment updates. *****************************************************************************/ #ifndef OID_H_ #define OID_H_ #include "stdint.h" #include "platform.h" #include "ion.h" #include "lyst.h" #include "shared/utils/debug.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ /** * OID TYPES * * FULL: SNMP ASN.1 OID encoded with BER. * EX: * PARAM: OID with parameters appended. * EX: <#P>... * COMP_FULL: Compressed, full OID * EX: * COMP_PARAM: COmpressed, parameterized OID * EX: <#P>... */ #define OID_TYPE_FULL 0 #define OID_TYPE_PARAM 1 #define OID_TYPE_COMP_FULL 2 #define OID_TYPE_COMP_PARAM 3 /** * Maximum size, in bytes, supported by any OID in the system. * WARNING: Changes to these values must be reflected in the associated MID * data types and associated functions. */ #define MAX_OID_SIZE (32) #define MAX_OID_PARM (5) /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ /** * Describes an OID nickname database entry. * * The OID nickname database maps unique identifiers to a full or partial * OID representation. The encapsulated partial/full OID may be used in place * of the nickname when re-constructing an OID from a protocol data unit. */ typedef struct { uvast id; /**> The nickname identifier. */ uint8_t raw[MAX_OID_SIZE]; /**> The OID representing the expansion*/ uint32_t raw_size; /**> Size of the expansion OID. */ } oid_nn_t; /** * Describes an Object Identifier (OID). * * RAW OID Handling: * The value and value_size members capture the raw OID as originally * communicated when the OID was defined. For a FULL OID, this is the full OID. * For parameterized OIDs, this is the common (non-parameterized) part of the * OID. For a compressed OID, this is the unique part of the OID that is not * elided behind the nickname. The value includes the # bytes portion. * * PARAMETER HANDLING: * The num_parm member stores the number of parameters in the OID. * The raw_parms and parms_size capture the serialized parameters (including * size SDNV) and the size of the serialized parameter buffer, respectively. * The parm_idx array holds a series of indices into raw_parms identifying the * start of the ith parameter SDNV within raw_parms. For example, to decode * the 3rd parameter, the SDNV string would start at raw_parms[parm_idx[3]]. * * NICKNAME HANDLING * The nn_id holds the identifier of the OID nickname. The nickname expansion * is not represented in this structure. * * \todo * - This structure is huge. Will need to migrate this to dynamic memory * once we achieve baseline functionality. */ typedef struct { uint8_t type; /**> Type of OID. */ Lyst params; // uint32_t num_parm; /**> Number of parameters in the OID */ // uint32_t parm_idx[MAX_OID_PARM]; /**> Index into raw_parms of ith parm */ // uint8_t raw_parms[MAX_OID_SIZE]; /**> Raw parms (including # parms) */ // uint32_t parms_size; /**> Size of all parms (w/ # parms) */ uvast nn_id; /**> Optional nickname for this OID. */ uint8_t value[MAX_OID_SIZE]; /**> OID, sans nickname & parms. */ uint32_t value_size; /**> Length in bytes of OID value (incl. room for the size) */ } oid_t; /* * +--------------------------------------------------------------------------+ * | DATA DEFINITIONS + * +--------------------------------------------------------------------------+ */ /** * \todo Migrate this to a more efficient structure, and make persistent. */ extern Lyst nn_db; extern ResourceLock nn_db_mutex; /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ int oid_add_param(oid_t *oid, uint8_t *value, uint32_t len); uint32_t oid_calc_size(oid_t *oid); void oid_clear(oid_t *oid); int oid_compare(oid_t *oid1, oid_t *oid2, uint8_t use_parms); oid_t* oid_copy(oid_t *src_oid); oid_t* oid_deserialize_comp(unsigned char *buffer, uint32_t size, uint32_t *bytes_used); oid_t* oid_deserialize_comp_param(unsigned char *buffer, uint32_t size, uint32_t *bytes_used); oid_t* oid_deserialize_full(unsigned char *buffer, uint32_t size, uint32_t *bytes_used); oid_t* oid_deserialize_param(unsigned char *buffer, uint32_t size, uint32_t *bytes_used); char* oid_pretty_print(oid_t *oid); void oid_release(oid_t *oid); int oid_sanity_check(oid_t *oid); uint8_t* oid_serialize(oid_t *oid, uint32_t *size); char* oid_to_string(oid_t *oid); int oid_nn_add(oid_nn_t *nn); void oid_nn_cleanup(); int oid_nn_delete(uvast nn_id); LystElt oid_nn_exists(uvast nn_id); oid_nn_t* oid_nn_find(uvast nn_id); int oid_nn_init(); #endif /* OID_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/primitives/admin.h0000644000175000017500000000725412260400057020213 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file admin.h ** ** ** Description: Administrative primitives. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/17/13 E. Birrane Redesign of messaging architecture. ** 06/24/13 E. Birrane Migrated from uint32_t to time_t. *****************************************************************************/ #ifndef _ADMIN_H_ #define _ADMIN_H_ #include "shared/utils/nm_types.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | MACROS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ /* * Associated Message Type: MSG_TYPE_ADMIN_REG_AGENT * Purpose: Notify manager of discovered agent. * +-------+----------+ * | Size | Agent ID | * | (SDNV)| (var) | * +-------+----------+ */ typedef struct { eid_t agent_id; /**> ID of the agent being registered. */ } adm_reg_agent_t; /* * Associated Message Type: MSG_TYPE_ADMIN_RPT_POLICY * Purpose: Set the reporting policy on an agent. * * +-------+--------+-------+-------+----------+ * | Alert | Warn | Error | Log | Reserved | * +-------+--------+-------+-------+----------+ * | 0 | 1 | 2 | 3 | 4 5 6 7 | * +-------+--------+-------+-------+----------+ * LSB MSB */ typedef struct { uint8_t mask; /**> Reporting Policy Mask. */ } adm_rpt_policy_t; /* * Associated Message Type: MSG_TYPE_ADMIN_STAT_MSG * Purpose: Report status from an agent. * +------+------+------------+ * | Code | Time | Generators | * |(MID) | (TS) | (MC) | * +------+------+------------+ */ typedef struct { mid_t *code; /**> Status Code. */ time_t time; /**> Time when code occurred. */ Lyst generators; /**> MID list of generators. */ } adm_stat_msg_t; /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ /* Create functions. */ adm_reg_agent_t *msg_create_reg_agent(eid_t eid); adm_rpt_policy_t *msg_create_rpt_policy(uint8_t mask); adm_stat_msg_t *msg_create_stat_msg(mid_t *code, time_t time, Lyst generators); /* Release functions.*/ void msg_release_reg_agent(adm_reg_agent_t *msg); void msg_release_rpt_policy(adm_rpt_policy_t *msg); void msg_release_stat_msg(adm_stat_msg_t *msg); #endif /* _ADMIN_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/primitives/instr.h0000644000175000017500000000502312260400057020252 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file instr.h ** ** ** Description: DTNMP Instrumentation headers. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/04/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef _INSTR_H_ #define _INSTR_H_ #include "shared/utils/nm_types.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | MACROS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ typedef struct { unsigned long num_rpt_defs; // done unsigned long num_sent_rpts; // done unsigned long num_time_rules; // done unsigned long num_time_rules_run; // done unsigned long num_prod_rules; unsigned long num_prod_rules_run; unsigned long num_consts; unsigned long num_data_defs; unsigned long num_macros; // done unsigned long num_macros_run; unsigned long num_ctrls; // done unsigned long num_ctrls_run; //done } agent_instr_t; /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ void agent_instr_init(); void agent_instr_clear(); extern agent_instr_t gAgentInstr; #endif /* _INSTR_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/primitives/def.h0000644000175000017500000000642412260400057017657 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file def.h ** ** ** Description: Structures that capture protocol custom definitions. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/17/13 E. Birrane Redesign of messaging architecture. *****************************************************************************/ #ifndef _DEF_H_ #define _DEF_H_ #include "mid.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | MACROS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ typedef struct { Object itemObj; /**> Location of definition in SDR. */ uint32_t size; /**> Size of definition in the SDR */ Object descObj; /**> Location of this descr in SDR. */ } def_gen_desc_t; /* * Associated Message Type(s): MSG_TYPE_DEF_CUST_RPT * MSG_TYPE_DEF_COMP_DATA * MSG_TYPE_DEF_MACRO * * Purpose: Define custom item on an agent. Since many definitions in the * standard have the same format, we use one data structure to * represent them. * * +-------+------------+ * | ID | Contents | * | (MID) | (MC) | * +-------+------------+ */ typedef struct { mid_t *id; /**> The identifier (name) of the report. */ Lyst contents; /**> The ordered MIDs comprising the definition. */ /* Below items are not serialized with this structure. */ def_gen_desc_t desc; /**> Descriptor of def in the SDR. */ } def_gen_t; /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ /* Create functions. */ def_gen_t *def_create_gen(mid_t *id, Lyst contents); def_gen_t *def_find_by_id(Lyst defs, ResourceLock *mutex, mid_t *id); /* Release functions.*/ void def_release_gen(def_gen_t *def); void def_lyst_clear(Lyst *list, ResourceLock *mutex, int destroy); void def_print_gen(def_gen_t *def); #endif /* _DEF_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/primitives/report.c0000644000175000017500000002211612260400057020423 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file report.c ** ** ** Description: ** ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/11/13 E. Birrane Redesign of primitives architecture. ** 06/24/13 E. Birrane Migrated from uint32_t to time_t. *****************************************************************************/ #include "platform.h" #include "shared/utils/utils.h" #include "shared/msg/pdu.h" #include "shared/msg/msg_reports.h" #include "shared/msg/msg_ctrl.h" #include "report.h" /* Create functions. */ /** * \brief Convenience function to build data report message. * * \author Ed Birrane * * \note * - We shallow copy information into the message. So, don't release anything * provided as an argument to this function. * * \return NULL - Failure * !NULL - Created message. * * \param[in[ contents The data IDs available. */ rpt_items_t *rpt_create_lst(Lyst contents) { rpt_items_t *result = NULL; DTNMP_DEBUG_ENTRY("rpt_create_lst","(0x%x)", (unsigned long) contents); /* Step 0: Sanity Check. */ if(contents == NULL) { DTNMP_DEBUG_ERR("rpt_create_lst","Bad Args.",NULL); DTNMP_DEBUG_EXIT("rpt_create_lst","->NULL",NULL); return NULL; } /* Step 1: Allocate the message. */ if((result = (rpt_items_t*)MTAKE(sizeof(rpt_items_t))) == NULL) { DTNMP_DEBUG_ERR("rpt_create_lst","Can't alloc %d bytes.", sizeof(rpt_items_t)); DTNMP_DEBUG_EXIT("rpt_create_lst","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->contents = contents; DTNMP_DEBUG_EXIT("rpt_create_lst","->0x%x",result); return result; } /** * \brief Convenience function to build a data definition report. * * \author Ed Birrane * * \note * - We shallow copy information into the message. So, don't release anything * provided as an argument to this function. * * \return NULL - Failure * !NULL - Created message. * * \param[in[ defs The data definitions. */ rpt_defs_t* rpt_create_defs(Lyst defs) { rpt_defs_t *result = NULL; DTNMP_DEBUG_ENTRY("rpt_create_defs","(0x%x)", (unsigned long) defs); /* Step 0: Sanity Check. */ if(defs == NULL) { DTNMP_DEBUG_ERR("rpt_create_defs","Bad Args.",NULL); DTNMP_DEBUG_EXIT("rpt_create_defs","->NULL",NULL); return NULL; } /* Step 1: Allocate the message. */ if((result = (rpt_defs_t*)MTAKE(sizeof(rpt_defs_t))) == NULL) { DTNMP_DEBUG_ERR("rpt_create_defs","Can't alloc %d bytes.", sizeof(rpt_defs_t)); DTNMP_DEBUG_EXIT("rpt_create_defs","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->defs = defs; DTNMP_DEBUG_EXIT("rpt_create_defs","->0x%x",result); return result; } /** * \brief Convenience function to build a data report. * * \author Ed Birrane * * \note * - We shallow copy information into the message. So, don't release anything * provided as an argument to this function. * * \return NULL - Failure * !NULL - Created message. * * \param[in] time The time when the report was created. * \param[in[ reports The data reports. */ rpt_data_t *rpt_create_data(time_t time, Lyst reports, eid_t recipient) { rpt_data_t *result = NULL; DTNMP_DEBUG_ENTRY("rpt_create_data","(%d,0x%x,%s)", time, (unsigned long) reports, recipient.name); /* Step 0: Sanity Check. */ if(reports == NULL) { DTNMP_DEBUG_ERR("rpt_create_data","Bad Args.",NULL); DTNMP_DEBUG_EXIT("rpt_create_data","->NULL",NULL); return NULL; } /* Step 1: Allocate the message. */ if((result = (rpt_data_t*) MTAKE(sizeof(rpt_data_t))) == NULL) { DTNMP_DEBUG_ERR("rpt_create_data","Can't alloc %d bytes.", sizeof(rpt_data_t)); DTNMP_DEBUG_EXIT("rpt_create_data","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->time = time; result->reports = reports; result->recipient = recipient; result->size = 0; DTNMP_DEBUG_EXIT("rpt_create_data","->0x%x",result); return result; } /** * \brief Convenience function to build a data report. * * \author Ed Birrane * * \note * - We shallow copy information into the message. So, don't release anything * provided as an argument to this function. * * \return NULL - Failure * !NULL - Created message. * * \param[in[ defs The data reports. */ rpt_prod_t *rpt_create_prod(Lyst defs) { rpt_prod_t *result = NULL; DTNMP_DEBUG_ENTRY("rpt_create_prod","(0x%x)", (unsigned long) defs); /* Step 0: Sanity Check. */ if(defs == NULL) { DTNMP_DEBUG_ERR("rpt_create_prod","Bad Args.",NULL); DTNMP_DEBUG_EXIT("rpt_create_prod","->NULL",NULL); return NULL; } /* Step 1: Allocate the message. */ if((result = (rpt_prod_t*)MTAKE(sizeof(rpt_prod_t))) == NULL) { DTNMP_DEBUG_ERR("rpt_create_prod","Can't alloc %d bytes.", sizeof(rpt_prod_t)); DTNMP_DEBUG_EXIT("rpt_create_prod","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->defs = defs; DTNMP_DEBUG_EXIT("rpt_create_prod","->0x%x",result); return result; } /* Release functions.*/ void rpt_release_lst(rpt_items_t *msg) { DTNMP_DEBUG_ENTRY("rpt_release_lst","(0x%x)", (unsigned long) msg); if(msg != NULL) { if(msg->contents != NULL) { midcol_destroy(&(msg->contents)); } MRELEASE(msg); } DTNMP_DEBUG_EXIT("rpt_release_lst","->.",NULL); } void rpt_release_defs(rpt_defs_t *msg) { DTNMP_DEBUG_ENTRY("rpt_release_defs","(0x%x)", (unsigned long) msg); if(msg != NULL) { if(msg->defs != NULL) { midcol_destroy(&(msg->defs)); } MRELEASE(msg); } DTNMP_DEBUG_EXIT("rpt_release_defs","->.",NULL); } void rpt_release_data_entry(rpt_data_entry_t *entry) { if(entry != NULL) { MRELEASE(entry->contents); mid_release(entry->id); MRELEASE(entry); } } void rpt_release_data(rpt_data_t *msg) { DTNMP_DEBUG_ENTRY("rpt_release_data","(0x%x)", (unsigned long) msg); if(msg != NULL) { LystElt elt; rpt_data_entry_t *item; for(elt = lyst_first(msg->reports); elt; elt = lyst_next(elt)) { item = (rpt_data_entry_t *) lyst_data(elt); rpt_release_data_entry(item); /* \todo Double check we don't need to kill the ELT here versus as * part of lyst_destroy. */ } lyst_destroy(msg->reports); MRELEASE(msg); } DTNMP_DEBUG_EXIT("rpt_release_data","->.",NULL); } void rpt_release_prod(rpt_prod_t *msg) { DTNMP_DEBUG_ENTRY("rpt_release_prod","(0x%x)", (unsigned long) msg); if(msg != NULL) { LystElt elt; rule_time_prod_t *item; for(elt = lyst_first(msg->defs); elt; elt = lyst_next(elt)) { item = (rule_time_prod_t *) lyst_data(elt); rule_release_time_prod_entry(item); /* \todo Double check we don't need to kill the ELT here versus as * part of lyst_destroy. */ } lyst_destroy(msg->defs); MRELEASE(msg); } DTNMP_DEBUG_EXIT("rpt_release_prod","->.",NULL); } void rpt_print_data_entry(rpt_data_entry_t *entry) { char *id_str = NULL; if(entry == NULL) { fprintf(stderr,"NULL ENTRY.\n"); } id_str = mid_pretty_print(entry->id); fprintf(stderr,"DATA ENTRY:\n%s\n", id_str); MRELEASE(id_str); fprintf(stderr,"SIZE: %d\n", (uint32_t)entry->size); utils_print_hex(entry->contents, entry->size); } /** * \brief Cleans up a lyst of data reports. * * \author Ed Birrane * * \param[in,out] reportLyst THe lyst to be cleared. */ void rpt_clear_lyst(Lyst *list, ResourceLock *mutex, int destroy) { LystElt elt; rpt_data_t *cur_rpt = NULL; DTNMP_DEBUG_ENTRY("rpt_clear_lyst","(0x%x, 0x%x, %d)", (unsigned long) list, (unsigned long) mutex, destroy); if((list == NULL) || (*list == NULL)) { DTNMP_DEBUG_ERR("rpt_clear_lyst","Bad Params.", NULL); return; } if(mutex != NULL) { lockResource(mutex); } /* Free any reports left in the reports list. */ for (elt = lyst_first(*list); elt; elt = lyst_next(elt)) { /* Grab the current report */ if((cur_rpt = (rpt_data_t*) lyst_data(elt)) == NULL) { DTNMP_DEBUG_WARN("rpt_clear_lyst","Can't get report from lyst!", NULL); } else { rpt_release_data(cur_rpt); } } lyst_clear(*list); if(destroy != 0) { lyst_destroy(*list); *list = NULL; } if(mutex != NULL) { unlockResource(mutex); } DTNMP_DEBUG_EXIT("rpt_clear_lyst","->.", NULL); } ion-3.2.0~dfsg1.orig/nm/shared/primitives/report.h0000644000175000017500000001203412260400057020426 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file report.h ** ** ** Description: Defines report data types for DTNMP. ** ** Notes: ** 1. Currently we do not support ACLs. ** 2. Currently, report is destined to go to whoever requested the ** production of the report. ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/11/13 E. Birrane Redesign of primitives architecture. ** 06/24/13 E. Birrane Migrated from uint32_t to time_t. *****************************************************************************/ #ifndef _REPORT_H_ #define _REPORT_H_ #include "lyst.h" #include "shared/utils/nm_types.h" #include "shared/primitives/def.h" /* #include "shared/msg/pdu.h" #include "shared/msg/msg_def.h" #include "shared/msg/msg_reports.h" */ /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | MACROS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ /** * Associated Message Type(s): MSG_TYPE_RPT_DATA_LIST * * Purpose: Define a data list report. * * +---------------+ * | Configured ID | * | (MC) | * +---------------+ */ typedef struct { Lyst contents; /**> The ordered MIDs comprising the data list. */ } rpt_items_t; /** * Associated Message Type(s): MSG_TYPE_RPT_DATA_DEFS * * Purpose: Define a data definition report. * * +--------+------+----------+ +------+----------+ * | # Defs | ID 1 | Def 1 | ... | ID N | Def N | * | (SDNV) |(MID) | (MC) | |(MID) | (MC) | * +--------+------+----------+ +------+----------+ */ typedef struct { Lyst defs; /**> The ordered MIDs comprising the data defs. */ } rpt_defs_t; /** * Entry in a data report list, comprising a single report. */ typedef struct { mid_t *id; /**> The report ID. */ uvast size; /**> The number of bytes of report data. */ uint8_t *contents; /**> The report data. */ } rpt_data_entry_t; /** * Associated Message Type(s): MSG_TYPE_RPT_DATA_RPT * * Purpose: A data report. * \todo Update the standard * +------+------+------+-------+---------+ +------+------+---------+ * | Time | SIZE |ID | Size | Data[n] | | ID | Size | Data[m] | * | (TS) |(SDNV)|(SDNV)|(SDNV) | (BYTEs) |...|(SDNV)|(SDNV)| (BYTEs) | * +------+------+------+-------+---------+ +------+------+---------+ */ typedef struct { time_t time; /**> Time the reports were generated. */ Lyst reports; /**> The reports (lyst of rpt_data_entry_t */ eid_t recipient; uint32_t size; } rpt_data_t; /** * Associated Message Type(s): MSG_TYPE_RPT_PROD_SCHED * * Purpose: Define a data definition report. * \todo: Support for predicate types as well? * * +---------+--------+ +--------+ * | # Rules | Rule 1 | ... | Rule N | * | (SDNV) | (VAR) | | (VAR) | * +---------+--------+ +--------+ */ typedef struct { Lyst defs; /**> Report defs (msg_ctrl_period_prod_t). */ } rpt_prod_t; /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ void rpt_clear_lyst(Lyst *list, ResourceLock *mutex, int destroy); rpt_items_t* rpt_create_lst(Lyst contents); rpt_defs_t* rpt_create_defs(Lyst defs); rpt_data_t* rpt_create_data(time_t time, Lyst reports, eid_t recipient); rpt_prod_t* rpt_create_prod(Lyst defs); def_gen_t* rpt_find_custom(Lyst reportLyst, ResourceLock *mutex, mid_t *mid); void rpt_print_data_entry(rpt_data_entry_t *entry); void rpt_release_lst(rpt_items_t *msg); void rpt_release_defs(rpt_defs_t *msg); void rpt_release_data_entry(rpt_data_entry_t *entry); void rpt_release_data(rpt_data_t *msg); void rpt_release_prod(rpt_prod_t *msg); #endif /* _REPORT_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/primitives/oid.c0000644000175000017500000013531412260400057017670 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file oid.c ** ** Description: This file contains the implementation of functions that ** operate on Object Identifiers (OIDs). This file also implements ** global values, including the OID nickname database. ** ** Notes: ** 1. In the current implementation, the nickname database is not ** persistent. ** 2. We do not support a "create" function for OIDs as, so far, any ** need to create OIDs can be met by calling the appropriate ** deserialize function. ** ** Assumptions: ** 1. We limit the size of an OID in the system to reduce the amount ** of pre-allocated memory in this embedded system. Non-embedded ** implementations may wish to dynamically allocate MIDs as they are ** received. ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/29/12 E. Birrane Initial Implementation ** 11/14/12 E. Birrane Code review comments and documentation update. *****************************************************************************/ #include "platform.h" #include "shared/utils/utils.h" #include "shared/primitives/oid.h" Lyst nn_db; ResourceLock nn_db_mutex; /****************************************************************************** * * \par Function Name: oid_add_param * * \par Adds a parameter to a parameterized OID. * * \retval 0 Failure * !0 Success * * \param[in,out] oid The OID getting a new param. * \param[in] value The value of the new parameter * \param[in] len The length, in bytes, of the new parameter. * * \par Notes: * 1. The new parameter is allocated into the OID and, upon exit, * the passed-in value may be released if necessary. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation, *****************************************************************************/ int oid_add_param(oid_t *oid, uint8_t *value, uint32_t len) { int result = 0; uint8_t *cursor = NULL; Sdnv len_sdnv; datacol_entry_t *entry = NULL; DTNMP_DEBUG_ENTRY("oid_add_param","(%#llx, %#llx, %ld)", oid, value, len); /* Step 0: Sanity Check.*/ if((oid == NULL) || (value == NULL) || (len == 0)) { DTNMP_DEBUG_ERR("oid_add_param","Bad Args", NULL); DTNMP_DEBUG_EXIT("oid_add_param","->0.",NULL); return 0; } /* Step 1: Make sure the OID is a parameterized one. */ if((oid->type != OID_TYPE_PARAM) && (oid->type != OID_TYPE_COMP_PARAM)) { DTNMP_DEBUG_ERR("oid_add_param","Can't add parameter to OID of type %d.", oid->type); DTNMP_DEBUG_EXIT("oid_add_param","->0.",NULL); return 0; } /* Step 2: Make sure this doesn't give us too many params. */ if((lyst_length(oid->params)+1) > MAX_OID_PARM) { DTNMP_DEBUG_ERR("oid_add_param","OID has %d params, no room for more.", lyst_length(oid->params)); DTNMP_DEBUG_EXIT("oid_add_param","->0.",NULL); return 0; } /* Step 3: Make sure we have room for the passed-in parameter. */ encodeSdnv(&len_sdnv, len); if((oid_calc_size(oid) + len) > MAX_OID_SIZE) { DTNMP_DEBUG_ERR("oid_add_param","Parm too long. OID %d MAX %d Len %d", oid_calc_size(oid), MAX_OID_SIZE, len); DTNMP_DEBUG_EXIT("oid_add_param","->0.",NULL); return 0; } /* Step 4: Allocate the entry. */ if((entry = (datacol_entry_t*)MTAKE(sizeof(datacol_entry_t))) == NULL) { DTNMP_DEBUG_ERR("oid_add_param","Can't alloc %d bytes.", sizeof(datacol_entry_t)); DTNMP_DEBUG_EXIT("oid_add_param","->0.",NULL); return 0; } entry->length = len; if((entry->value = (uint8_t*) MTAKE(entry->length)) == NULL) { DTNMP_DEBUG_ERR("oid_add_param","Can't alloc %d bytes.", entry->length); MRELEASE(entry); DTNMP_DEBUG_EXIT("oid_add_param","->0.",NULL); return 0; } cursor = entry->value; // memcpy(cursor, len_sdnv.text, len_sdnv.length); // cursor += len_sdnv.length; memcpy(cursor, value, len); cursor += len; lyst_insert_last(oid->params, entry); DTNMP_DEBUG_EXIT("oid_add_param","->%d.",result); return result; } /****************************************************************************** * * \par Function Name: oid_calc_size * * \par Purpose: Calculate size of the OID once serialized. THe serialized OID * does *not* include the OID type, but will include the following info * based on type: * - # Bytes in the OID (always) * - # Parms (for any parameterized OID) * - SDNV per parm (for any parameterized OID) * - Nickname (for any compressed OID). * Therefore, the largest possible OID has the following form: * * <..opt..> <..........required........> <..........optional..........> * +--------+-------+-------+ +------+--------+-------+ +-------+ * |Nickname|# Bytes| Byte 1| ... |Byte N| # Parms| Parm 1| ... | Parm N| * | (SDNV) | (SDNV)| (Byte)| |(Byte)| (SDNV) | (SDNV)| |(SDNV) | * +--------+-------+-------+ +------+--------+-------+ +-------+ * * \retval 0 - Error * >0 The serialized size of the OID. * * \param[in] oid The OID whose serialized size is to be calculated. * \param[in] expand_nn Whether to expand the nickname (!0) or not (0). * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/27/12 E. Birrane Initial implementation, *****************************************************************************/ uint32_t oid_calc_size(oid_t *oid) { uint32_t size = 0; Sdnv tmp; datacol_entry_t *entry = NULL; DTNMP_DEBUG_ENTRY("oid_calc_size","(%#llx)",(unsigned long)oid); /* Step 0: Sanity Check. */ if(oid == NULL) { DTNMP_DEBUG_ERR("oid_calc_size","Bad Args.",NULL); DTNMP_DEBUG_EXIT("oid_calc_size","->0",NULL); return 0; } /* Step 1: How big is the nickname portion of the OID? */ if((oid->type == OID_TYPE_COMP_FULL) || (oid->type == OID_TYPE_COMP_PARAM)) { encodeSdnv(&tmp, oid->nn_id); size += tmp.length; } /* Step 2: Add the # bytes SDNV and the OID data size. */ size += oid->value_size; DTNMP_DEBUG_INFO("oid_calc_size","val is %d\n", oid->value_size); /* * Step 3: If we have parameters, add them too. This is simple because we * keep the serialized parameters around, including the SDNV at * the beginning precisely to make subsequent serialization (and * sizing) calculations easier. */ if(lyst_length(oid->params) > 0) { LystElt elt; /* Step 3a: Make room for number of parameters. */ encodeSdnv(&tmp, lyst_length(oid->params)); size += tmp.length; /* Step 3b: Add room for each parameter, which is a # bytes, followed * by the bytes. */ for(elt = lyst_first(oid->params); elt; elt = lyst_next(elt)) { entry = (datacol_entry_t *) lyst_data(elt); if(entry != NULL) { encodeSdnv(&tmp, entry->length); /*/todo update spec: parms is # bytes, followed by bytes. */ size += tmp.length + entry->length; } } } DTNMP_DEBUG_EXIT("oid_calc_size","->%d",size); return size; } /****************************************************************************** * * \par Function Name: oid_clear * * \par Purpose: Resets the values associated with an OID structure. * * \retval void * * \param[in,out] oid The OID being cleared. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/27/12 E. Birrane Initial implementation, *****************************************************************************/ void oid_clear(oid_t *oid) { DTNMP_DEBUG_ENTRY("oid_clear","(%#llx)", (unsigned long) oid); /* Step 0: Sanity Check. */ if(oid == NULL) { DTNMP_DEBUG_ERR("oid_clear","Clearing NULL OID.", NULL); DTNMP_DEBUG_EXIT("oid_clear","<->",NULL); return; } /* Step 1: Free parameters list. */ utils_datacol_destroy(&(oid->params)); /* Step 2: Bzero rest of the OID. */ memset(oid, 0, sizeof(oid_t)); DTNMP_DEBUG_EXIT("oid_clear","<->", NULL); } /****************************************************************************** * * \par Function Name: oid_compare * * \par Purpose: Determines equivalence of two OIDs. * * \retval !0 : Not equal (including error) * 0 : oid1 == oid2 * * \param[in] oid1 First OID being compared. * \param[in] oid2 Second OID being compared. * \param[in] use_parms Whether to compare parms as well. * * \par Notes: * 1. This function should only check for equivalence (== 0), not order * since we do not differentiate between oid1 < oid2 and error. * 2. Can compare a non-NULL OID and a NULL OID. They will not be * equivalent. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/27/12 E. Birrane Initial implementation, *****************************************************************************/ int oid_compare(oid_t *oid1, oid_t *oid2, uint8_t use_parms) { int result = 0; DTNMP_DEBUG_ENTRY("oid_compare","(%#llx, %#llx)", (unsigned long) oid1, (unsigned long) oid2); /* Step 0: Sanity check and shallow comparison in one. */ if(((oid1 == NULL) || (oid2 == NULL)) || ((oid1->value_size != oid2->value_size)) || ((oid1->type != oid2->type))) { DTNMP_DEBUG_EXIT("oid_compare","->-1.", NULL); return -1; } if(use_parms != 0) { if(lyst_length(oid1->params) != lyst_length(oid2->params)) { DTNMP_DEBUG_EXIT("oid_compare","->-1.", NULL); return -1; } } /* Step 1: Compare the value version of the oid */ result = memcmp(oid1->value, oid2->value, oid1->value_size); /* Step 2: If OIDs match so far, and if there are parameters, then we * need to check the parameters... */ if(use_parms != 0) { if((result == 0) && (lyst_length(oid1->params) > 0)) { result = utils_datacol_compare(oid1->params, oid2->params); } } DTNMP_DEBUG_EXIT("oid_compare","->%d.", result); return result; } /****************************************************************************** * * \par Function Name: oid_copy * * \par Purpose: Duplicates an OID. * * \retval NULL: The copy failed * !NULL: The deep-copied OID. * * \param[in] src_oid The OID being copied. * * \par Notes: * 1. The desintation OID is allocated and must be released when done. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/27/12 E. Birrane Initial implementation, *****************************************************************************/ oid_t *oid_copy(oid_t *src_oid) { oid_t *result = NULL; DTNMP_DEBUG_ENTRY("oid_copy","(%#llx)", (unsigned long) src_oid); /* Step 0: Sanity Check */ if(src_oid == NULL) { DTNMP_DEBUG_ERR("oid_copy","Cannot copy from NULL source OID.", NULL); DTNMP_DEBUG_EXIT("oid_copy","->NULL",NULL); return NULL; } /* Step 1: Allocate the new OID. */ if((result = (oid_t*) MTAKE(sizeof(oid_t))) == NULL) { DTNMP_DEBUG_ERR("oid_copy","Can't allocate %d bytes.", sizeof(oid_t)); DTNMP_DEBUG_EXIT("oid_copy","->NULL",NULL); return NULL; } /* Step 2: Deep copy parameters. */ result->params = utils_datacol_copy(src_oid->params); /* Step 3: Shallow copies the rest. */ result->type = src_oid->type; result->nn_id = src_oid->nn_id; result->value_size = src_oid->value_size; memcpy(result->value, src_oid->value, result->value_size); DTNMP_DEBUG_EXIT("oid_copy","->%d", result); return result; } /****************************************************************************** * * \par Function Name: oid_deserialize_comp * * \par Purpose: Extracts a compressed OID from a buffer. * * \retval NULL - Failure. * !NULL - The extracted OID. * * \param[in] buffer The effective start of the buffer. * \param[in] size The size of the buffer, in bytes. Don't go past this. * \param[out] bytes_used The number of consumed buffer bytes. * * \par Notes: * 1. The returned OID is dynamically allocated and must be freed when * no longer needed. * 2. The caller must increment the buffer pointed by the number of bytes * used before trying to deserialize the next thing in the buffer. * 3. We don't validate the oid here because if the oid is bad, we may * need to plow through anyway to get to the next object in the buffer, * so bailing early helps no-one. However, it behooves the caller to * check that sanity of the OID with a call to oid_sanity_check. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/27/12 E. Birrane Initial implementation, *****************************************************************************/ oid_t *oid_deserialize_comp(unsigned char *buffer, uint32_t size, uint32_t *bytes_used) { uvast nn_id = 0; uint32_t bytes = 0; oid_t *new_oid = NULL; unsigned char *cursor = NULL; DTNMP_DEBUG_ENTRY("oid_deserialize_comp","(%#llx,%d,%#llx)", (unsigned long) buffer, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((buffer == NULL) || (bytes_used == NULL) || (size == 0)) { DTNMP_DEBUG_ERR("oid_deserialize_comp", "Bad args.", NULL); DTNMP_DEBUG_EXIT("oid_deserialize_comp", "->NULL", NULL); return NULL; } else { *bytes_used = 0; cursor = buffer; } /* Step 1: Grab the nickname, which is in an SDNV. */ if((bytes = utils_grab_sdnv(cursor, size, &nn_id)) <= 0) { DTNMP_DEBUG_ERR("oid_deserialize_comp", "Can't grab nickname.", NULL); *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_comp", "->0", NULL); return 0; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } /* Step 2: grab the remaining OID, which looks just like a full OID. */ if((new_oid = oid_deserialize_full(cursor, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("oid_deserialize_comp", "Can't grab remaining OID.", NULL); *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_comp", "->NULL", NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } /* Step 3: Store extra information in the new OID. */ new_oid->nn_id = nn_id; new_oid->type = OID_TYPE_COMP_FULL; DTNMP_DEBUG_EXIT("oid_deserialize_comp","-> %x.", (unsigned long)new_oid); return new_oid; } /****************************************************************************** * * \par Function Name: oid_deserialize_comp_param * * \par Purpose: Extracts a compressed, parameterized OID from a buffer. * * \retval NULL - Failure. * !NULL - The extracted OID. * * \param[in] buffer The effective start of the buffer. * \param[in] size The size of the buffer, in bytes. Don't go past this. * \param[out] bytes_used The number of consumed buffer bytes. * * \par Notes: * 1. The returned OID is dynamically allocated and must be freed when * no longer needed. * 2. The caller must increment the buffer pointed by the number of bytes * used before trying to deserialize the next thing in the buffer. * 3. We don't validate the oid here because if the oid is bad, we may * need to plow through anyway to get to the next object in the buffer, * so bailing early helps no-one. However, it behooves the caller to * check that sanity of the OID with a call to oid_sanity_check. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/27/12 E. Birrane Initial implementation, *****************************************************************************/ oid_t *oid_deserialize_comp_param(unsigned char *buffer, uint32_t size, uint32_t *bytes_used) { uvast nn_id = 0; uint32_t bytes = 0; oid_t *new_oid = NULL; unsigned char *cursor = NULL; DTNMP_DEBUG_ENTRY("oid_deserialize_comp_param","(%#llx,%d,%#llx)", (unsigned long) buffer, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((buffer == NULL) || (bytes_used == NULL) || (size == 0)) { DTNMP_DEBUG_ERR("oid_deserialize_comp_param", "Bad args.", NULL); DTNMP_DEBUG_EXIT("oid_deserialize_comp_param", "->NULL", NULL); return NULL; } else { *bytes_used = 0; cursor = buffer; } /* Step 1: Grab the nickname, which is in an SDNV. */ if((bytes = utils_grab_sdnv(cursor, size, &nn_id)) <= 0) { DTNMP_DEBUG_ERR("oid_deserialize_comp_param", "Can't grab nickname.", NULL); *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_comp_param", "->0", NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } /* Step 2: grab the parameterized, remaining OID. */ if((new_oid = oid_deserialize_param(cursor, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("oid_deserialize_comp_param", "Can't grab remaining OID.", NULL); *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_comp_param", "->NULL", NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } /* Step 3: Store extra information in the new OID. */ new_oid->nn_id = nn_id; new_oid->type = OID_TYPE_COMP_PARAM; DTNMP_DEBUG_EXIT("oid_deserialize_comp_param","-> %x.", (unsigned long)new_oid); return new_oid; } /****************************************************************************** * * \par Function Name: oid_deserialize_full * * \par Purpose: Extracts a regular OID from a buffer. * * \todo We currently assume that the length field is a single byte (0-127). * We need to code this to follow BER rules for large definite data * form. Like SDNV but not quite: if high-bit of first byte set, bits * 7-1 give # octets that comprise length. Then, concatenate, big-endian, * those octets to build length. Ex: length 435 = 0x8201B3 * * \retval NULL - Failure. * !NULL - The extracted OID. * * \param[in] buffer The effective start of the buffer. * \param[in] size The size of the buffer, in bytes. Don't go past this. * \param[out] bytes_used The number of consumed buffer bytes. * * \par Notes: * 1. The returned OID is dynamically allocated and must be freed when * no longer needed. * 2. The caller must increment the buffer pointed by the number of bytes * used before trying to deserialize the next thing in the buffer. * 3. We don't validate the oid here because if the oid is bad, we may * need to plow through anyway to get to the next object in the buffer, * so bailing early helps no-one. However, it behooves the caller to * check that sanity of the OID with a call to oid_sanity_check. * 4. We DO bail if the OID is larger than we can accommodate, though. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/27/12 E. Birrane Initial implementation, *****************************************************************************/ oid_t *oid_deserialize_full(unsigned char *buffer, uint32_t size, uint32_t *bytes_used) { uint32_t oid_size = 0; oid_t *new_oid = NULL; uint8_t val = 0; unsigned char *cursor = NULL; DTNMP_DEBUG_ENTRY("oid_deserialize_full","(%#llx,%d,%#llx)", ( unsigned long) buffer, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks. */ if((buffer == NULL) || (bytes_used == NULL) || (size == 0)) { DTNMP_DEBUG_ERR("oid_deserialize_full", "Bad args.", NULL); DTNMP_DEBUG_EXIT("oid_deserialize_full", "->NULL", NULL); return NULL; } else { *bytes_used = 0; cursor = buffer; } /* * Step 1: Grab # SDNVs in the OID * \todo: Check if this should be a byte or an SDNV. */ if((*bytes_used = utils_grab_byte(cursor, size, &val)) != 1) { DTNMP_DEBUG_ERR("oid_deserialize_full", "Can't grab size byte.", NULL); DTNMP_DEBUG_EXIT("oid_deserialize_full", "-> NULL", NULL); return NULL; } else { cursor += *bytes_used; size -= *bytes_used; oid_size = val; } /* * Step 2: Make sure OID fits within our size. We add 1 to oid_size to * account for the # bytes parameter. * \todo Change the 1 here to something else if me move to SDNV for #bytes. */ if((oid_size + 1) >= MAX_OID_SIZE) { DTNMP_DEBUG_ERR("oid_deserialize_full","Size %d exceeds supported size %d", oid_size + 1, MAX_OID_SIZE); *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_full","-> NULL", NULL); return NULL; } /* Step 3: Make sure we have oid_size bytes left in the buffer. */ if(oid_size > size) { DTNMP_DEBUG_ERR("oid_deserialize_full","Can't read %d bytes from %d sized buf.", oid_size, size); *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_full","-> NULL", NULL); return NULL; } /* Step 4: Allocate the target OID object. */ if((new_oid = (oid_t*)MTAKE(sizeof(oid_t))) == NULL) { DTNMP_DEBUG_ERR("oid_deserialize_full","Cannot allocate new OID.", NULL); *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_full","-> NULL", NULL); return NULL; } /* Step 5: Copy in the data contents of the OID. We don't interpret the * values here, just put them in. */ new_oid->value[0] = oid_size; memcpy(&(new_oid->value[1]), cursor, oid_size); new_oid->value_size = oid_size + 1; *bytes_used += oid_size; if((new_oid->params = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("oid_deserialize_full","Cannot allocate param lyst.", NULL); MRELEASE(new_oid); *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_full","-> NULL", NULL); return NULL; } new_oid->type = OID_TYPE_FULL; DTNMP_DEBUG_EXIT("oid_deserialize_full","-> new_oid: %#llx bytes_used %d", (unsigned long)new_oid, *bytes_used); return new_oid; } /****************************************************************************** * * \par Function Name: oid_deserialize_param * * \par Purpose: Extracts a parameterized OID from a buffer. * * \retval NULL - Failure. * !NULL - The extracted OID. * * \param[in] buffer The effective start of the buffer. * \param[in] size The size of the buffer, in bytes. Don't go past this. * \param[out] bytes_used The number of consumed buffer bytes. * * \par Notes: * 1. The returned OID is dynamically allocated and must be freed when * no longer needed. * 2. The caller must increment the buffer pointed by the number of bytes * used before trying to deserialize the next thing in the buffer. * 3. We don't validate the oid here because if the oid is bad, we may * need to plow through anyway to get to the next object in the buffer, * so bailing early helps no-one. However, it behooves the caller to * check that sanity of the OID with a call to oid_sanity_check. * 4. We DO bail if the OID is larger than we can accommodate, though. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/27/12 E. Birrane Initial implementation, *****************************************************************************/ oid_t *oid_deserialize_param(unsigned char *buffer, uint32_t size, uint32_t *bytes_used) { oid_t *new_oid; uint32_t bytes = 0; uvast value = 0; uint32_t idx = 0; unsigned char *cursor = NULL; DTNMP_DEBUG_ENTRY("oid_deserialize_param","(%#llx,%d,%#llx)", (unsigned long) buffer, size, (unsigned long) bytes_used); /* Step 0: Sanity Checks... */ if((buffer == NULL) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("oid_deserialize_param","NULL input values!",NULL); DTNMP_DEBUG_EXIT("oid_deserialize_param","->NULL",NULL); return NULL; } else { *bytes_used = 0; cursor = buffer; } /* Step 1: Grab the regular OID and store it. */ new_oid = oid_deserialize_full(cursor, size, &bytes); if((bytes == 0) || (new_oid == NULL)) { DTNMP_DEBUG_ERR("oid_deserialize_param","Could not grab OID.", NULL); oid_release(new_oid); /* release just in case bytes was 0. */ *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_param","-> NULL", NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } /* Step 2: Grab the data collection representing parameters. Only if there * are parameters to grab. */ if(size > 0) { if((new_oid->params = utils_datacol_deserialize(cursor, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("oid_deserialize_param","Could not grab params.", NULL); oid_release(new_oid); /* release just in case bytes was 0. */ *bytes_used = 0; DTNMP_DEBUG_EXIT("oid_deserialize_param","-> NULL", NULL); return NULL; } else { cursor += bytes; size -= bytes; *bytes_used += bytes; } } /* Step 3: Fill in any other parts of the OID. */ new_oid->type = OID_TYPE_PARAM; DTNMP_DEBUG_EXIT("oid_deserialize_param","-> %#llx.", (unsigned long) new_oid); return new_oid; } /****************************************************************************** * * \par Function Name: oid_pretty_print * * \par Purpose: Builds a string representation of the OID suitable for * diagnostic viewing. * * \retval NULL: Failure to construct a string representation of the OID. * !NULL: The string representation of the OID string. * * \param[in] oid The OID whose string representation is being created. * * \par Notes: * 1. This is a slow, wasteful function and should not be called in * embedded systems. For something to dump in a log, try the function * oid_to_string instead. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, *****************************************************************************/ char *oid_pretty_print(oid_t *oid) { int size = 0; char *str = NULL; char *result = NULL; char *cursor = NULL; LystElt elt; datacol_entry_t *entry = NULL; DTNMP_DEBUG_ENTRY("oid_pretty_print","(%#llx)", (unsigned long) oid); /* Step 0: Sanity Check. */ if(oid == NULL) { DTNMP_DEBUG_ERR("oid_pretty_print","NULL OID.",NULL); DTNMP_DEBUG_EXIT("oid_pretty_print","->NULL.",NULL); return NULL; } /* Step 1: Guestimate size. This is, at best, a dark art and prone to * exaggeration. Numerics are assumed to take 5 bytes, unless I * think they will take 3 instead (indices vs. values). Other * values are based on constant strings in the function. One must * update this calculation if one changes string constants, else * one will be sorry. */ size = 33 + /* Header */ 11 + /* OID type as text */ (lyst_length(oid->params) * 22) + /* Each parameter index */ (MAX_OID_PARM * (20 * MAX_OID_SIZE)) + /* Parameters */ 12 + /* nn_id */ 18 + /* value_size */ 7 + (oid->value_size * 4) + /* OID values */ 22; /* Footer. */ /* Step 2: Allocate the string. */ if((result = (char*)MTAKE(size)) == NULL) { DTNMP_DEBUG_ERR("oid_pretty_print", "Can't alloc %d bytes.", size); DTNMP_DEBUG_EXIT("oid_pretty_print","->NULL",NULL); return NULL; } /* Step 3: Populate the allocated string. Keep an eye on the size. */ cursor = result; cursor += sprintf(cursor,"OID:\n---------------------\nType: "); switch(oid->type) { case 0: cursor += sprintf(cursor,"FULL\n"); break; case 1: cursor += sprintf(cursor,"PARAM\n"); break; case 2: cursor += sprintf(cursor,"COMP_FULL\n"); break; case 3: cursor += sprintf(cursor,"COMP_PARAM\n"); break; default: cursor += sprintf(cursor,"UNKNOWN\n"); break; } cursor += sprintf(cursor,"num_parm: %ld\n", lyst_length(oid->params)); int i = 0; for(elt = lyst_first(oid->params); elt; elt = lyst_next(elt)) { entry = (datacol_entry_t*)lyst_data(elt); str = utils_hex_to_string(entry->value, entry->length); cursor += sprintf(cursor, "Parm %d:%s\n",i,str); MRELEASE(str); i++; } cursor += sprintf(cursor, "nn_id: %d\n", (uint32_t)oid->nn_id); cursor += printf(cursor, "value_size: %d\n", oid->value_size); str = oid_to_string(oid); cursor += sprintf(cursor, "value: %s\n---------------------\n\n", str); MRELEASE(str); /* Step 4: Sanity check. */ if((cursor - result) > size) { DTNMP_DEBUG_ERR("oid_pretty_print", "OVERWROTE! Alloc %d, wrote %llu.", size, (cursor-result)); MRELEASE(result); DTNMP_DEBUG_EXIT("oid_pretty_print","->NULL",NULL); return NULL; } DTNMP_DEBUG_INFO("oid_pretty_print","Wrote %llu into %d string.", (cursor -result), size); DTNMP_DEBUG_EXIT("oid_pretty_print","->%#llx",result); return result; } /****************************************************************************** * * \par Function Name: oid_release * * \par Purpose: Frees resources associated with an OID. * * \retval void * * \param[in,out] oid The OID being freed. * * \par Notes: * 1. Very little to do here as an OID is statically loaded structure. * Function remains for if/when we refactor OIDs to be more dynamic. * 2. The OID pointer is garbage after this call and must not be * referenced again. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ void oid_release(oid_t *oid) { DTNMP_DEBUG_ENTRY("oid_release", "(%#llx)", (unsigned long) oid); if(oid != NULL) { oid_clear(oid); MRELEASE(oid); oid = NULL; } DTNMP_DEBUG_EXIT("oid_release", "-> NULL", NULL); } /****************************************************************************** * * \par Function Name: oid_sanity_check * * \par Purpose: Checks an oid structure for proper values. * * \retval <=0 - Failure. The OID is not sane. * >0 - Success. The OID is sane. * * \param[in] oid The OID whose sanity is in question. * * \par Notes: * 1. We don't bail on the first failure so as to better populate the * error log in instances where we have an OID with multiple problems. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ int oid_sanity_check(oid_t *oid) { int result = 1; DTNMP_DEBUG_ENTRY("oid_sanity_check","(%#llx)", (unsigned long) oid); /* NULL Checks. Perform all so that we get lots of logging in case * there are multiple problems with the OID. */ if(oid == NULL) { DTNMP_DEBUG_ERR("oid_sanity_check","NULL oid.", NULL); result = 0; } if(oid->type > 3) { DTNMP_DEBUG_ERR("oid_sanity_check","Bad type: %d.", oid->type); result = 0; } if(lyst_length(oid->params) > MAX_OID_PARM) { DTNMP_DEBUG_ERR("oid_sanity_check","Too many params: %d.", lyst_length(oid->params)); result = 0; } uint32_t size = oid_calc_size(oid); if(size > MAX_OID_SIZE) { DTNMP_DEBUG_ERR("oid_sanity_check","Parm size %d bigger than max %d", size, MAX_OID_SIZE); result = 0; } if(oid->value_size > MAX_OID_SIZE) { DTNMP_DEBUG_ERR("oid_sanity_check","Val size %d bigger than max %d", oid->value_size, MAX_OID_SIZE); result = 0; } DTNMP_DEBUG_EXIT("oid_sanity_check","->%d", result); return result; } /****************************************************************************** * * \par Function Name: oid_serialize * * \par Purpose: Generate full, serialized version of the OID. * * \todo Add a mechanism to determine whether we should expand a nickname or * not when serializing the OID. * * \todo Instead of counting exact size, it will be faster to simply allocate * the MAX_OID_SIZE and populate up to that point. Not sure if we are * going to be space or time constrained just yet. While the nn_id lookup * stays expensive we may not want to call it 2x as part of serialization * (once to calculate size and again to grab values). * * * \retval NULL - Failure serializing * !NULL - Serialized stream. * * \param[in] oid The OID to be serialized. * \param[out] size The size of the resulting serialized OID. * * \par Notes: * 1. The result is allocated on the memory pool and must be released when * no longer needed. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ uint8_t *oid_serialize(oid_t *oid, uint32_t *size) { uint8_t *result = NULL; uint8_t *cursor = NULL; uint8_t *parms = NULL; uint32_t parm_size = 0; uint32_t idx = 0; Sdnv nn_sdnv; DTNMP_DEBUG_ENTRY("oid_serialize","(%#llx,%#llx)", (unsigned long)oid, (unsigned long)size); /* Step 0: Sanity Check */ if((oid == NULL) || (size == NULL)) { DTNMP_DEBUG_ERR("oid_serialize","Bad args.",NULL); DTNMP_DEBUG_EXIT("oid_serialize","->NULL",NULL); return NULL; } /* Step 1: Count up the total size of the OID. */ if((*size = oid_calc_size(oid)) == 0) { DTNMP_DEBUG_ERR("oid_serialize","Bad size %d.",*size); *size = 0; DTNMP_DEBUG_EXIT("oid_serialize","->NULL",NULL); return NULL; } /* Step 2: Sanity check the size. */ if(*size > MAX_OID_SIZE) { DTNMP_DEBUG_ERR("oid_serialize","Size %d bigger than max of %d.", *size, MAX_OID_SIZE); *size = 0; DTNMP_DEBUG_EXIT("oid_serialize","->NULL",NULL); return NULL; } /* Step 3: Allocate the serialized buffer.*/ if((result = (uint8_t *) MTAKE(*size)) == NULL) { DTNMP_DEBUG_ERR("oid_serialize","Couldn't allocate %d bytes.", *size); *size = 0; DTNMP_DEBUG_EXIT("oid_serialize","->NULL",NULL); return NULL; } else { cursor = result; } /* Step 4: Copy in the nickname portion. */ if((oid->type == OID_TYPE_COMP_FULL) || (oid->type == OID_TYPE_COMP_PARAM)) { encodeSdnv(&nn_sdnv, oid->nn_id); memcpy(cursor, nn_sdnv.text, nn_sdnv.length); cursor += nn_sdnv.length; } /* Step 5: Copy in the value portion. */ memcpy(cursor,oid->value, oid->value_size); cursor += oid->value_size; /* Step 6: Copy in the parameters portion. */ if((oid->type == OID_TYPE_PARAM) || (oid->type == OID_TYPE_COMP_PARAM)) { parms = utils_datacol_serialize(oid->params, &parm_size); if((parms == NULL) || (parm_size == 0)) { DTNMP_DEBUG_ERR("oid_serialize","Can't serialize parameters.",NULL); *size = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("oid_serialize","->NULL",NULL); return NULL; } memcpy(cursor, parms, parm_size); cursor += parm_size; MRELEASE(parms); } /* Step 7: Final sanity check */ if((cursor-result) > *size) { DTNMP_DEBUG_ERR("oid_serialize","Serialized %d bytes but counted %d!", (cursor-result), *size); *size = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("oid_serialize","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("oid_serialize","->%#llx",(unsigned long)result); return result; } /****************************************************************************** * * \par Function Name: oid_to_string * * \par Purpose: Create a compact string representation of the OID. * * \retval NULL - Failure building string version of the OID. * !NULL - The compact string representing the OID. * * \param[in] oid The OID whose string representation is being calculated. * * \par Notes: * 1. This function allocates memory from the memory pool. The returned * string MUST be released when no longer needed. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ char *oid_to_string(oid_t *oid) { char *result = NULL; uint32_t size = 0; DTNMP_DEBUG_ENTRY("oid_to_string","(%#llx)",(unsigned long) oid); /* Step 0: Sanity Check. */ if(oid == NULL) { DTNMP_DEBUG_ERR("oid_to_string","NULL OID",NULL); DTNMP_DEBUG_EXIT("oid_to_string","->NULL.",NULL); return NULL; } /* Step 1: Walk through and collect size. */ /* For now, we just show the raw MID. */ result = utils_hex_to_string(oid->value, oid->value_size); DTNMP_DEBUG_EXIT("oid_to_string","->%s.", result); return result; } /****************************************************************************** * * \par Function Name: oid_nn_add * * \par Purpose: Adds a nickname to the database. * * \retval 0 Failure. * !0 Success. * * \param[in] oid The OID whose string representation is being calculated. * * \par Notes: * 1. We will allocate our own entry on addition, the passed-in structure * may be deleted or changed after this call. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ int oid_nn_add(oid_nn_t *nn) { oid_nn_t *new_nn = NULL; DTNMP_DEBUG_ENTRY("oid_nn_add","(%#llx)",(unsigned long)nn); /* Step 0: Sanity check. */ if(nn == NULL) { DTNMP_DEBUG_ERR("oid_nn_add","Bad args.",NULL); DTNMP_DEBUG_EXIT("oid_nn_add","->0",NULL); return 0; } /* Need to lock early so our uniqueness check (step 1) doesn't change by * the time we go to insert in step 4. */ lockResource(&nn_db_mutex); /* Step 1: Make sure entry doesn't already exist. */ if(oid_nn_exists(nn->id)) { DTNMP_DEBUG_ERR("oid_nn_add","Id 0x%x already exists in db.", nn->id); unlockResource(&nn_db_mutex); DTNMP_DEBUG_EXIT("oid_nn_add","->0",NULL); return 0; } /* Step 2: Allocate new entry. */ if ((new_nn = (oid_nn_t*)MTAKE(sizeof(oid_nn_t))) == NULL) { DTNMP_DEBUG_ERR("oid_nn_add","Can't take %d bytes for new nn.", sizeof(oid_nn_t)); unlockResource(&nn_db_mutex); DTNMP_DEBUG_EXIT("oid_nn_add","->0",NULL); return 0; } /* Step 3: Populate new entry with passed-in data. */ memcpy(new_nn, nn, sizeof(oid_nn_t)); /* Step 4: Add new entry to the db. */ lyst_insert_first(nn_db, new_nn); unlockResource(&nn_db_mutex); DTNMP_DEBUG_EXIT("oid_nn_add","->1",NULL); return 1; } /****************************************************************************** * * \par Function Name: oid_nn_cleanup * * \par Purpose: Breaks down the nickname database. * * \retval void * * \par Notes: * 1. We assume there are no other people who will use the nn_db after * this! * 2. We also kill the mutex around the database. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ void oid_nn_cleanup() { LystElt elt; oid_nn_t *entry = NULL; DTNMP_DEBUG_ENTRY("oid_nn_cleanup","()",NULL); /* Step 0: Sanity Check. */ if(nn_db == NULL) { DTNMP_DEBUG_WARN("oid_nn_cleanup","NN database already cleaned.",NULL); return; } /* Step 1: Wait for folks to be done with the database. */ lockResource(&nn_db_mutex); /* Step 2: Release each entry. */ for (elt = lyst_first(nn_db); elt; elt = lyst_next(elt)) { entry = (oid_nn_t*) lyst_data(elt); if (entry != NULL) { MRELEASE(entry); } else { DTNMP_DEBUG_WARN("oid_nn_cleanup","Found NULL entry in nickname db.", NULL); } } lyst_destroy(nn_db); /* Step 3: Clean up locking mechanisms too. */ unlockResource(&nn_db_mutex); killResourceLock(&nn_db_mutex); } /****************************************************************************** * * \par Function Name: oid_nn_delete * * \par Purpose: Removes a nickname from the database. * * \retval 0 - Entry not found (or other error) * !0 - Success. * * \param[in] nn_id The ID of the entry to remove. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ int oid_nn_delete(uvast nn_id) { oid_nn_t *cur_nn = NULL; LystElt tmp_elt; int result = 0; DTNMP_DEBUG_ENTRY("oid_nn_delete","(%#llx)",nn_id); /* Step 1: Need to lock to preserve validity of the lookup result. . */ lockResource(&nn_db_mutex); /* Step 2: If you find it, delete it. */ if((tmp_elt = oid_nn_exists(nn_id)) != NULL) { cur_nn = (oid_nn_t*) lyst_data(tmp_elt); lyst_delete(tmp_elt); MRELEASE(cur_nn); result = 1; } unlockResource(&nn_db_mutex); DTNMP_DEBUG_EXIT("oid_nn_delete","->%d",result); return result; } /****************************************************************************** * * \par Function Name: oid_nn_exists * * \par Purpose: Determines if an ID is in the nickname db. * * \retval NULL - Not found. * !NULL - ELT pointing to the found element. * * \param[in] nn_id The ID of the nickname whose existence is in question. * * \todo There is probably a smarter way to do this with a lyst find function * and a search callback. * * \par Notes: * 1. LystElt is a pointer. Handle this handle with care. * 2. We break abstraction here and return a Lyst structure because this * lookup function is often called in the context of lyst maintenance, * but if we were to change the underlying nickname database storage * approach, this function would, clearly, need to change. Those who * do not like this approach are referred to the much less deprecable * function: oid_find. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ LystElt oid_nn_exists(uvast nn_id) { oid_nn_t *cur_nn = NULL; LystElt tmp_elt = NULL; LystElt result = NULL; DTNMP_DEBUG_ENTRY("oid_nn_exists","(%#llx)",nn_id); /* Step 0: Make sure no +/-'s while we search. */ lockResource(&nn_db_mutex); for(tmp_elt = lyst_first(nn_db); tmp_elt; tmp_elt = lyst_next(tmp_elt)) { cur_nn = (oid_nn_t*) lyst_data(tmp_elt); if(cur_nn != NULL) { if(cur_nn->id == nn_id) { result = tmp_elt; break; } } else { DTNMP_DEBUG_WARN("oid_nn_exists","Encountered NULL nn?",NULL); } } unlockResource(&nn_db_mutex); DTNMP_DEBUG_EXIT("oid_nn_delete","->%x",result); return result; } /****************************************************************************** * * \par Function Name: oid_nn_find * * \par Purpose: Convenience function to grab a nickname entry from its ID. * * \retval NULL - Item not found. * !NULL - Handle to the found item. * * \param[in] nn_id The ID of the nickname to find. * * \todo There is probably a smarter way to do this with a lyst find function * and a search callback. * * \par Notes: * 1. The returned pointer should NOT be released. It points directly into * the nickname list. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ oid_nn_t* oid_nn_find(uvast nn_id) { LystElt tmpElt = NULL; oid_nn_t *result = NULL; DTNMP_DEBUG_ENTRY("oid_nn_find","(%#llx)",nn_id); /* Step 0: Call exists function (exists should block mutex, so we don't. */ if((tmpElt = oid_nn_exists(nn_id)) != NULL) { result = (oid_nn_t*) lyst_data(tmpElt); } DTNMP_DEBUG_EXIT("oid_nn_find","->%#llx",result); return result; } /****************************************************************************** * * \par Function Name: oid_nn_init * * \par Purpose: Initialize the nickname database for OIDs. * * \retval <0 - Failure. * 0 - Success. * * \param[in] nn_id The ID of the nickname to find. * * \todo Add functions here to read the nickname database from persistent * storage, such as an SDR. * * \par Notes: * 1. nn_db must only hold items that have been dynamically allocated * from the memory pool. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ int oid_nn_init() { DTNMP_DEBUG_ENTRY("oid_init_nn_db","()",NULL); /* Step 0: Sanity Check. */ if(nn_db != NULL) { DTNMP_DEBUG_WARN("oid_nn_init","Trying to init existing NN db.",NULL); return 0; } if((nn_db = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("oid_nn_init","Can't allocate NN DB!", NULL); DTNMP_DEBUG_EXIT("oid_nn_init","->-1.",NULL); return -1; } if(initResourceLock(&nn_db_mutex)) { DTNMP_DEBUG_ERR("oid_init_nn_db","Unable to initialize mutex, errno = %s", strerror(errno)); DTNMP_DEBUG_EXIT("oid_init_nn_db","->-1.",NULL); return -1; } DTNMP_DEBUG_EXIT("oid_init_nn_db","->0.",NULL); return 0; } ion-3.2.0~dfsg1.orig/nm/shared/primitives/mid.h0000644000175000017500000001472412260400057017674 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: mid.h ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for the identification and ** processing of DTNMP Managed Identifiers (MIDs). ** ** Notes: ** ** Assumptions: ** 1. We limit the size of an OID in the system to reduce the amount ** of pre-allocated memory in this embedded system. Non-embedded ** implementations may wish to dynamically allocate MIDs as they are ** received. ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/21/11 E. Birrane Code comments and functional updates. ** 10/22/12 E. Birrane Update to latest version of DTNMP. Cleanup. ** 06/25/13 E. Birrane New spec. rev. Remove priority from MIDs *****************************************************************************/ #ifndef MID_H_ #define MID_H_ #include "stdint.h" #include "ion.h" #include "shared/utils/debug.h" #include "shared/primitives/oid.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ /** * Defines the bits comprising the MID flags as follows. * * Bits 0-1: The type of component identified by the MID * Bits 2-3: The category of component identified by the MID * Bit 4: The issuer flag associated with the MID * Bit 5: The tag flag associated with the MID * Bits 6-7: The OID type encapsulated within the MID * */ #define MID_FLAG_TYPE (0x03) #define MID_FLAG_CAT (0x0C) #define MID_FLAG_ISS (0x10) #define MID_FLAG_TAG (0x20) #define MID_FLAG_OID (0xC0) /** * MID TYPE DEFINITIONS * * DATA: Values sampled directly by the agent, and combinations thereof. * CONTROL: Functions that may be called by the agent. * LITERAL: Well-named Constants. * OPERATOR: Coded mathematical expression (special case of control). */ #define MID_TYPE_DATA 0 #define MID_TYPE_CONTROL 1 #define MID_TYPE_LITERAL 2 #define MID_TYPE_OPERATOR 3 /** * MID CATEGORY DEFINITIONS * * ATOMIC: Proper-named data from specification. * COMPUTED: Computed by mathematical expression of atomic/computed data values. * COLLECTION: List of items, atomic or computed. */ #define MID_CAT_ATOMIC 0 #define MID_CAT_COMPUTED 1 #define MID_CAT_COLLECTION 2 /** * Maximum size, in bytes, supported for MID fields. * WARNING: Changes to these values must be reflected in the associated MID * data type and associated functions. */ #define MAX_TAG (8) #define MAX_ISSUER (8) /* * +--------------------------------------------------------------------------+ * | MACROS + * +--------------------------------------------------------------------------+ */ #define MID_GET_FLAG_TYPE(flag) (flag & MID_FLAG_TYPE) #define MID_GET_FLAG_CAT(flag) ((flag & MID_FLAG_CAT) >> 2) #define MID_GET_FLAG_ISS(flag) ((flag & MID_FLAG_ISS) >> 4) #define MID_GET_FLAG_TAG(flag) ((flag & MID_FLAG_TAG) >> 5) #define MID_GET_FLAG_OID(flag) ((flag & MID_FLAG_OID) >> 6) /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ /** * Describes a Managed Identifier object. * * Notably with this structure is the fact that we keep a completely * serialized version of the MID in addition to bit-busting the values into * the other members of the structure. This makes re-serialization of the MID * for re-use a very fast endeavor. * * The mid_internal_serialize function may be used to re-serialize this * internal representation if something changes (such changing the OID type * to expand a nickname). */ typedef struct { /** Flags describing optional MID elements */ uint8_t flags; /** Type of the MID, one of MID_TYPE_[DATA|CONTROL|LITERAL|OPERATOR]. */ uint8_t type; /** Category of the MID, one of MID_CAT_[ATOMIC|COMPUTED|COLLECTION]. */ uint8_t category; /** Issuer, capped to largest atomic data type allowed by architecture */ uvast issuer; /** OID */ oid_t *oid; /** Tag, capped to largest atomic data type allowed by architecture */ uvast tag; /** The complete SDNV-encoded serialized MID. */ uint8_t* raw; /** Size of the serialized mid in bytes. */ uint32_t raw_size; } mid_t; /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ int mid_add_param(mid_t *mid, uint8_t *value, uint32_t len); void mid_clear(mid_t *mid); int mid_compare(mid_t *mid1, mid_t *mid2, uint8_t use_parms); mid_t* mid_construct(uint8_t type, uint8_t cat, uvast *issuer, uvast *tag, oid_t *oid); mid_t* mid_copy(mid_t *src_mid); mid_t* mid_deserialize(unsigned char *buffer, uint32_t buffer_size, uint32_t *bytes_used); int mid_internal_serialize(mid_t *mid); char* mid_pretty_print(mid_t *mid); void mid_release(mid_t *mid); int mid_sanity_check(mid_t *mid); uint8_t* mid_serialize(mid_t *mid, uint32_t *size); char* mid_to_string(mid_t *mid); Lyst midcol_copy(Lyst mids); void midcol_destroy(Lyst *mids); Lyst midcol_deserialize(unsigned char *buffer, uint32_t buffer_size, uint32_t *bytes_used); char* midcol_pretty_print(Lyst mc); char* midcol_to_string(Lyst mc); uint8_t* midcol_serialize(Lyst mids, uint32_t *size); #endif ion-3.2.0~dfsg1.orig/nm/shared/primitives/instr.c0000644000175000017500000000244012260400057020245 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file instr.c ** ** ** Description: DTNMP Instrumentation functions. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/04/13 E. Birrane Initial Implementation *****************************************************************************/ #include "instr.h" #include agent_instr_t gAgentInstr; void agent_instr_init() { agent_instr_clear(); } void agent_instr_clear() { memset(&gAgentInstr,0, sizeof(gAgentInstr)); } ion-3.2.0~dfsg1.orig/nm/shared/primitives/def.c0000644000175000017500000001344612260400057017654 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file def.c ** ** ** Description: Structures that capture protocol custom definitions. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/17/13 E. Birrane Redesign of messaging architecture. *****************************************************************************/ #include "platform.h" #include "shared/utils/utils.h" #include "def.h" /** * \brief Convenience function to build custom definition messages. * * \author Ed Birrane * * \note * - We shallow copy information into the message. So, don't release anything * provided as an argument to this function. * * \return NULL - Failure * !NULL - Created message. * * \param[in] id The ID of the new definition. * \param[in[ contents The new definition as an ordered set of MIDs. */ def_gen_t *def_create_gen(mid_t *id, Lyst contents) { def_gen_t *result = NULL; DTNMP_DEBUG_ENTRY("def_create_gen","(0x%x,0x%x)", (unsigned long) id, (unsigned long) contents); /* Step 0: Sanity Check. */ if((id == NULL) || (contents == NULL)) { DTNMP_DEBUG_ERR("def_create_gen","Bad Args.",NULL); DTNMP_DEBUG_EXIT("def_create_gen","->NULL",NULL); return NULL; } /* Step 1: Allocate the message. */ if((result = (def_gen_t*)MTAKE(sizeof(def_gen_t))) == NULL) { DTNMP_DEBUG_ERR("def_create_gen","Can't alloc %d bytes.", sizeof(def_gen_t)); DTNMP_DEBUG_EXIT("def_create_gen","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->id = id; result->contents = contents; DTNMP_DEBUG_EXIT("def_create_gen","->0x%x",result); return result; } /* Release functions.*/ /** * \brief Release any definition-category message. * * \author Ed Birrane * * \param[in,out] def The message being released. */ void def_release_gen(def_gen_t *def) { DTNMP_DEBUG_ENTRY("def_release_gen","(0x%x)", (unsigned long) def); if(def != NULL) { if(def->id != NULL) { mid_release(def->id); } if(def->contents != NULL) { midcol_destroy(&(def->contents)); } MRELEASE(def); } DTNMP_DEBUG_EXIT("def_release_gen","->.",NULL); } /** * \brief Find custom definition by MID. * * \author Ed Birrane * * \return NULL - No definition found. * !NULL - The found definition. * * \param[in] defs The lyst of definitions. * \param[in] mutex Resource mutex protecting the defs list (or NULL) * \param[in] id The ID of the report we are looking for. */ def_gen_t *def_find_by_id(Lyst defs, ResourceLock *mutex, mid_t *id) { LystElt elt; def_gen_t *cur_def = NULL; DTNMP_DEBUG_ENTRY("def_find_by_id","(0x%x, 0x%x", (unsigned long) defs, (unsigned long) id); /* Step 0: Sanity Check. */ if((defs == NULL) || (id == NULL)) { DTNMP_DEBUG_ERR("def_find_by_id","Bad Args.",NULL); DTNMP_DEBUG_EXIT("def_find_by_id","->NULL.", NULL); return NULL; } if(mutex != NULL) { lockResource(mutex); } for (elt = lyst_first(defs); elt; elt = lyst_next(elt)) { /* Grab the definition */ if((cur_def = (def_gen_t*) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("def_find_by_id","Can't grab def from lyst!", NULL); } else { if(mid_compare(id, cur_def->id,1) == 0) { DTNMP_DEBUG_EXIT("def_find_by_id","->0x%x.", cur_def); if(mutex != NULL) { unlockResource(mutex); } return cur_def; } } } if(mutex != NULL) { unlockResource(mutex); } DTNMP_DEBUG_EXIT("def_find_by_id","->NULL.", NULL); return NULL; } /** * \brief Clears list of definition messages. * * \author Ed Birrane * * \param[in,out] defs The lyst of definition messages to be cleared */ void def_lyst_clear(Lyst *list, ResourceLock *mutex, int destroy) { LystElt elt; def_gen_t *cur_def = NULL; DTNMP_DEBUG_ENTRY("def_lyst_clear","(0x%x, 0x%x, %d)", (unsigned long) list, (unsigned long) mutex, destroy); if((list == NULL) || (*list == NULL)) { DTNMP_DEBUG_ERR("def_lyst_clear","Bad Params.", NULL); return; } if(mutex != NULL) { lockResource(mutex); } /* Free any reports left in the reports list. */ for (elt = lyst_first(*list); elt; elt = lyst_next(elt)) { /* Grab the current report */ if((cur_def = (def_gen_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("clearDefsLyst","Can't get report from lyst!", NULL); } else { def_release_gen(cur_def); } } lyst_clear(*list); if(destroy != 0) { lyst_destroy(*list); *list = NULL; } if(mutex != NULL) { unlockResource(mutex); } DTNMP_DEBUG_EXIT("clearDefsLyst","->.",NULL); } void def_print_gen(def_gen_t *def) { char *id_str; char *mc_str; if(def == NULL) { fprintf(stderr,"NULL Definition.\n"); } id_str = mid_pretty_print(def->id); mc_str = midcol_pretty_print(def->contents); fprintf(stderr,"Definition:\n----------ID:\n%s\n\nMC:\n%s\n\n----------", id_str, mc_str); MRELEASE(id_str); MRELEASE(mc_str); } ion-3.2.0~dfsg1.orig/nm/shared/primitives/admin.c0000644000175000017500000001317412260400057020204 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file admin.c ** ** ** Description: Administrative primitives. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/17/13 E. Birrane Redesign of messaging architecture. ** 06/24/13 E. Birrane Migrated from uint32_t to time_t. *****************************************************************************/ #include "platform.h" #include "shared/utils/utils.h" #include "shared/primitives/mid.h" #include "admin.h" /* Create functions. */ /** * \brief Convenience function to build Register Agent message. * * \author Ed Birrane * * \note * - We shallow copy information into the message. So, don't release anything * provided as an argument to this function. * * \return NULL - Failure * !NULL - Created message. * * \param[in] eid The agent EID. */ adm_reg_agent_t *msg_create_reg_agent(eid_t eid) { adm_reg_agent_t *result = NULL; DTNMP_DEBUG_ENTRY("msg_create_reg_agent","(%s)", eid.name); /* Step 1: Allocate the message. */ if((result = (adm_reg_agent_t*) MTAKE(sizeof(adm_reg_agent_t))) == NULL) { DTNMP_DEBUG_ERR("msg_create_reg_agent","Can't alloc %d bytes.", sizeof(adm_reg_agent_t)); DTNMP_DEBUG_EXIT("msg_create_reg_agent","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->agent_id = eid; DTNMP_DEBUG_EXIT("msg_create_reg_agent","->0x%x",result); return result; } /** * \brief COnvenience function to build Report Policy message. * * \author Ed Birrane * * \note * - We shallow copy information into the message. So, don't release anything * provided as an argument to this function. * * \return NULL - Failure * !NULL - Created message. * * \param[in] eid The report policy mask. */ adm_rpt_policy_t *msg_create_rpt_policy(uint8_t mask) { adm_rpt_policy_t *result = NULL; DTNMP_DEBUG_ENTRY("msg_create_rpt_policy","(0x%x)", mask); /* Step 1: Allocate the message. */ if((result = (adm_rpt_policy_t*)MTAKE(sizeof(adm_reg_agent_t))) == NULL) { DTNMP_DEBUG_ERR("msg_create_rpt_policy","Can't alloc %d bytes.", sizeof(adm_reg_agent_t)); DTNMP_DEBUG_EXIT("msg_create_rpt_policy","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->mask = mask; DTNMP_DEBUG_EXIT("msg_create_rpt_policy","->0x%x",result); return result; } /** * \brief Convenience function to build a Status message. * * \author Ed Birrane * * \note * - We shallow copy information into the message. So, don't release anything * provided as an argument to this function. * * \return NULL - Failure * !NULL - Created message. * * \param[in] code The status, as a MID. * \param[in] time When the status occured. * \param[in] generators The MIDs causing the status. */ adm_stat_msg_t *msg_create_stat_msg(mid_t *code, time_t time, Lyst generators) { adm_stat_msg_t *result = NULL; DTNMP_DEBUG_ENTRY("msg_create_stat_msg","(code,0x%x,0x%x)", time, (unsigned long) generators); /* Step 0: Sanity Check. */ if((code == NULL) || (generators == NULL)) { DTNMP_DEBUG_ERR("msg_create_stat_msg","Bad Args.",NULL); DTNMP_DEBUG_EXIT("msg_create_stat_msg","->NULL",NULL); return NULL; } /* Step 1: Allocate the message. */ if((result = (adm_stat_msg_t*)MTAKE(sizeof(adm_reg_agent_t))) == NULL) { DTNMP_DEBUG_ERR("msg_create_stat_msg","Can't alloc %d bytes.", sizeof(adm_reg_agent_t)); DTNMP_DEBUG_EXIT("msg_create_stat_msg","->NULL",NULL); return NULL; } /* Step 2: Populate the message. */ result->code = code; result->time = time; result->generators = generators; DTNMP_DEBUG_EXIT("msg_create_stat_msg","->0x%x",result); return result; } /* Release functions.*/ /** * \brief Release Register Agent message. * * \author Ed Birrane * * \param[in,out] msg The message being released. */ void msg_release_reg_agent(adm_reg_agent_t *msg) { DTNMP_DEBUG_ENTRY("msg_release_reg_agent","(0x%x)", (unsigned long) msg); if(msg != NULL) { MRELEASE(msg); } DTNMP_DEBUG_EXIT("msg_release_reg_agent","->.",NULL); } /** * \brief Release Report Policy message. * * \author Ed Birrane * * \param[in,out] msg The message being released. */ void msg_release_rpt_policy(adm_rpt_policy_t *msg) { DTNMP_DEBUG_ENTRY("msg_release_rpt_policy","(0x%x)", (unsigned long) msg); if(msg != NULL) { MRELEASE(msg); } DTNMP_DEBUG_EXIT("msg_release_rpt_policy","->.",NULL); } /** * \brief Release Status message. * * \author Ed Birrane * * \param[in,out] msg The message being released. */ void msg_release_stat_msg(adm_stat_msg_t *msg) { DTNMP_DEBUG_ENTRY("msg_release_stat_msg","(0x%x)", (unsigned long) msg); if(msg != NULL) { mid_release(msg->code); midcol_destroy(&(msg->generators)); MRELEASE(msg); } DTNMP_DEBUG_EXIT("msg_release_stat_msg","->.",NULL); } ion-3.2.0~dfsg1.orig/nm/shared/utils/0000755000175000017500000000000012260400057015707 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/shared/utils/ion_if.c0000644000175000017500000003117212260400057017322 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: ion_if.c ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for DTNMP actors to connect to ** the local BPA. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 08/10/11 V.Ramachandran Initial Implementation ** 11/13/12 E. Birrane Technical review, comment updates. ** 06/25/13 E. Birrane Renamed message "bundle" message "group". *****************************************************************************/ #include "bp.h" #include "shared/utils/nm_types.h" #include "shared/utils/ion_if.h" #include "shared/utils/utils.h" #include "shared/msg/pdu.h" /****************************************************************************** * * \par Function Name: iif_deregister_node * * \par Deregisters the current application with the DTN network. * * \retval 0 - Could not Register * 1 - Registered. * * \param[in,out] iif The Interface being deregistered. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/10/11 V.Ramachandran Initial implementation, *****************************************************************************/ uint8_t iif_deregister_node(iif_t *iif) { DTNMP_DEBUG_ENTRY("iif_deregister_node","(%#llx)", (unsigned long)iif); /* Step 0: Sanity Check */ if(iif == NULL) { DTNMP_DEBUG_ERR("iif_deregister_node","Null IIF.", NULL); DTNMP_DEBUG_EXIT("iif_deregister_node","-> %d", 0); return 0; } bp_close(iif->sap); bp_detach(); memset(iif->local_eid.name,0, 1024); DTNMP_DEBUG_EXIT("iif_deregister_node","-> %d", 1); return 1; } /****************************************************************************** * * \par Function Name: iif_get_local_eid * * \par Returns the EID of the local node. * * \retval The EID associated with the IIF. * * \param[in] iif The Interface whose local EID is being queried. * * \par Notes: * 1. Assumes the IIF exists at this point. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/10/11 V.Ramachandran Initial implementation, *****************************************************************************/ eid_t iif_get_local_eid(iif_t *iif) { DTNMP_DEBUG_ENTRY("iif_get_local_eid","(%#llx)", iif); if(iif == NULL) { eid_t result; DTNMP_DEBUG_ERR("iif_get_local_eid","Bad args.",NULL); memset(&result,0,sizeof(eid_t)); DTNMP_DEBUG_EXIT("iif_get_local_eid","->0.",NULL); return result; } DTNMP_DEBUG_EXIT("iif_get_local_eid","->1.",NULL); return iif->local_eid; } /****************************************************************************** * * \par Function Name: iif_is_registered * * \par Returns 1 if the DTN connection is active, 0 otherwise. * * \retval 1 - IIF is registered * 0 - IIF is not registered. * * \param[in] iif The Interface whose registration status is being queried. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/10/11 V.Ramachandran Initial implementation, *****************************************************************************/ uint8_t iif_is_registered(iif_t *iif) { uint8_t result = 0; DTNMP_DEBUG_ENTRY("iif_is_registered","(%#llx)", iif); if(iif == NULL) { DTNMP_DEBUG_ERR("iif_is_registered","Bad args.",NULL); DTNMP_DEBUG_EXIT("iif_is_registered","->0.",NULL); return result; } result = (iif->local_eid.name[0] != 0) ? 1 : 0; DTNMP_DEBUG_EXIT("iif_is_registered","->%d.",NULL); return result; } /****************************************************************************** * * \par Function Name: iif_receive * * \par Blocking receive. Receives a message from the BPA. * * \retval NULL - Error * !NULL - The received serialized payload. * * \param[in] iif The registered interface. * \param[out] size The size of the msg bundle. * \param[out] meta The sender information from the convergence layer for all msgs. * \param[in] timeout The # seconds to wait on a receive before timing out * * \par Notes: * - The returned data must be freed via zco_destroy_reference() * * \todo * - Use ZCOs and handle large message sizes. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/10/11 V.Ramachandran Initial implementation, *****************************************************************************/ uint8_t *iif_receive(iif_t *iif, uint32_t *size, pdu_metadata_t *meta, int timeout) { BpDelivery dlv; ZcoReader reader; int dataLength; int content_len; Sdr sdr = bp_get_sdr(); uint8_t *buffer = NULL; uint8_t *cursor = NULL; pdu_msg_t *pdu = NULL; uint32_t bytes = 0; uint32_t buf_size = 0; int result; DTNMP_DEBUG_ENTRY("iif_receive", "(0x%x, %d)", (unsigned long) iif, timeout); DTNMP_DEBUG_INFO("iif_rceive", "Received bundle.", NULL); /* Step 1: Receive the bundle.*/ if((result = bp_receive(iif->sap, &dlv, timeout)) < 0) { DTNMP_DEBUG_ERR("iif_receive","bp_receive failed. Result: %d.", result); exit(0); } else { switch(dlv.result) { case BpEndpointStopped: /* The endpoint stopped? Panic.*/ DTNMP_DEBUG_ERR("iif_receive","Endpoint stopped.", NULL); exit(0); case BpPayloadPresent: /* Clear to process the payload. */ DTNMP_DEBUG_ERR("iif_receive", "Payload present.", NULL); break; default: /* No message. Return NULL. */ return NULL; break; } } content_len = zco_source_data_length(sdr, dlv.adu); /* Step 2: Allocate result space. */ *size = content_len; if((buffer = (uint8_t*) MTAKE(content_len)) == NULL) { DTNMP_DEBUG_ERR("iif_receive","Can't alloc %d of msg.", content_len); DTNMP_DEBUG_ERR("iif_receive","Timeout is %d.", timeout); DTNMP_DEBUG_EXIT("iif_receive","->NULL",NULL); return NULL; } /* Step 2: Read the bundle in from the ZCO. */ sdr_begin_xn(sdr); zco_start_receiving(dlv.adu, &reader); dataLength = zco_receive_source(sdr, &reader, content_len, (char*)buffer); if(sdr_end_xn(sdr) < 0 || dataLength < 0) { DTNMP_DEBUG_ERR("iif_receive", "Unable to process received bundle.", NULL); MRELEASE(buffer); DTNMP_DEBUG_EXIT("iif_receive","-> NULL", NULL); return NULL; } /* Step 5: Set up the metadata. */ strcpy(meta->senderEid.name, dlv.bundleSourceEid); strcpy(meta->originatorEid.name, dlv.bundleSourceEid); strcpy(meta->recipientEid.name, iif->local_eid.name); DTNMP_DEBUG_EXIT("iif_receive", "->0x%x", (unsigned long) buffer); return buffer; } /****************************************************************************** * * \par Function Name: iif_register_node * * \par Registers the current application with the DTN network. * * \retval 0 - Could not Register * 1 - Registered. * * \param[out] iif Updated IIF structure. * \param[in] eid EID of the node we are registering. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/10/11 V.Ramachandran Initial implementation, *****************************************************************************/ uint8_t iif_register_node(iif_t *iif, eid_t eid) { DTNMP_DEBUG_ENTRY("iif_register_node","(%s)", eid.name); /* Step 0: Sanity Check */ if(iif == NULL) { DTNMP_DEBUG_ERR("iif_register_node","Null IIF.", NULL); DTNMP_DEBUG_EXIT("iif_register_node","-> %d", 0); return 0; } iif->local_eid = eid; if(bp_attach() < 0) { DTNMP_DEBUG_ERR("iif_register_node","Failed to attach.", NULL); DTNMP_DEBUG_EXIT("iif_register_node","-> %d", 0); return 0; } if(bp_open((char *)eid.name, &(iif->sap)) < 0) { DTNMP_DEBUG_ERR("iif_register_node","Failed to open %s.", eid.name); DTNMP_DEBUG_EXIT("iif_register_node","-> %d", 0); return 0; } DTNMP_DEBUG_INFO("iif_register_node","Registered Agent as %s.", eid.name); DTNMP_DEBUG_EXIT("iif_register_node","-> %d", 1); return 1; } /****************************************************************************** * * \par Function Name: iif_send * * \par Sends a text string to the recipient node. * * \retval Whether the send succeeded (1) or failed (0) * * \param[in] iif The registered interface * \param[in] data The data to send. * \param[in] len The length of data to send, in bytes. * \param[in] rx_eid The EID of the recipient of the data. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/10/11 V.Ramachandran Initial implementation, * 06/25/13 E. Birrane Renamed message "bundle" message "group". *****************************************************************************/ uint8_t iif_send(iif_t *iif, pdu_group_t *group, char *recipient) { BpExtendedCOS extendedCOS = {0, 0, 0}; Object extent; Object newBundle; int sdrDataLength; // Space allocated in SDR int ctrlZco = 0; uint8_t *data = NULL; uint32_t len; DTNMP_DEBUG_ENTRY("iif_send","(%#llx, %#llx, %#llx)", iif, group, recipient); /* Step 0 - Sanity checks. */ if((iif == NULL) || (group == NULL) || (recipient == NULL)) { DTNMP_DEBUG_ERR("iif_send","Bad Args.", NULL); DTNMP_DEBUG_EXIT("iif_send", "->0.", NULL); return 0; } /* Step 1 - Serialize the bundle. */ data = pdu_serialize_group(group, &len); if(len == 0) { MRELEASE(data); DTNMP_DEBUG_ERR("iif_send","Bad message of length 0.", NULL); DTNMP_DEBUG_EXIT("iif_send", "->0.", NULL); return 0; } /* Information on bitstream we are sending. */ DTNMP_DEBUG_INFO("iif_send","Sending following data of length %d",len); utils_print_hex(data, len); /* Step 2 - Get the SDR, insert the message as an SDR transaction.*/ Sdr sdr = bp_get_sdr(); CHKZERO(sdr_begin_xn(sdr)); extent = sdr_malloc(sdr, len); if(extent) { sdr_write(sdr, extent, (char *) data, len); } else { DTNMP_DEBUG_ERR("iif_send","Can't write to NULL extent.", NULL); } // Object sdrObj = sdr_insert(sdr, (char *) data, len); if (sdr_end_xn(sdr) < 0) { DTNMP_DEBUG_ERR("iif_send","Can't close transaction?", NULL); } /* Step 3 - Great ZCO in an SDR transaction.*/ Object content = ionCreateZco(ZcoSdrSource, extent, 0, len, &ctrlZco); //Object content = zco_create(sdr, ZcoSdrSource, sdrObj, 0, len); if(!content) { DTNMP_DEBUG_ERR("iif_send","Zero-Copy Object creation failed.", NULL); DTNMP_DEBUG_EXIT("iif_send", "->0.", NULL); return 0; } /* Step 4 - Pass on to the BPA to send.*/ int res = 0; if((res = bp_send( iif->sap, // BpSAP reference recipient, // recipient NULL, // report-to 300, // lifespan (?) BP_STD_PRIORITY, // Class-of-Service / Priority NoCustodyRequested, // Custody Switch 0, // SRR Flags 0, // ACK Requested &extendedCOS, // Extended COS content, // ADU &newBundle // New Bundle )) != 1) { DTNMP_DEBUG_ERR("iif_send","Send failed (%d).", res); MRELEASE(data); DTNMP_DEBUG_EXIT("iif_send", "->0.", NULL); return 0; } MRELEASE(data); DTNMP_DEBUG_EXIT("iif_send", "->1.", NULL); return 1; } ion-3.2.0~dfsg1.orig/nm/shared/utils/ion_if.h0000644000175000017500000000545512260400057017334 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: ion_if.h ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for DTNMP actors to connect to ** the local BPA. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 08/10/11 V.Ramachandran Initial Implementation ** 11/13/12 E. Birrane Technical review, comment updates. ** 06/25/13 E. Birrane Renamed message "bundle" message "group". *****************************************************************************/ #ifndef ION_IF_H_ #define ION_IF_H_ #include "bp.h" #include "shared/msg/pdu.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ /** * The ION Interface structure captures state necessary to communicate with * the local Bundle Protocol Agent (BPA). */ typedef struct { eid_t local_eid; BpSAP sap; } iif_t; /* * +--------------------------------------------------------------------------+ * | DATA DEFINITIONS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ uint8_t iif_deregister_node(iif_t *iif); eid_t iif_get_local_eid(iif_t *iif); uint8_t iif_is_registered(iif_t *iif); uint8_t* iif_receive(iif_t *iif, uint32_t *size, pdu_metadata_t *meta, int timeout); uint8_t iif_register_node(iif_t *iif, eid_t eid); uint8_t iif_send(iif_t *iif, pdu_group_t *group, char *recipient); #endif /* ION_IF_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/utils/utils.c0000644000175000017500000006275112260400057017226 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file utils.c ** ** Subsystem: ** Network Management Utilities ** ** Description: ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/29/12 E. Birrane Initial Implementation. *****************************************************************************/ #include "platform.h" #include "ion.h" #include "shared/utils/debug.h" #include "shared/utils/utils.h" /****************************************************************************** * * \par Function Name: atox * * \par Initializes an unsigned long with a value from a string. For example, * return an unsigned long with the value 0x01020304 from the string * "01020304". * * \param[in] s The string to be converted to a hex array. * \param[out] success Whether the conversion was a success. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/25/12 E. Birrane Initial implementation. * 12/16/12 E. Birrane Added success return, error checks, logging *****************************************************************************/ unsigned long utils_atox(char *s, int *success) { unsigned long result = 0; int i = 0; int mult = 0; int j = 0; int temp = 0; DTNMP_DEBUG_ENTRY("utils_atox","(%#llx, %#llx)", s, success); /* Step 0 - Sanity Check. */ if((s == NULL) || (success == NULL)) { DTNMP_DEBUG_ERR("utils_atox","Bad Args.",NULL); *success = 0; DTNMP_DEBUG_ENTRY("utils_atox","->0.",NULL); return 0; } *success = 1; /* Step 1 - Make sure string isn't too long. Since every character in the * string represents a nibble, 2 characters are a byte, making * the longest valid length sizeof(unsigned long) * 2. */ if(strlen(s) > (sizeof(unsigned long) * 2)) { DTNMP_DEBUG_ERR("utils_atox","x UI: String %s too long to convert to hex unsigned long.", s); *success = 0; DTNMP_DEBUG_ENTRY("utils_atox","->0.",NULL); return 0; } /* Step 2 - Walk through the string building the result. */ for(i = strlen(s)-1; i >= 0; i--) { mult = j * 16; if(mult == 0) { mult = 1; } switch(s[i]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': temp = s[i] - '0'; result += temp * mult; break; case 'A': case 'a': result += 10 * mult; break; case 'B': case 'b': result += 11 * mult; break; case 'C': case 'c': result += 12 * mult; break; case 'D': case 'd': result += 13 * mult; break; case 'E': case 'e': result += 14 * mult; break; case 'F': case 'f': result += 15 * mult; break; default: DTNMP_DEBUG_ERR("utils_atox","x Non-hex character: %c", s[i]); *success = 0; j--; break; } j++; } DTNMP_DEBUG_INFO("utils_atox","i UI: Turned string %s to number %x.", s, result); return result; } /****************************************************************************** * * \par Function Name: utils_datacol_compare * * \par Determines equivalence of two Data Collections. * * \retval -1 : Error * 0 : col1 == col2 * 1 : col1 != col2 * * \param[in] col1 First Data Collection being compared. * \param[in] col2 Second Data Collection being compared. * * \par Notes: * 1. This function should only check for equivalence (== 0), not order * since we do not differentiate between col1 < col2 and error. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/12 E. Birrane Initial implementation, *****************************************************************************/ int utils_datacol_compare(Lyst col1, Lyst col2) { LystElt elt1; LystElt elt2; datacol_entry_t *entry1 = NULL; datacol_entry_t *entry2 = NULL; DTNMP_DEBUG_ENTRY("utils_datacol_compare","(%#llx, %#llx)",col1, col2); /* Step 0: Sanity check. */ if((col1 == NULL) || (col2 == NULL)) { DTNMP_DEBUG_ERR("utils_datacol_compare", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("utils_datacol_compare","->-1.", NULL); return -1; } /* Step 1: Easy checks: Same magnitude? */ if(lyst_length(col1) == lyst_length(col2)) { elt1 = lyst_first(col1); elt2 = lyst_first(col2); while(elt1 && elt2) { entry1 = (datacol_entry_t *) lyst_data(elt1); entry2 = (datacol_entry_t *) lyst_data(elt2); if(entry1->length != entry2->length) { DTNMP_DEBUG_EXIT("utils_datacol_compare","->1.", NULL); return 1; } else if(memcmp(entry1->value,entry2->value,entry1->length) != 0) { DTNMP_DEBUG_EXIT("utils_datacol_compare","->1.", NULL); return 1; } elt1 = lyst_next(elt1); elt2 = lyst_next(elt2); } } else { DTNMP_DEBUG_EXIT("utils_datacol_compare","->1.", NULL); return 1; } DTNMP_DEBUG_EXIT("utils_datacol_compare","->0.", NULL); return 0; } /****************************************************************************** * * \par Function Name: utils_datacol_copy * * \par Duplicates a Data Collection object. * * \retval NULL - Failure * !NULL - The copied MID * * \param[in] col The Data Collection being copied. * * \par Notes: * 1. The returned Data Collection is allocated and must be freed when * no longer needed. This is a deep copy. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/22/12 E. Birrane Initial implementation, *****************************************************************************/ Lyst utils_datacol_copy(Lyst col) { Lyst result = NULL; LystElt elt; datacol_entry_t *cur_entry = NULL; datacol_entry_t *new_entry = NULL; DTNMP_DEBUG_ENTRY("utils_datacol_copy","(%#llx)",(unsigned long) col); /* Step 0: Sanity Check. */ if(col == NULL) { DTNMP_DEBUG_ERR("utils_datacol_copy","Bad Args.",NULL); DTNMP_DEBUG_EXIT("utils_datacol_copy","->NULL.",NULL); return NULL; } /* Build the Lyst. */ if((result = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("utils_datacol_copy","Unable to create lyst.",NULL); DTNMP_DEBUG_EXIT("utils_datacol_copy","->NULL.",NULL); return NULL; } /* Walking copy. */ int success = 1; for(elt = lyst_first(col); elt; elt = lyst_next(elt)) { cur_entry = (datacol_entry_t *) lyst_data(elt); if((new_entry = (datacol_entry_t*)MTAKE(sizeof(datacol_entry_t))) == NULL) { DTNMP_DEBUG_ERR("utils_datacol_copy","Failed to alloc %d bytes.", sizeof(datacol_entry_t)); utils_datacol_destroy(&result); DTNMP_DEBUG_EXIT("utils_datacol_copy","->NULL.",NULL); return NULL; } new_entry->length = cur_entry->length; if((new_entry->value = (uint8_t*)MTAKE(new_entry->length)) == NULL) { DTNMP_DEBUG_ERR("utils_datacol_copy","Failed to alloc %d bytes.", new_entry->length); MRELEASE(new_entry); utils_datacol_destroy(&result); DTNMP_DEBUG_EXIT("utils_datacol_copy","->NULL.",NULL); return NULL; } memcpy(new_entry->value, cur_entry->value, new_entry->length); lyst_insert_last(result,new_entry); } DTNMP_DEBUG_EXIT("utils_datacol_copy","->%#llx.",(unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: utils_datacol_deserialize * * \par Extracts a Data Collection from a byte buffer. When serialized, a * Data Collection is an SDNV # of items, followed by a series of * entries. Each entry is an SDNV size followed by a blob of data. * * \retval NULL - Failure * !NULL - The created/deserialized Data Collection. * * \param[in] buffer The byte buffer holding the data * \param[in] buffer_size The # bytes available in the buffer * \param[out] bytes_used The # of bytes consumed in the deserialization. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/12 E. Birrane Initial implementation, * 06/17/13 E. Birrane Updated to ION 3.1.3, moved to uvast data type. *****************************************************************************/ Lyst utils_datacol_deserialize(uint8_t* buffer, uint32_t buffer_size, uint32_t *bytes_used) { unsigned char *cursor = NULL; Lyst result = NULL; uint32_t bytes = 0; uvast num = 0; uvast len = 0; uint32_t i = 0; DTNMP_DEBUG_ENTRY("utils_datacol_deserialize","(%#llx,%d,%#llx)", (unsigned long) buffer, buffer_size, (unsigned long) bytes_used); /* Step 0: Sanity Check. */ if((buffer == NULL) || (buffer_size == 0) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("utils_datacol_deserialize","Bad Args", NULL); DTNMP_DEBUG_EXIT("utils_datacol_deserialize","->NULL",NULL); return NULL; } *bytes_used = 0; cursor = buffer; /* Step 1: Create the Lyst. */ if((result = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("utils_datacol_deserialize","Can't create lyst.", NULL); DTNMP_DEBUG_EXIT("utils_datacol_deserialize","->NULL",NULL); return NULL; } /* Step 2: Grab # entries in the collection. */ if((bytes = utils_grab_sdnv(cursor, buffer_size, &num)) == 0) { DTNMP_DEBUG_ERR("utils_datacol_deserialize","Can't parse SDNV.", NULL); lyst_destroy(result); DTNMP_DEBUG_EXIT("utils_datacol_deserialize","->NULL",NULL); return NULL; } else { cursor += bytes; buffer_size -= bytes; *bytes_used += bytes; } /* Step 3: Grab entries. */ for(i = 0; i < num; i++) { datacol_entry_t *entry = NULL; /* Make new entry. */ if((entry = (datacol_entry_t*) MTAKE(sizeof(datacol_entry_t))) == NULL) { DTNMP_DEBUG_ERR("utils_datacol_deserialize","Can't grab MID #%d.", i); utils_datacol_destroy(&result); DTNMP_DEBUG_EXIT("utils_datacol_deserialize","->NULL",NULL); return NULL; } /* Grab data item length. */ if((bytes = utils_grab_sdnv(cursor, buffer_size, &len)) == 0) { DTNMP_DEBUG_ERR("utils_datacol_deserialize","Can't parse SDNV.", NULL); MRELEASE(entry); utils_datacol_destroy(&result); DTNMP_DEBUG_EXIT("utils_datacol_deserialize","->NULL",NULL); return NULL; } cursor += bytes; buffer_size -= bytes; *bytes_used += bytes; entry->length = len; if((entry->value = (uint8_t*)MTAKE(entry->length)) == NULL) { DTNMP_DEBUG_ERR("utils_datacol_deserialize","Can't parse SDNV.", NULL); MRELEASE(entry); utils_datacol_destroy(&result); DTNMP_DEBUG_EXIT("utils_datacol_deserialize","->NULL",NULL); return NULL; } memcpy(entry->value, cursor, entry->length); cursor += entry->length; buffer_size -= entry->length; *bytes_used += entry->length; /* Drop it in the lyst in order. */ lyst_insert_last(result, entry); } DTNMP_DEBUG_EXIT("utils_datacol_deserialize","->%#llx",(unsigned long)result); return result; } /****************************************************************************** * * \par Function Name: utils_datacol_destroy * * \par Releases all memory allocated in the Data Collection. Clear all Data * Collection information. * * \param[in,out] datacol The data collection to be destroyed. * * \par Notes: * - We pass in a pointer so we can destroy the lyst. The lyst must not * be accessed after this call. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/22/12 E. Birrane Initial implementation, *****************************************************************************/ void utils_datacol_destroy(Lyst *datacol) { LystElt elt; datacol_entry_t *entry = NULL; DTNMP_DEBUG_ENTRY("utils_datacol_destroy","(%#llx)", (unsigned long) datacol); /* * Step 0: Make sure we even have a lyst. Not an error if not, since we * are destroying anyway. */ if((datacol == NULL) || (*datacol == NULL)) { DTNMP_DEBUG_ERR("utils_datacol_destroy","Bad Args.",NULL); DTNMP_DEBUG_EXIT("utils_datacol_destroy","->.", NULL); return; } /* Step 1: Walk through the MIDs releasing as you go. */ for(elt = lyst_first(*datacol); elt; elt = lyst_next(elt)) { entry = (datacol_entry_t *) lyst_data(elt); if(entry != NULL) { MRELEASE(entry->value); MRELEASE(entry); } } /* Step 2: Destroy and zero out the lyst. */ lyst_destroy(*datacol); *datacol = NULL; DTNMP_DEBUG_EXIT("utils_datacol_destroy","->.", NULL); } /****************************************************************************** * * \par Function Name: utils_datacol_serialize * * \par Purpose: Generate full, serialized version of a Data Collection. A * serialized Data Collection is of the form: * \par +-------+--------+--------+ +--------+--------+ * | # | Item 1 | Item 1 | | Item N | Item N | * | Items | Size | Data |... | Size | Data | * | [SDNV]| [SDNV] |[BYTES] | | [SDNV] |[BYTES] | * +-------+--------+--------+ +--------+--------+ * * \retval NULL - Failure serializing * !NULL - Serialized collection. * * \param[in] datacol The Data Collection to be serialized. * \param[out] size The size of the resulting serialized Collection. * * \par Notes: * 1. The result is allocated on the memory pool and must be released when * no longer needed. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 11/14/12 E. Birrane Initial implementation, *****************************************************************************/ uint8_t *utils_datacol_serialize(Lyst datacol, uint32_t *size) { uint8_t *result = NULL; Sdnv num_sdnv; Sdnv tmp; LystElt elt; DTNMP_DEBUG_ENTRY("utils_datacol_serialize","(%#llx, %#llx)", (unsigned long) datacol, (unsigned long) size); /* Step 0: Sanity Check */ if((datacol == NULL) || (size == NULL)) { DTNMP_DEBUG_ERR("utils_datacol_serialize","Bad args.", NULL); DTNMP_DEBUG_EXIT("utils_datacol_serialize","->NULL",NULL); return NULL; } /* Step 1: Calculate the size. */ /* Consider the size of the SDNV holding # data entries.*/ encodeSdnv(&num_sdnv, lyst_length(datacol)); *size = num_sdnv.length; /* Walk through each datacol and look at size. */ for(elt = lyst_first(datacol); elt; elt = lyst_next(elt)) { datacol_entry_t *entry = (datacol_entry_t *) lyst_data(elt); if(entry != NULL) { encodeSdnv(&tmp, entry->length); *size += (entry->length + tmp.length); } else { DTNMP_DEBUG_WARN("utils_datacol_serialize","Found NULL Entry?", NULL); } } /* Step 3: Allocate the space for the serialized list. */ if((result = (uint8_t*) MTAKE(*size)) == NULL) { DTNMP_DEBUG_ERR("utils_datacol_serialize","Can't alloc %d bytes", *size); *size = 0; DTNMP_DEBUG_EXIT("utils_datacol_serialize","->NULL",NULL); return NULL; } /* Step 4: Walk through list again copying as we go. */ uint8_t *cursor = result; /* Copy over the number of data entries in the collection. */ memcpy(cursor, num_sdnv.text, num_sdnv.length); cursor += num_sdnv.length; for(elt = lyst_first(datacol); elt; elt = lyst_next(elt)) { datacol_entry_t *entry = (datacol_entry_t *) lyst_data(elt); if(entry != NULL) { encodeSdnv(&tmp, entry->length); memcpy(cursor, tmp.text, tmp.length); cursor += tmp.length; memcpy(cursor,entry->value, entry->length); cursor += entry->length; } else { DTNMP_DEBUG_WARN("utils_datacol_serialize","Found NULL MID?", NULL); } } /* Step 5: Final sanity check. */ if((cursor - result) != *size) { DTNMP_DEBUG_ERR("utils_datacol_serialize","Wrote %d bytes not %d bytes", (cursor - result), *size); *size = 0; MRELEASE(result); DTNMP_DEBUG_EXIT("utils_datacol_serialize","->NULL",NULL); return NULL; } DTNMP_DEBUG_EXIT("utils_datacol_serialize","->%#llx",(unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: utils_grab_byte * * \par Purpose: extracts a byte from a sized buffer. * * \return 0 - Failure. * >0 - # bytes consumed from the buffer. * * \param[in,out] cursor Pointer into current buffer. * \param[in] size Remaining size of the buffer. * \param[out] result The extracted byte. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ int8_t utils_grab_byte(unsigned char *cursor, uint32_t size, uint8_t *result) { DTNMP_DEBUG_ENTRY("utils_grab_byte","(%x,%d,%x)", (unsigned long) cursor, size, (unsigned long) result); /* Do we have a byte to grab? */ if(size < 1) { DTNMP_DEBUG_ERR("utils_grab_byte","Bounds overrun. Size %d Used %d.", size, 1); DTNMP_DEBUG_EXIT("utils_grab_byte","-> 0", NULL); return 0; } *result = *cursor; DTNMP_DEBUG_EXIT("utils_grab_byte","-> 1", NULL); return 1; } /****************************************************************************** * * \par Function Name: utils_grab_sdnv * * \par Purpose: extracts an SDNV value from a sized buffer. * * \return 0 - Failure. * >0 - # bytes consumed from the buffer. * * \param[in,out] cursor Pointer into current buffer. * \param[in] size Remaining size of the buffer. * \param[out] result The extracted value. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, * 06/17/13 E. Birrane Updated to ION 3.1.3, added uvast type. *****************************************************************************/ uint32_t utils_grab_sdnv(unsigned char *cursor, uint32_t size, uvast *result) { int result_len = 0; DTNMP_DEBUG_ENTRY("utils_grab_sdnv","(%x,%d,%x)", (unsigned long) cursor, (unsigned long) size, (unsigned long) result); if((result_len = decodeSdnv(result, cursor)) == 0) { DTNMP_DEBUG_ERR("utils_grab_sdnv","Bad SDNV extract.", NULL); DTNMP_DEBUG_EXIT("utils_grab_sdnv","-> 0", NULL); return 0; } /* Did we go too far? */ if((size-result_len) < 0) { DTNMP_DEBUG_ERR("utils_grab_sdnv","Bounds overrun. Size %d Used %d.", size, result_len); DTNMP_DEBUG_EXIT("utils_grab_sdnv","-> 0", NULL); return 0; } DTNMP_DEBUG_EXIT("utils_grab_sdnv","-> %d", result_len); return result_len; } /****************************************************************************** * * \par Function Name: utils_hex_to_string * * \par Purpose: Constructs a character string of values from a buffer. * * \return NULL - Failure. * !NULL - Desired string * * \param[in] buffer The buffer whose string representation is desired. * \param[in] size Size of the buffer, in bytes, * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ char *utils_hex_to_string(uint8_t *buffer, uint32_t size) { char *result = NULL; uint32_t char_size = 0; char temp[3]; int i = 0; int r = 0; DTNMP_DEBUG_ENTRY("utils_hex_to_string","(%x,%d)", (unsigned long) buffer, size); /* Each byte requires 2 characters to represent in HEX. Also, require * three additional bytes to capture '0x' and NULL terminator. */ char_size = (2 * size) + 3; result = (char *) MTAKE(char_size); if(result == NULL) { DTNMP_DEBUG_ERR("utils_hex_to_string", "Cannot allocate %d bytes.", char_size); DTNMP_DEBUG_EXIT("utils_hex_to_string", "-> NULL.", NULL); return NULL; } result[0] = '0'; result[1] = 'x'; r = 2; for(i = 0; i < size; i++) { sprintf(temp, "%.2x", (unsigned int)buffer[i]); result[r++] = temp[0]; result[r++] = temp[1]; } result[r] = '\0'; DTNMP_DEBUG_EXIT("mid_to_string","->%s.", result); return result; } /****************************************************************************** * * \par Function Name: utils_print_hex * * \par Purpose: Prints a string as a series of hex characters. * * \param[in] s The string to be printed. * \param[in] len The length of the string. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ void utils_print_hex(unsigned char *s, uint32_t len) { int i; printf("0x"); for(i = 0; i < len; i++) { printf("%.2x", s[i]); } printf("\n"); } /****************************************************************************** * * \par Function Name: utils_string_to_hex * * \par Purpose: Converts an ASCII string representing hex values to a byte * array of those hex values. * * \return NULL - Failure. * !NULL - The desired byte array. * * \param[in] value The string to be converted to hex. * \param[out] size The length of the converted byte array. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/14/12 E. Birrane Initial implementation, *****************************************************************************/ uint8_t *utils_string_to_hex(unsigned char *value, uint32_t *size) { uint8_t *result = NULL; char tmp_s[3]; int len = 0; int success = 0; int pad = 0; DTNMP_DEBUG_ENTRY("utils_string_to_hex","(%#llx, %#llx)", value, size); /* Step 0 - Sanity Checks. */ if((value == NULL) || (size == NULL)) { DTNMP_DEBUG_ERR("utils_string_to_hex", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("utils_string_to_hex", "->NULL.", NULL); return NULL; } /* Step 1 - Figure out the size of the byte array. Since each ASCII * character represents a nibble, the size of the byte array is * half the size of the string (accounting for odd values). */ len = strlen((char*)value); if((len%2) == 0) { *size = len/2; } else { *size = (len/2) + 1; pad = 1; } if((result = (uint8_t *) MTAKE(*size)) == NULL) { DTNMP_DEBUG_ERR("utils_string_to_hex","Can't Alloc %d bytes.", *size); *size = 0; DTNMP_DEBUG_EXIT("utils_string_to_hex", "->NULL.", NULL); return NULL; } /* Step 2 - For each byte, copy in the nibbles. */ tmp_s[2] = '\0'; int incr = 1; int base = 0; int i = 0; for(i = 0; i < len;) { if(pad == 1) { tmp_s[0] = '0'; tmp_s[1] = value[i]; pad = 0; incr = 1; base = 1; } else { memcpy(tmp_s, &(value[i]), 2); incr = 2; } result[(i+base)/2] = utils_atox(tmp_s, &success); i += incr; if(success == 0) { DTNMP_DEBUG_ERR("utils_string_to_hex","Can't AtoX %s.", tmp_s); MRELEASE(result); *size = 0; DTNMP_DEBUG_EXIT("utils_string_to_hex", "->NULL.", NULL); return NULL; } } DTNMP_DEBUG_EXIT("utils_string_to_hex", "->%#llx.", result); return result; } /* * THis software adapted from: * http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html * * performs: result = t1 - t2. */ int utils_time_delta(struct timeval *result, struct timeval *t1, struct timeval *t2) { /* Perform the carry for the later subtraction by updating t2. */ if (t1->tv_usec < t2->tv_usec) { int nsec = (t2->tv_usec - t1->tv_usec) / 1000000 + 1; t2->tv_usec -= 1000000 * nsec; t2->tv_sec += nsec; } if (t1->tv_usec - t2->tv_usec > 1000000) { int nsec = (t1->tv_usec - t2->tv_usec) / 1000000; t2->tv_usec += 1000000 * nsec; t2->tv_sec -= nsec; } /* Compute the time remaining to wait. tv_usec is certainly positive. */ result->tv_sec = t1->tv_sec - t2->tv_sec; result->tv_usec = t1->tv_usec - t2->tv_usec; /* Return 1 if result is negative. */ return t1->tv_sec < t2->tv_sec; } /* Return number of micro-seconds that have elapsed since the passed-in time.*/ vast utils_time_cur_delta(struct timeval *t1) { vast result = 0; struct timeval cur; struct timeval delta; int neg = 0; getCurrentTime(&cur); neg = utils_time_delta(&delta, &cur, t1); result = delta.tv_usec; result += delta.tv_sec * 1000000; if(neg) { result *= -1; } return result; } ion-3.2.0~dfsg1.orig/nm/shared/utils/nm_types.h0000644000175000017500000000133712260400057017722 0ustar l3onl3on// // nm_types.h // DTN Network Management Agent Structures and Data Types // // Author: V. Ramachandran, 8/31/2011 // Copyright 2011 Johns Hopkins University APL. All rights reserved. // #ifndef NM_TYPES_H #define NM_TYPES_H #include #include #include "platform.h" #include "debug.h" #define MAX_EID_LEN (256) // The beginning of the J2000 epoch (01 Jan 2000, 11:58:55.816 UTC) in // seconds of the Posix (1970) epoch. #define BEGIN_J2000 (946727936) /* The DTNMP relative time cut-off, set as the first second of * September 9th, 2012. */ #define DTNMP_RELATIVE_TIME_EPOCH (1348025776) typedef struct { char name[MAX_EID_LEN]; } eid_t; typedef unsigned char* buffer_t; #endif /* NM_TYPES_H */ ion-3.2.0~dfsg1.orig/nm/shared/utils/utils.h0000644000175000017500000000711612260400057017225 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: utils.h ** ** Subsystem: ** Network Management Utilities ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for the identification and ** processing of DTNMP Managed Identifiers (MIDs). ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 10/29/12 E. Birrane Initial Implementation *****************************************************************************/ #ifndef UTILS_H_ #define UTILS_H_ #include "stdint.h" #include "bp.h" #include "lyst.h" /* * +--------------------------------------------------------------------------+ * | CONSTANTS + * +--------------------------------------------------------------------------+ */ #ifndef MIN #define MIN(x,y) (x < y ? x : y) #endif /* * +--------------------------------------------------------------------------+ * | DATA TYPES + * +--------------------------------------------------------------------------+ */ /** * The Data Collection is similar to a MID collection: an SDNV count followed * by one or more of a homogeneous structure. In the case of a Data Collection, * the structure is given by the datacol_entry_t. This is simply a buffer with * associated byte length. */ typedef struct { uint8_t *value; /**> The data associated with the entry. */ uint32_t length; /**> The length of the data in bytes. */ } datacol_entry_t; /* * +--------------------------------------------------------------------------+ * | DATA DEFINITIONS + * +--------------------------------------------------------------------------+ */ /* * +--------------------------------------------------------------------------+ * | FUNCTION PROTOTYPES + * +--------------------------------------------------------------------------+ */ //unsigned long utils_atox(char *s); unsigned long utils_atox(char *s, int *success); int utils_datacol_compare(Lyst col1, Lyst col2); Lyst utils_datacol_copy(Lyst col); Lyst utils_datacol_deserialize(uint8_t* buffer, uint32_t buffer_size, uint32_t *bytes_used); void utils_datacol_destroy(Lyst *datacol); uint8_t* utils_datacol_serialize(Lyst datacol, uint32_t *size); int8_t utils_grab_byte(unsigned char *cursor, uint32_t size, uint8_t *result); uint32_t utils_grab_sdnv(unsigned char *cursor, uint32_t size, uvast *result); char* utils_hex_to_string(uint8_t *buffer, uint32_t size); void utils_print_hex(unsigned char *s, uint32_t len); uint8_t* utils_string_to_hex(unsigned char *value, uint32_t *size); int utils_time_delta(struct timeval *result, struct timeval *t1, struct timeval *t2); vast utils_time_cur_delta(struct timeval *t1); #endif /* UTILS_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/utils/expr.h0000644000175000017500000000442112260400057017037 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: expr.h ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for DTNMP actors to construct and ** evaluate expressions. ** ** Notes: ** ** Assumptions: ** 1. For the time being, we only support unsigned long as a data type. ** 2. For the time being, we assume operators are binary operators. ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/28/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef EXPR_H_ #define EXPR_H_ #include "ion_if.h" #include "nm_types.h" #include "shared/primitives/mid.h" /* 3 bits */ #define EXPR_TYPE_INT32 0 #define EXPR_TYPE_UINT32 1 #define EXPR_TYPE_VAST 2 #define EXPR_TYPE_UVAST 3 #define EXPR_TYPE_REAL32 4 #define EXPR_TYPE_REAL64 5 #define EXPR_TYPE_BLOB 6 #define EXPR_TYPE_STRING 7 /* Literal... I need to know : Type : Value (pre-defined or in the OID structure.) OID reserved for LITERAL. Parm 1 is type. Parm 2 is value. Operator I need to know: This can be hard-coded to MID/OID. - Operands (1, 2, 3) - Result type */ typedef struct { int type; uint8_t *value; uint64_t length; } expr_result_t; expr_result_t *expr_get_value(mid_t *mid); expr_result_t *expr_apply_binary_op(mid_t *op, expr_result_t *expr1, expr_result_t *expr2); expr_result_t *expr_eval(Lyst expr); void expr_release(expr_result_t result); #endif /* EXPR_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/utils/db.h0000644000175000017500000000315312260400057016447 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: db.h ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for DTNMP actors to interact with ** SDRs to persistently store information. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 06/29/13 E. Birrane Initial Implementation *****************************************************************************/ #ifndef DB_H_ #define DB_H_ #include "ion_if.h" #include "nm_types.h" int db_forget(Object *primitiveObj, Object *descObj, Object list); int db_persist(uint8_t *item, uint32_t item_len, Object *itemObj, void *desc, uint32_t desc_len, Object *descObj, Object list); #endif /* DB_H_ */ ion-3.2.0~dfsg1.orig/nm/shared/utils/expr.c0000644000175000017500000000333312260400057017033 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: expr.c ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for DTNMP actors to construct and ** evaluate expressions. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/28/13 E. Birrane Initial Implementation *****************************************************************************/ #include "expr.h" expr_result_t *expr_get_value(mid_t *mid) { switch(MID_GET_FLAG_TYPE(mid->flags)) { case MID_TYPE_DATA: /* Use the associated collect function */ break; case MID_TYPE_LITERAL: break; case MID_TYPE_OPERATOR: break; default: break; } } expr_result_t *expr_apply_binary_op(mid_t *op, expr_result_t *expr1, expr_result_t *expr2) { } expr_result_t *expr_eval(Lyst expr) { } void expr_release(expr_result_t result) { MRELEASE(result.value); } ion-3.2.0~dfsg1.orig/nm/shared/utils/debug.h0000644000175000017500000000571612260400057017157 0ustar l3onl3on// // nm_debug.h // DTN NM Agent // // Created by Birrane, Edward J. on 10/21/11. // Copyright 2011 __MyCompanyName__. All rights reserved. // #ifndef DEBUG_H_ #define DEBUG_H_ /***************************************************************************** * DEBUG DEFINITIONS * *****************************************************************************/ #ifndef DTNMP_DEBUGGING #define DTNMP_DEBUGGING 1 /** Whether to enable (1) or disable (0) debugging */ #endif #define DTNMP_DEBUG_LVL_PROC 1 /** Function entry/exit and above debugging */ #define DTNMP_DEBUG_LVL_INFO 2 /** Info information and above debugging */ #define DTNMP_DEBUG_LVL_WARN 3 /** Warning and above debugging */ #define DTNMP_DEBUG_LVL_ERR 4 /** Error and above debugging */ #define DTNMP_DEBUG_LVL DTNMP_DEBUG_LVL_WARN #define GMSG_BUFLEN 512 #if DTNMP_DEBUGGING == 1 extern char gMsg[]; /* Debug message buffer. */ #endif /** * \def DTNMP_DEBUG * Constructs an error string message and sends it to putErrmsg. There are * four levels of debugging specified: * 1: Function entry/exit logging. This logs the entry and exit of all major * functions in the DTNMP library and is useful for confirming control flow * through the DTNMP module. * 2: Information logging. Information statements are peppered through the * code to provide insight into the state of the module at processing * points considered useful by DTNMP module software engineers. * 3: Warning logging. Warning statements are used to flag unexpected * values that, based on context, may not constitute errors. * 4: Error logging. Errors are areas in the code where some sanity check * or other required condition fails to be met by the software. * * Error logging within the DTNMP module is of the form: * : * Where id is one of: * + (function entry) * - (function exit) * i (information statement) * ? (warning statement) * x (error statement) * * Debugging can be turned off at compile time by removing the * DTNMP_DEBUGGING #define. */ #define DTNMP_DEBUG(level, type, func, format,...) if(level >= DTNMP_DEBUG_LVL) \ {isprintf(gMsg, GMSG_BUFLEN, (char *) format, __VA_ARGS__); \ fprintf(stderr, "[%s:%d] %c %s %s\n",__FILE__,__LINE__,type, func, gMsg);} #define DTNMP_DEBUG_ENTRY(func, format,...) \ DTNMP_DEBUG(DTNMP_DEBUG_LVL_PROC,'+',func,format, __VA_ARGS__) #define DTNMP_DEBUG_EXIT(func, format,...) \ DTNMP_DEBUG(DTNMP_DEBUG_LVL_PROC,'-',func,format, __VA_ARGS__) #define DTNMP_DEBUG_INFO(func, format,...) \ DTNMP_DEBUG(DTNMP_DEBUG_LVL_INFO,'i',func,format, __VA_ARGS__) #define DTNMP_DEBUG_WARN(func, format,...) \ DTNMP_DEBUG(DTNMP_DEBUG_LVL_WARN,'w',func,format, __VA_ARGS__) #define DTNMP_DEBUG_ERR(func, format,...) \ DTNMP_DEBUG(DTNMP_DEBUG_LVL_ERR,'x',func,format, __VA_ARGS__) #define DTNMP_DEBUG_ALWAYS(func, format,...) \ DTNMP_DEBUG(DTNMP_DEBUG_LVL,':',func,format, __VA_ARGS__) #endif // DEBUG_H_ ion-3.2.0~dfsg1.orig/nm/shared/utils/db.c0000644000175000017500000001015012260400057016435 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** File Name: db.c ** ** Description: This file contains the definitions, prototypes, constants, and ** other information necessary for DTNMP actors to interact with ** SDRs to persistently store information. ** ** Notes: ** ** Assumptions: ** ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 06/29/13 E. Birrane Initial Implementation *****************************************************************************/ #include "db.h" int db_forget(Object *primitiveObj, Object *descObj, Object list) { Sdr sdr = getIonsdr(); Object elt; if((primitiveObj == NULL) || (descObj == NULL) || (list == 0)) { DTNMP_DEBUG_ERR("db_forget","Bad Params.",NULL); return -1; } sdr_begin_xn(sdr); if(*primitiveObj != 0) { sdr_free(sdr, *primitiveObj); } if(*descObj != 0) { elt = sdr_list_first(sdr, list); while(elt) { if(sdr_list_data(sdr, elt) == *descObj) { sdr_list_delete(sdr, elt, NULL, NULL); sdr_free(sdr, *descObj); elt = 0; } else { elt = sdr_list_next(sdr, elt); } } } sdr_end_xn(sdr); /* Forget now invalid SDR pointers. */ *descObj = 0; *primitiveObj = 0; return 1; } /* * This function writes an item and its associated descriptor into the SDR, * allocating space for each, and adding the SDR descriptor pointer to a * given SDR list. * * item : The serialized item to store in the SDR. * item_len: The size of the serialized item. * *itemObj: The SDR pointer to the serialized item in the SDR. * desc : The item descriptor being written to the SDR. * desc_len: The size of the item descriptor. * *descObj: The SDR pointer to the item's descriptor object in the SDR. * list : The SDR list holding the item descriptor (at *descrObj). */ int db_persist(uint8_t *item, uint32_t item_len, Object *itemObj, void *desc, uint32_t desc_len, Object *descObj, Object list) { Sdr sdr = getIonsdr(); sdr_begin_xn(sdr); /* Step 1: Allocate a descriptor object for this item in the SDR. */ if((*descObj = sdr_malloc(sdr, desc_len)) == 0) { sdr_cancel_xn(sdr); DTNMP_DEBUG_ERR("db_persist", "Can't allocate descriptor of size %d.", desc_len); return -1; } /* Step 2: Allocate space for the serialized rule in the SDR. */ if((*itemObj = sdr_malloc(sdr, item_len)) == 0) { sdr_free(sdr, *descObj); sdr_cancel_xn(sdr); *descObj = 0; DTNMP_DEBUG_ERR("db_persist", "Unable to allocate Item in SDR. Size %d.", item_len); return -1; } /* Step 3: Write the item to the SDR. */ sdr_write(sdr, *itemObj, (char *) item, item_len); /* Step 4: Write the item descriptor to the SDR. */ sdr_write(sdr, *descObj, (char *) desc, desc_len); /* Step 5: Save the descriptor in the AgentDB active rules list. */ if (sdr_list_insert_last(sdr, list, *descObj) == 0) { sdr_free(sdr, *itemObj); sdr_free(sdr, *descObj); sdr_cancel_xn(sdr); *itemObj = 0; *descObj = 0; DTNMP_DEBUG_ERR("db_persist", "Unable to insert item Descr. in SDR.", NULL); return -1; } if(sdr_end_xn(sdr)) { DTNMP_DEBUG_ERR("db_persist", "Can't create Agent database.", NULL); return -1; } return 1; } ion-3.2.0~dfsg1.orig/nm/test/0000755000175000017500000000000012260400057014260 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/test/testInsertDataReport.sql0000644000175000017500000000513312260400057021135 0ustar l3onl3onUSE dtnmp; -- Create Report #1 -- Get MIDs SET @MID1 := (SELECT ID FROM dbtMIDs WHERE ID = 2); SET @MID2 := (SELECT ID FROM dbtMIDs WHERE ID = 3); SET @MID3 := (SELECT ID FROM dbtMIDs WHERE ID = 4); -- Create Report MID INSERT INTO dbtMIDs (Attributes,Type,Category,IssuerFlag,TagFlag,OIDType,IssuerID,OIDValue,TagValue) VALUES (2,b'10',b'10',b'0',b'0',b'00',0,'082b0601020303010d',0); SET @DefineCustomReportMIDIDValue = LAST_INSERT_ID(); -- Create MID Collection ID INSERT INTO dbtMIDCollections (Comment) VALUES ('R1'); SET @MIDCollectionID = LAST_INSERT_ID(); -- Create MID Collection INSERT INTO dbtMIDCollection (CollectionID,MIDID,MIDOrder) VALUES (@MIDCollectionID,@MID1,1); INSERT INTO dbtMIDCollection (CollectionID,MIDID,MIDOrder) VALUES (@MIDCollectionID,@MID2,2); INSERT INTO dbtMIDCollection (CollectionID,MIDID,MIDOrder) VALUES (@MIDCollectionID,@MID3,3); -- Create Definition for Define Custom Report INSERT INTO dbtMessagesDefinitions (DefinitionType,DefinitionID,DefinitionMC) VALUES (1,@DefineCustomReportMIDIDValue,@MIDCollectionID); -- Define a Control INSERT INTO dbtMessagesControls(Type,Start,Periods,Predicate,Count,Collection) VALUES(1,0,1,0,1,@MIDCollectionID); -- Register an agent INSERT INTO dbtRegisteredAgents(AgentID) VALUES('ipn:21404.1'); -- Create an outgoing Message Group with the Control from above INSERT INTO dbtOutgoing(CreatedTS,ModifiedTS,State) VALUES(NOW(),NOW(),0); SET @v1 = LAST_INSERT_ID(); SELECT @v2 := ID FROM lvtMessageTablesList WHERE TableName='dbtMessagesControls'; SELECT @v3 := MAX(ID) FROM dbtMessagesControls; INSERT INTO dbtOutgoingMessages(OutgoingID,MessagesTableID,MessagesTableRowID) VALUES(@v1,@v2,@v3); -- Retrieve unprocessed (READY) Outgoing Messages SELECT @MessageGroupID := dbtOutgoing.ID, @TableName := lvtMessageTablesList.TableName, @TableRowID := dbtOutgoingMessages.MessagesTableRowID FROM dbtOutgoing, dbtOutgoingMessages, lvtMessageTablesList WHERE dbtOutgoing.State=0 AND dbtOutgoing.ID=dbtOutgoingMessages.OutgoingID AND lvtMessageTablesList.ID=dbtOutgoingMessages.MessagesTableID; -- Give a sender for the (READY) Outgoing Messages SELECT @sender := ID FROM dbtOutgoing WHERE dbtOutgoing.State=0; INSERT INTO dbtOutgoingRecipients(OutgoingID,AgentID) VALUES(@sender,1); -- Retrieve the contents of the table listed as an Outgoing Message SET @s = CONCAT('select * from ', @TableName, ' where ID = ', @TableRowID); PREPARE stmt1 FROM @s; EXECUTE stmt1; DEALLOCATE PREPARE stmt1; -- Tell Manager we are ready to process. UPDATE dbtOutgoing SET State = State + 1 WHERE ID = @v1; PREPARE stmt1 FROM @s; EXECUTE stmt1; DEALLOCATE PREPARE stmt1; ion-3.2.0~dfsg1.orig/nm/test/run_test.sh0000755000175000017500000000013212260400057016456 0ustar l3onl3onmysql -u root --password=NetworkManagement -h localhost dtnmp < testInsertDataReport.sql ion-3.2.0~dfsg1.orig/nm/test/testControlsData.sql0000644000175000017500000000630712260400057020304 0ustar l3onl3onUse dtnmp; -- Create MID Collection INSERT INTO dbtMIDCollections(Comment) VALUES('m1'); SET @coll = LAST_INSERT_ID(); INSERT INTO dbtMIDCollection(CollectionID,MIDID,MIDOrder) VALUES(@coll,4,1); INSERT INTO dbtMIDCollection(CollectionID,MIDID,MIDOrder) VALUES(@coll,2,2); INSERT INTO dbtMIDCollection(CollectionID,MIDID,MIDOrder) VALUES(@coll,3,3); -- Define a Control INSERT INTO dbtMessagesControls(Type,Start,Periods,Predicate,Count,Collection) VALUES(1,0,1,0,3,@coll); -- Create an outgoing Message Group with the Control from above INSERT INTO dbtOutgoing(CreatedTS,ModifiedTS,State) VALUES(NOW(),NOW(),0); SET @v1 = LAST_INSERT_ID(); SELECT @v2 := ID FROM lvtMessageTablesList WHERE TableName='dbtMessagesControls'; SELECT @v3 := MAX(ID) FROM dbtMessagesControls; INSERT INTO dbtOutgoingMessages(OutgoingID,MessagesTableID,MessagesTableRowID) VALUES(@v1,@v2,@v3); UPDATE dbtOutgoing SET State = State + 1 WHERE ID = @v1; -- Retrieve unprocessed (READY) Outgoing Messages SELECT @MessageGroupID := dbtOutgoing.ID, @TableName := lvtMessageTablesList.TableName, @TableRowID := dbtOutgoingMessages.MessagesTableRowID FROM dbtOutgoing, dbtOutgoingMessages, lvtMessageTablesList WHERE dbtOutgoing.State=1 AND dbtOutgoing.ID=dbtOutgoingMessages.OutgoingID AND lvtMessageTablesList.ID=dbtOutgoingMessages.MessagesTableID; -- Retrieve the contents of the table listed as an Outgoing Message SET @s = CONCAT('select * from ', @TableName, ' where ID = ', @TableRowID); PREPARE stmt1 FROM @s; EXECUTE stmt1; DEALLOCATE PREPARE stmt1; -- Create Report #1 -- Get MIDs SET @MID1 := (SELECT ID FROM dbtMIDs WHERE ID = 5); -- Create Report MID INSERT INTO dbtMIDs (Attributes,Type,Category,IssuerFlag,TagFlag,OIDType,IssuerID,OIDValue,TagValue) VALUES (2,0,2,false,false,0,2,'92a0301020100010403',0); SET @DefineCustomReportMIDIDValue = LAST_INSERT_ID(); -- Create MID Collection ID INSERT INTO dbtMIDCollections (Comment) VALUES ('R1'); SET @MIDCollectionID = LAST_INSERT_ID(); -- Create MID Collection INSERT INTO dbtMIDCollection (CollectionID,MIDID,MIDOrder) VALUES (@MIDCollectionID,@MID1,1); -- Create Definition for Define Custom Report INSERT INTO dbtMessagesDefinitions (DefinitionType,DefinitionID,DefinitionMC) VALUES (1,@DefineCustomReportMIDIDValue,@MIDCollectionID); -- Define a Control INSERT INTO dbtMessagesControls(Type,Start,Periods,Predicate,Count,Collection) VALUES(1,1,2,0,3,@MIDCollectionID); -- Create an outgoing Message Group with the Control from above INSERT INTO dbtOutgoing(CreatedTS,ModifiedTS,State) VALUES(NOW(),NOW(),0); SET @v1 = LAST_INSERT_ID(); SELECT @v2 := ID FROM lvtMessageTablesList WHERE TableName='dbtMessagesControls'; SELECT @v3 := MAX(ID) FROM dbtMessagesControls; INSERT INTO dbtOutgoingMessages(OutgoingID,MessagesTableID,MessagesTableRowID) VALUES(@v1,@v2,@v3); UPDATE dbtOutgoing SET State = State + 1 WHERE ID = @v1; -- Retrieve unprocessed (READY) Outgoing Messages SELECT @MessageGroupID := dbtOutgoing.ID, @TableName := lvtMessageTablesList.TableName, @TableRowID := dbtOutgoingMessages.MessagesTableRowID FROM dbtOutgoing, dbtOutgoingMessages, lvtMessageTablesList WHERE dbtOutgoing.State=1 AND dbtOutgoing.ID=dbtOutgoingMessages.OutgoingID AND lvtMessageTablesList.ID=dbtOutgoingMessages.MessagesTableID; ion-3.2.0~dfsg1.orig/nm/test/testMacro.sql0000644000175000017500000000465512260400057016754 0ustar l3onl3onUse dtnmp; -- Make a Control MID -- INSERT INTO dbtMIDs(Attributes,Type,Category,IssuerFlag,TagFlag,OIDType,IssuerID,OIDValue,TagValue) VALUES(0,b'01',b'00',b'0',b'0',0,0,'092A030102017A010300',0); INSERT INTO dbtMIDs(Attributes,Type,Category,IssuerFlag,TagFlag,OIDType,IssuerID,OIDValue,TagValue) VALUES(0,b'01',b'00',b'0',b'0',b'01',0,'082B06010203010301',0); SET @MIDID := LAST_INSERT_ID(); -- Make a MID Collection INSERT INTO dbtMIDCollections(Comment) VALUES('m1'); SET @MCID := LAST_INSERT_ID(); INSERT INTO dbtMIDCollection(CollectionID,MIDID,MIDOrder) VALUES(@MCID,@MIDID,1); -- Define a Control INSERT INTO dbtMessagesControls(Type,Start,Periods,Predicate,Count,Collection) VALUES(3,0,0,0,0,@MCID); -- Define Data Collection INSERT INTO dbtDataCollections(comment) VALUES('c1'); SET @DCID := LAST_INSERT_ID(); -- Define Data Collection Entry INSERT INTO dbtDataCollection(CollectionID,DataLength,DataBlob,DataOrder) VALUES(@DCID,11,'ipn:21404.1',1); -- Enter info into ParameterizedOIDs INSERT INTO dbtMIDParameterizedOIDs(MIDID,DataCollectionID) VALUES(@MIDID,@DCID); -- Register an agent INSERT INTO dbtRegisteredAgents(AgentID) VALUES('ipn:21404.1'); -- Create an outgoing Message Group with the Control from above INSERT INTO dbtOutgoing(CreatedTS,ModifiedTS,State) VALUES(NOW(),NOW(),0); SET @v1 = LAST_INSERT_ID(); SELECT @v2 := ID FROM lvtMessageTablesList WHERE TableName='dbtMessagesControls'; SELECT @v3 := MAX(ID) FROM dbtMessagesControls; INSERT INTO dbtOutgoingMessages(OutgoingID,MessagesTableID,MessagesTableRowID) VALUES(@v1,@v2,@v3); -- Retrieve unprocessed (READY) Outgoing Messages SELECT @MessageGroupID := dbtOutgoing.ID, @TableName := lvtMessageTablesList.TableName, @TableRowID := dbtOutgoingMessages.MessagesTableRowID FROM dbtOutgoing, dbtOutgoingMessages, lvtMessageTablesList WHERE dbtOutgoing.State=0 AND dbtOutgoing.ID=dbtOutgoingMessages.OutgoingID AND lvtMessageTablesList.ID=dbtOutgoingMessages.MessagesTableID; -- Give a sender for the (READY) Outgoing Messages SELECT @sender := ID FROM dbtOutgoing WHERE dbtOutgoing.State=0; INSERT INTO dbtOutgoingRecipients(OutgoingID,AgentID) VALUES(@sender,1); -- Retrieve the contents of the table listed as an Outgoing Message SET @s = CONCAT('select * from ', @TableName, ' where ID = ', @TableRowID); PREPARE stmt1 FROM @s; EXECUTE stmt1; DEALLOCATE PREPARE stmt1; -- Tell Manager we are ready to process. UPDATE dbtOutgoing SET State = State + 1 WHERE ID = @v1; ion-3.2.0~dfsg1.orig/nm/test/testcontrols.sql0000644000175000017500000000360512260400057017550 0ustar l3onl3onuse dtnmp; -- Create MID Collection INSERT INTO dbtMIDCollections(Comment) VALUES('m1'); SET @coll = LAST_INSERT_ID(); INSERT INTO dbtMIDCollection(CollectionID,MIDID,MIDOrder) VALUES(@coll,4,1); INSERT INTO dbtMIDCollection(CollectionID,MIDID,MIDOrder) VALUES(@coll,2,2); INSERT INTO dbtMIDCollection(CollectionID,MIDID,MIDOrder) VALUES(@coll,3,3); -- Define a Control INSERT INTO dbtMessagesControls(Type,Start,Periods,Predicate,Count,Collection) VALUES(1,0,1,0,1,@coll); -- Register an agent INSERT INTO dbtRegisteredAgents(AgentID) VALUES('ipn:21404.1'); -- Create an outgoing Message Group with the Control from above INSERT INTO dbtOutgoing(CreatedTS,ModifiedTS,State) VALUES(NOW(),NOW(),0); SET @v1 = LAST_INSERT_ID(); SELECT @v2 := ID FROM lvtMessageTablesList WHERE TableName='dbtMessagesControls'; SELECT @v3 := MAX(ID) FROM dbtMessagesControls; INSERT INTO dbtOutgoingMessages(OutgoingID,MessagesTableID,MessagesTableRowID) VALUES(@v1,@v2,@v3); -- Retrieve unprocessed (READY) Outgoing Messages SELECT @MessageGroupID := dbtOutgoing.ID, @TableName := lvtMessageTablesList.TableName, @TableRowID := dbtOutgoingMessages.MessagesTableRowID FROM dbtOutgoing, dbtOutgoingMessages, lvtMessageTablesList WHERE dbtOutgoing.State=0 AND dbtOutgoing.ID=dbtOutgoingMessages.OutgoingID AND lvtMessageTablesList.ID=dbtOutgoingMessages.MessagesTableID; -- Give a sender for the (READY) Outgoing Messages SELECT @sender := ID FROM dbtOutgoing WHERE dbtOutgoing.State=0; INSERT INTO dbtOutgoingRecipients(OutgoingID,AgentID) VALUES(@sender,1); -- Retrieve the contents of the table listed as an Outgoing Message SET @s = CONCAT('select * from ', @TableName, ' where ID = ', @TableRowID); PREPARE stmt1 FROM @s; EXECUTE stmt1; DEALLOCATE PREPARE stmt1; -- Tell Manager we are ready to process. UPDATE dbtOutgoing SET State = State + 1 WHERE ID = @v1; PREPARE stmt1 FROM @s; EXECUTE stmt1; DEALLOCATE PREPARE stmt1; ion-3.2.0~dfsg1.orig/nm/db/0000755000175000017500000000000012260400056013665 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/db/dtnmpddl.sql0000644000175000017500000002345412260400056016224 0ustar l3onl3onDROP DATABASE IF EXISTS dtnmp; CREATE DATABASE dtnmp; USE dtnmp; DROP TABLE IF EXISTS dbtOutgoing; CREATE TABLE dbtOutgoing ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, CreatedTS Datetime, ModifiedTS Datetime, State TINYINT NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtOutgoingMessages; CREATE TABLE dbtOutgoingMessages ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, OutgoingID INT UNSIGNED NOT NULL DEFAULT 0, MessagesTableID INT UNSIGNED NOT NULL DEFAULT 0, MessagesTableRowID INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtOutgoingRecipients; CREATE TABLE dbtOutgoingRecipients ( OutgoingID INT UNSIGNED NOT NULL DEFAULT 0, AgentID INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtIncoming; CREATE TABLE dbtIncoming ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, ReceivedTS Datetime, GeneratedTS Datetime, State TINYINT NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtIncomingMessages; CREATE TABLE dbtIncomingMessages ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, IncomingID INT UNSIGNED NOT NULL DEFAULT 0, Content BLOB) ; DROP TABLE IF EXISTS lvtMessageTablesList; CREATE TABLE lvtMessageTablesList ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, TableName VARCHAR(64) NOT NULL DEFAULT 'ERROR') ; DROP TABLE IF EXISTS dbtRegisteredAgents; CREATE TABLE dbtRegisteredAgents ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, AgentId VARCHAR(128) NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMessagesAdministrativeStatusReportingPolicy; CREATE TABLE dbtMessagesAdministrativeStatusReportingPolicy ( AgentID INT UNSIGNED NOT NULL DEFAULT 0 PRIMARY KEY, AlertBit Bit(1), WarnBit Bit(1), ErrorBit Bit(1), LogBit Bit(1)) ; DROP TABLE IF EXISTS dbtMessagesAdministrativeStatusMessages; CREATE TABLE dbtMessagesAdministrativeStatusMessages ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Code INT UNSIGNED NOT NULL DEFAULT 0, Time INT UNSIGNED NOT NULL DEFAULT 0, GeneratorsMC INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMessagesDefinitions; CREATE TABLE dbtMessagesDefinitions ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, DefinitionType TINYINT NOT NULL DEFAULT 0, DefinitionID INT UNSIGNED NOT NULL DEFAULT 0, DefinitionMC INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMessagesReportingDataList; CREATE TABLE dbtMessagesReportingDataList ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, ConfiguredIdMC INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMessagesReportingDataDefinitions; CREATE TABLE dbtMessagesReportingDataDefinitions ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, DefinitionID INT UNSIGNED NOT NULL DEFAULT 0, DefinitionMC CHAR(64)) ; DROP TABLE IF EXISTS dbtMessagesReportingDataReport; CREATE TABLE dbtMessagesReportingDataReport ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, MessageGroupID INT UNSIGNED NOT NULL DEFAULT 0, Time INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMessagesReportingDataReportList; CREATE TABLE dbtMessagesReportingDataReportList ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, DataReportID INT UNSIGNED NOT NULL DEFAULT 0, ReportID INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMessagesReportingDataReportData; CREATE TABLE dbtMessagesReportingDataReportData ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, DataReportListID INT UNSIGNED NOT NULL DEFAULT 0, Data TINYINT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMessagesReportingProductionScheduleReport; CREATE TABLE dbtMessagesReportingProductionScheduleReport ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, MessageGroupID INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMessagesReportingProductionScheduleReports; CREATE TABLE dbtMessagesReportingProductionScheduleReports ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, ReportID INT UNSIGNED NOT NULL DEFAULT 0, Type TINYINT UNSIGNED NOT NULL DEFAULT 0, Start INT UNSIGNED NOT NULL DEFAULT 0, ConditionID INT UNSIGNED NOT NULL DEFAULT 0, Count BIGINT UNSIGNED NOT NULL DEFAULT 0, Results INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMessagesControls; CREATE TABLE dbtMessagesControls ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Type TINYINT UNSIGNED NOT NULL DEFAULT 0, Start BIGINT UNSIGNED NOT NULL DEFAULT 0, Periods BIGINT UNSIGNED NOT NULL DEFAULT 1, Predicate INT UNSIGNED NOT NULL DEFAULT 0, Count BIGINT UNSIGNED NOT NULL DEFAULT 0, Collection INT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMIDs; CREATE TABLE dbtMIDs ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Attributes INT UNSIGNED NOT NULL DEFAULT 0, Type Bit(2) NOT NULL DEFAULT 0, Category Bit(2) NOT NULL DEFAULT 0, IssuerFlag Bit(1) NOT NULL DEFAULT 0, TagFlag Bit(1) NOT NULL DEFAULT 0, OIDType Bit(2) NOT NULL DEFAULT 0, IssuerID BIGINT UNSIGNED NOT NULL DEFAULT 0, OIDValue VARCHAR(64), TagValue BIGINT UNSIGNED NOT NULL DEFAULT 0) ; DROP TABLE IF EXISTS dbtMIDCollections; CREATE TABLE dbtMIDCollections ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Comment VARCHAR(255)) ; DROP TABLE IF EXISTS dbtMIDCollection; CREATE TABLE dbtMIDCollection ( CollectionID INT UNSIGNED NOT NULL DEFAULT 0, MIDID INT UNSIGNED NOT NULL DEFAULT 0, MIDOrder INT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`CollectionID`,`MIDID`,`MIDOrder`)) ; DROP TABLE IF EXISTS dbtMIDDetails; CREATE TABLE dbtMIDDetails ( MIDID INT UNSIGNED NOT NULL DEFAULT 0, MIBName VARCHAR(50) NOT NULL DEFAULT '', MIBISO VARCHAR(255) NOT NULL DEFAULT '', Name VARCHAR(50) NOT NULL DEFAULT '', Description VARCHAR(255) NOT NULL DEFAULT '') ; DROP TABLE IF EXISTS lvtMIDAttributes; CREATE TABLE lvtMIDAttributes ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(50) NOT NULL DEFAULT '', Description VARCHAR(255) NOT NULL DEFAULT '') ; DROP TABLE IF EXISTS lvtMIDIssuers; CREATE TABLE lvtMIDIssuers ( ID BIGINT UNSIGNED NOT NULL PRIMARY KEY, Name VARCHAR(50) NOT NULL DEFAULT 'Unknown Issuer', Description VARCHAR(255) NOT NULL DEFAULT 'No Description.') ; DROP TABLE IF EXISTS dbtMIDParameterizedOIDs; CREATE TABLE dbtMIDParameterizedOIDs ( MIDID INT UNSIGNED NOT NULL DEFAULT 0, DataCollectionID INT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`MIDID`,`DataCollectionID`)) ; DROP TABLE IF EXISTS dbtDataCollections; CREATE TABLE dbtDataCollections ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Comment VARCHAR(255)) ; DROP TABLE IF EXISTS dbtDataCollection; CREATE TABLE dbtDataCollection ( CollectionID INT UNSIGNED NOT NULL DEFAULT 0, DataLength INT UNSIGNED NOT NULL DEFAULT 0, DataBlob MEDIUMBLOB , DataOrder INT NOT NULL DEFAULT 0, PRIMARY KEY (`CollectionID`,`DataOrder`)) ; DROP TABLE IF EXISTS lvtOutgoingState; CREATE TABLE lvtOutgoingState ( ID INT UNSIGNED NOT NULL PRIMARY KEY, Name VARCHAR(50) NOT NULL DEFAULT '', Description VARCHAR(255) NOT NULL DEFAULT '') ; DROP TABLE IF EXISTS lvtIncomingState; CREATE TABLE lvtIncomingState ( ID INT UNSIGNED NOT NULL PRIMARY KEY, Name VARCHAR(50) NOT NULL DEFAULT '', Description VARCHAR(255) NOT NULL DEFAULT '') ; -- Populate lvtOutgoingState INSERT INTO lvtOutgoingState (ID,Name,Description) VALUES (0,'Initializing',''); INSERT INTO lvtOutgoingState (ID,Name,Description) VALUES (1,'Ready',''); INSERT INTO lvtOutgoingState (ID,Name,Description) VALUES (2,'Processing',''); INSERT INTO lvtOutgoingState (ID,Name,Description) VALUES (3,'Sent',''); -- Populate lvtIncomingState INSERT INTO lvtIncomingState (ID,Name,Description) VALUES (0,'Initializing',''); INSERT INTO lvtIncomingState (ID,Name,Description) VALUES (1,'Ready',''); INSERT INTO lvtIncomingState (ID,Name,Description) VALUES (2,'Processed',''); -- Populate lvtMessageTablesList INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtOutgoing'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtOutgoingMessages'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtOutgoingRecipients'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtIncoming'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtIncomingMessages'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtRegisteredAgents'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesAdministrativeStatusReportingPolicy'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesAdministrativeStatusMessages'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesDefinitions'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesReportingDataList'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesReportingDataDefinitions'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesReportingDataReport'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesReportingDataReportList'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesReportingDataReportData'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesReportingProductionScheduleReport'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesReportingProductionScheduleReports'); INSERT INTO lvtMessageTablesList (TableName) VALUES ('dbtMessagesControls'); -- Populate lvtMIDAttributes INSERT INTO lvtMIDAttributes (Name,Description) VALUES ('Atomic MID','This is an atomic MID.'); INSERT INTO lvtMIDAttributes (Name,Description) VALUES ('User MID','This is an user defined MID.'); -- Populate lvtMIDIssuers INSERT INTO lvtMIDIssuers (ID,Name,Description) VALUES (1,'Ed','Ed B.'); INSERT INTO lvtMIDIssuers (ID,Name,Description) VALUES (2,'Miriam','Miriam W.'); INSERT INTO lvtMIDIssuers (ID,Name,Description) VALUES (3,'Leor','Leor B.'); INSERT INTO lvtMIDIssuers (ID,Name,Description) VALUES (4,'Mark','Mark S.'); INSERT INTO lvtMIDIssuers (ID,Name,Description) VALUES (5,'Sam','Sam J.'); ion-3.2.0~dfsg1.orig/nm/Makefile0000644000175000017500000000005712260400056014742 0ustar l3onl3on all: (cd mgr; make all) (cd agent; make all)ion-3.2.0~dfsg1.orig/nm/mgr/0000755000175000017500000000000012260400056014065 5ustar l3onl3onion-3.2.0~dfsg1.orig/nm/mgr/nm_mgr_ui.h0000644000175000017500000000573512260400056016224 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file nm_mgr_ui.h ** ** ** Description: A text-based DTNMP Manager. This manager provides the ** following functions associated with DTN network management: ** ** 1. Define and send custom report and macro definitions ** 2. Provide tools to build all versions of MIDs and OIDs. ** 3. Configure Agents for time- and state- based production ** 4. Print data reports received from a DTNMP Agent ** ** Notes: ** 1. Currently we do not support ACLs. ** 2. Currently, we do not support multiple DTNMP agents. ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/18/13 E. Birrane Code comments and cleanup *****************************************************************************/ #include "nm_mgr.h" #include "shared/utils/nm_types.h" #include "shared/adm/adm.h" #include "shared/primitives/mid.h" #define UI_MAIN_MENU 0 #define UI_ADMIN_MENU 1 #define UI_DEF_MENU 2 #define UI_RPT_MENU 3 #define UI_CTRL_MENU 4 extern int gContext; mid_t *ui_build_mid(char *mid_str); void ui_clear_reports(agent_t* agent); agent_t *ui_select_agent(); void ui_construct_ctrl_by_idx(agent_t* agent); void ui_construct_time_rule_by_idx(agent_t* agent); void ui_construct_time_rule_by_mid(agent_t* agent); void ui_define_macro(agent_t* agent); void ui_define_report(agent_t* agent); void ui_define_mid_params(char *name, int num_parms, mid_t *mid); void ui_register_agent(); void ui_deregister_agent(); void ui_event_loop(); int ui_get_user_input(char *prompt, char **line, int max_len); mid_t *ui_input_mid(); int ui_input_mid_flag(uint8_t *flag); Lyst ui_parse_mid_str(char *mid_str, int max_idx, int type); void ui_print_ctrls(); int ui_print_agents(); void ui_print_custom_rpt(rpt_data_entry_t *rpt_entry, def_gen_t *rpt_def); void ui_print_menu_admin(); void ui_print_menu_ctrl(); void ui_print_menu_def(); void ui_print_menu_main(); void ui_print_menu_rpt(); void ui_print_mids(); void ui_print_predefined_rpt(mid_t *mid, uint8_t *data, uint64_t data_size, uint64_t *data_used, adm_datadef_t *adu); void ui_print_reports(agent_t *agent); void ui_run_tests(); void *ui_thread(void * threadId); ion-3.2.0~dfsg1.orig/nm/mgr/nm_mgr_db.h0000644000175000017500000001260712260400056016170 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2011 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** \file nm_mgr_db.h ** ** File Name: nm_mgr_db.h ** ** ** Subsystem: ** Network Manager Daemon: Database Utilities ** ** Description: This file implements the DTNMP Manager interface to a back- ** end SQL database. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/10/13 S. Jacobs Initial Implementation ** 08/19/13 E. Birrane Documentation clean up and code review comments. *****************************************************************************/ #ifdef HAVE_MYSQL #ifndef NM_MGR_DB_H #define NM_MGR_DB_H /* System Headers */ #include "stdio.h" #include "unistd.h" #include "mysql.h" /* ION headers. */ #include "platform.h" #include "lyst.h" /* Application headers. */ #include "shared/adm/adm.h" #include "shared/msg/pdu.h" #include "shared/primitives/admin.h" #include "shared/primitives/mid.h" #include "shared/primitives/report.h" #include "shared/primitives/rules.h" #include "shared/utils/db.h" #include "shared/utils/ion_if.h" #include "shared/utils/utils.h" /* Enumerations */ /* * Transmit enumerations govern the state associated with messages stored in * the database to be sent to an agent. Given that the database may have * multiple writers, these states serve as a synchronization mechanism. */ #define TX_INIT (0) /* An outgoing message group is being written to the db. */ #define TX_READY (1) /* An outgoing message group is ready to be processed. */ #define TX_PROC (2) /* The message group is being processed. */ #define TX_SENT (3) /* The message group has been processed and sent. */ /* * Receive enumerations govern the state associated with messages stored in * the database that have been received by an agent. */ #define RX_INIT (0) /* An incoming message group is being received. */ #define RX_READT (1) /* An incoming message group is done being received. */ #define RX_PROC (2) /* An incoming message group has been processed. */ /* * The DB schema uses a table of tables to identify types of information * stored in outgoing messages. These enumerations capture supported * table identifiers. */ #define UNKNOWN_MSG (0) #define TIME_PROD_MSG (1) #define PRED_PROD_MSG (2) #define EXEC_CTRL_MSG (3) #define CUST_RPT (4) /* Functions to write primitives to associated database tables. */ uint32_t db_add_agent(eid_t agent_eid); uint32_t db_add_mid(int attr, uint8_t flag, uvast issuer, char *OID, uvast tag, char *mib, char *mib_iso, char *name, char *descr); uint32_t db_add_mid_collection(Lyst collection, char *comment); uint32_t db_add_rpt_data(rpt_data_t *rpt_data); uint32_t db_add_rpt_defs(rpt_defs_t *defs); uint32_t db_add_rpt_items(rpt_items_t *items); uint32_t db_add_rpt_sched(rpt_prod_t *sched); /* Functions to fetch primitives from associated database tables. */ ctrl_exec_t *db_fetch_ctrl(int id); Lyst db_fetch_data_col(int dc_id); datacol_entry_t *db_fetch_data_col_entry(int dc_id, int order); datacol_entry_t *db_fetch_data_col_entry_from_row(MYSQL_ROW row); def_gen_t *db_fetch_def(int id); mid_t *db_fetch_mid(int id); /* \todo Fix this for parm OIDs */ Lyst db_fetch_mid_col(int id); int db_fetch_mid_idx(int attr, uint8_t flag, uvast issuer, char *OID, uvast tag); oid_t *db_fetch_oid(int mid_id, int oid_type, char *oid_root); oid_t *db_fetch_oid_full(int mid_id, char *oid_root); oid_t *db_fetch_oid_parms(int mid_id, char* oid_root); uint8_t *db_fetch_parms_str(int mid_id, uint32_t *parm_size, uint32_t *num_parms); rule_pred_prod_t *db_fetch_pred_rule(int id); adm_reg_agent_t *db_fetch_reg_agent(int id); int db_fetch_table_type(int table_idx, int entry_idx); rule_time_prod_t *db_fetch_time_rule(int id); /* Functions to process incoming messages. */ int db_incoming_initialize(time_t timestamp); int db_incoming_finalize(uint32_t incomingID); int db_incoming_process_message(int incomingID, uint8_t *cursor, uint32_t size); /* Database Management Functions. */ void *db_mgt_daemon(void *threadId); int db_mgt_init(char *server, char *user, char *pwd, char *database, int clear); int db_mgt_clear(); void db_mgt_close(); void db_mgt_verify_mids(); /* Functions to process outgoing message tables. */ int db_outgoing_process(MYSQL_RES *sql_res); int db_outgoing_process_messages(uint32_t idx, pdu_group_t *msg_group); int db_outgoing_process_one_message(uint32_t idx, uint32_t entry_idx, pdu_group_t *msg_group, MYSQL_ROW row); Lyst db_outgoing_process_recipients(uint32_t id); int db_outgoing_ready(MYSQL_RES **sql_res); #endif #endif // HAVE_MYSQL ion-3.2.0~dfsg1.orig/nm/mgr/nm_mgr.c0000644000175000017500000004360612260400056015521 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2011 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** \file nm_mgr.c ** ** File Name: nm_mgr.c ** ** Subsystem: ** Network Manager Application ** ** Description: This file implements the DTNMP Manager user interface ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/19/13 E. Birrane Documentation clean up and code review comments. *****************************************************************************/ // Application headers. #include "nm_mgr.h" #include "nm_mgr_ui.h" #include "nm_mgr_db.h" #include "shared/primitives/rules.h" // Definitions of global data. iif_t ion_ptr; uint8_t g_running; Object agents_hashtable; Lyst known_agents; ResourceLock agents_mutex; Lyst macro_defs; ResourceLock macro_defs_mutex; eid_t manager_eid; eid_t agent_eid; uint32_t g_reports_total = 0; Sdr g_sdr; // This function looks to be completely unused at this time. // To prevent compilation warnings, Josh Schendel commented it out on // Aug 22, 2013. // Per comments regarding it's signal registerer, I suspect it should be // uncommented once the UI thread is deprecated and signal handler routines // are reactivated. // //static void mgr_signal_handler(); /****************************************************************************** * * \par Function Name: main * * \par Main agent processing function. * * \param[in] argc # command line arguments. * \param[in] argv[] Command-line arguments. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/20/13 E. Birrane Code Review Updates *****************************************************************************/ int main(int argc, char *argv[]) { pthread_t rx_thr; pthread_t ui_thr; pthread_t daemon_thr; char rx_thr_name[] = "rx_thread"; char ui_thr_name[] = "ui_thread"; char daemon_thr_name[] = "run_daemon"; errno = 0; if(argc != 2) { fprintf(stderr,"Usage: nm_mgr \n"); return 1; } /* Indicate that the threads should run once started. */ g_running = 1; /* Initialize the DTNMP Manager. */ if(mgr_init(argv) != 0) { DTNMP_DEBUG_ERR("main","Can't init DTNMP Manager.", NULL); exit(EXIT_FAILURE); } DTNMP_DEBUG_INFO("main","Manager EID: %s", argv[1]); /* Register signal handlers. */ /* DOn't use signal handlers until we deprecate the UI thread... */ /* isignal(SIGINT, mgr_signal_handler); isignal(SIGTERM, mgr_signal_handler);*/ /* Spawn threads for receiving msgs, user interface, and db connection. */ if(pthread_create(&rx_thr, NULL, mgr_rx_thread, (void *)rx_thr_name)) { DTNMP_DEBUG_ERR("main","Can't create pthread %s, errnor = %s", rx_thr_name, strerror(errno)); exit(EXIT_FAILURE); } if(pthread_create(&ui_thr, NULL, ui_thread, (void *)ui_thr_name)) { DTNMP_DEBUG_ERR("main","Can't create pthread %s, errnor = %s", ui_thr_name, strerror(errno)); exit(EXIT_FAILURE); } #ifdef HAVE_MYSQL if(pthread_create(&daemon_thr, NULL, db_mgt_daemon, (void *)daemon_thr_name)) { DTNMP_DEBUG_ERR("main","Can't create pthread %s, errnor = %s", daemon_thr_name, strerror(errno)); exit(EXIT_FAILURE); } #endif if (pthread_join(rx_thr, NULL)) { DTNMP_DEBUG_ERR("main","Can't join pthread %s. Errnor = %s", rx_thr_name, strerror(errno)); exit(EXIT_FAILURE); } if (pthread_join(ui_thr, NULL)) { DTNMP_DEBUG_ERR("main","Can't join pthread %s. Errnor = %s", ui_thr_name, strerror(errno)); exit(EXIT_FAILURE); } #ifdef HAVE_MYSQL if (pthread_join(daemon_thr, NULL)) { DTNMP_DEBUG_ERR("main","Can't join pthread %s. Errnor = %s", daemon_thr_name, strerror(errno)); exit(EXIT_FAILURE); } #endif DTNMP_DEBUG_ALWAYS("main","Shutting down manager.", NULL); mgr_cleanup(); DTNMP_DEBUG_INFO("main","Exiting Manager after cleanup.", NULL); exit(0); } /****************************************************************************** * * \par Function Name: mgr_agent_get * * \par Retrieve an agent from the manager list of known agents. * * \param[in] in_eid - The endpoint identifier for the agent. * * \return NULL - Error * !NULL - The retrieved agent. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/20/13 E. Birrane Code Review Updates *****************************************************************************/ agent_t* mgr_agent_get(eid_t* in_eid) { Object *entry = NULL; agent_t *agent = NULL; DTNMP_DEBUG_ENTRY("mgr_agent_get","(0x%#llx)", (unsigned long) in_eid); /* Step 0: Sanity Check. */ if(in_eid == NULL) { DTNMP_DEBUG_ERR("mgr_agent_get","Null argument", NULL); DTNMP_DEBUG_EXIT("mgr_agent_get", "->NULL", NULL); return NULL; } /* Step 1: Lock agent mutex, walk list looking for match. */ lockResource(&agents_mutex); LystElt elt = lyst_first(known_agents); while(elt != NULL) { agent = (agent_t *) lyst_data(elt); if(strcmp(in_eid->name, agent->agent_eid.name) == 0) { break; } else { agent = NULL; elt = lyst_next(elt); } } unlockResource(&agents_mutex); if(agent == NULL) { DTNMP_DEBUG_EXIT("mgr_agent_get", "->NULL", NULL); } else { DTNMP_DEBUG_EXIT("mgr_agent_get","->Agent %s", agent->agent_eid.name); } return agent; } /****************************************************************************** * * \par Function Name: mgr_agent_add * * \par Add an agent to the manager list of known agents. * * \param[in] in_eid - The endpoint identifier for the new agent. * * \return -1 - Error * 0 - Duplicate, agent not added. * 1 - Success. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/20/13 E. Birrane Code Review Updates *****************************************************************************/ int mgr_agent_add(eid_t agent_eid) { int result = -1; agent_t *agent = NULL; DTNMP_DEBUG_ENTRY("mgr_agent_add","(%s)", agent_eid.name); lockResource(&agents_mutex); /* Check if the agent is already known. */ if((agent = mgr_agent_get(&agent_eid)) != NULL) { unlockResource(&agents_mutex); result = 0; DTNMP_DEBUG_ERR("mgr_agent_add","Trying to add an already-known agent.", NULL); DTNMP_DEBUG_EXIT("mgr_agent_add","->%d.", result); return result; } /* Create and store the new agent. */ if((agent = mgr_agent_create(&agent_eid)) == NULL) { unlockResource(&agents_mutex); DTNMP_DEBUG_ERR("mgr_agent_add","Failed to create agent.", NULL); DTNMP_DEBUG_EXIT("mgr_agent_add","->%d.", result); return result; } DTNMP_DEBUG_INFO("mgr_agent_add","Registered agent: %s", agent_eid.name); unlockResource(&agents_mutex); result = 1; DTNMP_DEBUG_EXIT("mgr_agent_add","->%d.", result); return result; } /****************************************************************************** * * \par Function Name: mgr_agent_create * * \par Allocate and initialize a new agent structure. * * \param[in] in_eid - The endpoint identifier for the new agent. * * \return NULL - Error * !NULL - Allocated, initialized agent structure. * * \par Notes: * - We assume the agent mutex is already taken when this function is * called. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/20/13 E. Birrane Code Review Updates *****************************************************************************/ agent_t* mgr_agent_create(eid_t *in_eid) { Object *entry = NULL; agent_t *agent = NULL; DTNMP_DEBUG_ENTRY("mgr_agent_create", "(%s)", in_eid->name); /* Step 0: Sanity Check. */ if(in_eid == NULL) { DTNMP_DEBUG_ENTRY("mgr_agent_create", "(NULL)", NULL); DTNMP_DEBUG_EXIT("mgr_agent_create", "->NULL", NULL); return NULL; } /* Step 1: Allocate space for the new agent. */ if((agent = (agent_t*)MTAKE(sizeof(agent_t))) == NULL) { DTNMP_DEBUG_ERR("mgr_agent_create", "Unable to allocate %d bytes for new agent %s", sizeof(agent_t), in_eid->name); DTNMP_DEBUG_EXIT("mgr_agent_create", "->NULL", NULL); return NULL; } /* Step 2: Copy over the name. */ strncpy(agent->agent_eid.name, in_eid->name, MAX_EID_LEN); /* Step 3: Create associated lists. */ if((agent->custom_defs = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("mgr_agent_create","Unable to create custom definition lyst for agent %s", in_eid->name); MRELEASE(agent); DTNMP_DEBUG_EXIT("mgr_agent_create","->NULL", NULL); return NULL; } if((agent->reports = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("mgr_agent_create","Unable to create report lyst for agent %s", in_eid->name); lyst_destroy(agent->custom_defs); MRELEASE(agent); DTNMP_DEBUG_EXIT("mgr_agent_create","->NULL", NULL); return NULL; } if(lyst_insert(known_agents, agent) == NULL) { DTNMP_DEBUG_ERR("mgr_agent_create","Unable to insert agent %s into known agents lyst", in_eid->name); lyst_destroy(agent->custom_defs); lyst_destroy(agent->reports); MRELEASE(agent); DTNMP_DEBUG_EXIT("mgr_agent_create","->NULL", NULL); return NULL; } initResourceLock(&(agent->mutex)); DTNMP_DEBUG_EXIT("mgr_agent_create", "->New Agent %s", agent->agent_eid.name); return agent; } /****************************************************************************** * * \par Function Name: mgr_agent_remove * * \par Remove and deallocate the agent identified by the given EID from the * collection of known agents. * * \param[in] in_eid - The endpoint identifier for the agent. * * \return -1 - Error * 0 - Agent not found. * 1 - Success. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/20/13 E. Birrane Code Review Updates *****************************************************************************/ int mgr_agent_remove(eid_t* in_eid) { agent_t *agent = NULL; Object *entry = NULL; LystElt elt; DTNMP_DEBUG_ENTRY("mgr_agent_remove","(0x%#llx)", (unsigned long) in_eid); /* Step 0: Sanity Checks. */ if(in_eid == NULL) { DTNMP_DEBUG_ERR("remove_agent","Specified EID was null.", NULL); DTNMP_DEBUG_EXIT("remove_agent","", NULL); return -1; } lockResource(&agents_mutex); elt = lyst_first(known_agents); while(elt != NULL) { if(strcmp(in_eid->name, ((agent_t *) lyst_data(elt))->agent_eid.name) == 0) { agent = (agent_t *) lyst_data(elt); lyst_delete(elt); break; } else { elt = lyst_next(elt); } } unlockResource(&agents_mutex); if(agent == NULL) { DTNMP_DEBUG_ERR("remove_agent", "No agent %s found in hashtable", in_eid->name); DTNMP_DEBUG_EXIT("remove_agent", "->0", NULL); return 0; } rpt_clear_lyst(&(agent->reports), &(agent->mutex), 1); def_lyst_clear(&(agent->custom_defs), &(agent->mutex), 1); killResourceLock(&(agent->mutex)); MRELEASE(agent); DTNMP_DEBUG_EXIT("remove_agent", "->1", NULL); return 1; } /****************************************************************************** * * \par Function Name: mgr_agent_remove_cb * * \par Lyst callback to remove/delete agents in a lyst. * * \param[in] elt - The lyst element holding the agent. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/20/13 E. Birrane Code Review Updates *****************************************************************************/ void mgr_agent_remove_cb(LystElt elt, void *nil) { eid_t *agent_eid = NULL; agent_t *agent = NULL; Object *entry = NULL; if(elt == NULL) { DTNMP_DEBUG_ERR("mgr_agent_remove_cb", "Specified Lyst element was null.", NULL); DTNMP_DEBUG_EXIT("mgr_agent_remove_cb","", NULL); return; } lockResource(&agents_mutex); if((agent = (agent_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("mgr_agent_remove_cb", "Specified Lyst data was null.", NULL); } else { rpt_clear_lyst(&(agent->reports), &(agent->mutex), 1); def_lyst_clear(&(agent->custom_defs), &(agent->mutex), 1); killResourceLock(&(agent->mutex)); MRELEASE(agent); } unlockResource(&agents_mutex); DTNMP_DEBUG_EXIT("mgr_agent_remove_cb","", NULL); return; } /****************************************************************************** * * \par Function Name: mgr_cleanup * * \par Clesn resources before exiting the manager. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/20/13 E. Birrane Code Review Updates *****************************************************************************/ int mgr_cleanup() { lyst_apply(known_agents, mgr_agent_remove_cb, NULL); lyst_destroy(known_agents); killResourceLock(&agents_mutex); def_lyst_clear(&(macro_defs), &(macro_defs_mutex), 1); killResourceLock(¯o_defs_mutex); return 0; } /****************************************************************************** * * \par Function Name: mgr_init * * \par Initialize the manager... * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/20/13 E. Birrane Code Review Updates *****************************************************************************/ int mgr_init(char *argv[]) { DTNMP_DEBUG_ENTRY("mgr_init","(0x%x)",(unsigned long) argv); strcpy((char *) manager_eid.name, argv[1]); if(iif_register_node(&ion_ptr, manager_eid) == 0) { DTNMP_DEBUG_ERR("mgr_init","Unable to register BP Node. Exiting.", NULL); DTNMP_DEBUG_EXIT("mgr_init","->-1.",NULL); return -1; } if (iif_is_registered(&ion_ptr)) { DTNMP_DEBUG_INFO("mgr_init", "Mgr registered with ION, EID: %s", iif_get_local_eid(&ion_ptr).name); } else { DTNMP_DEBUG_ERR("mgr_init","Failed to register mgr with ION, EID %s", iif_get_local_eid(&ion_ptr).name); DTNMP_DEBUG_EXIT("mgr_init","->-1.",NULL); return -1; } g_sdr = getIonsdr(); if((known_agents = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("mgr_init","Failed to create known agents list.",NULL); //MRELEASE(ion_ptr); DTNMP_DEBUG_EXIT("mgr_init","->-1.",NULL); return -1; } if (initResourceLock(&agents_mutex)) { DTNMP_DEBUG_ERR("mgr_init","Can't initialize rcv rpt list. . errno = %s", strerror(errno)); //MRELEASE(ion_ptr); DTNMP_DEBUG_EXIT("mgr_init","->-1.",NULL); return -1; } if((macro_defs = lyst_create()) == NULL) { DTNMP_DEBUG_ERR("mgr_init","Failed to create macro def list.%s",NULL); //MRELEASE(ion_ptr); DTNMP_DEBUG_EXIT("mgr_init","->-1.",NULL); return -1; } if (initResourceLock(¯o_defs_mutex)) { DTNMP_DEBUG_ERR("mgr_init","Cant init macro def list mutex. errno = %s", strerror(errno)); //MRELEASE(ion_ptr); DTNMP_DEBUG_EXIT("mgr_init","->-1.",NULL); return -1; } adm_init(); #ifdef HAVE_MYSQL db_mgt_init("localhost", "root", "NetworkManagement", "dtnmp", 1); #endif DTNMP_DEBUG_EXIT("mgr_init","->0.",NULL); return 0; } /****************************************************************************** * * \par Function Name: mgr_signal_handler * * \par Catches kill signals and gracefully shuts down the manager. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- ** 08/18/13 E. Birrane Initial Implementation *****************************************************************************/ // This function looks to be completely unused at this time. // To prevent compilation warnings, Josh Schendel commented it out on // Aug 22, 2013. // Per comments regarding it's signal registerer, I suspect it should be // uncommented once the UI thread is deprecated and signal handler routines // are reactivated. // // static void mgr_signal_handler() // { // isignal(SIGINT, mgr_signal_handler); // isignal(SIGTERM, mgr_signal_handler); // // g_running = 0; // } ion-3.2.0~dfsg1.orig/nm/mgr/nm_mgr_rx.c0000644000175000017500000002004112260400056016216 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2011 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** \file nm_mgr_rx.c ** ** File Name: nm_mgr_rx.c ** ** ** Subsystem: ** Network Manager Daemon: Receive Thread ** ** Description: This file implements the management receive thread that ** accepts information from DTNMP agents. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 08/31/11 V. Ramachandran Initial Implementation ** 08/19/13 E. Birrane Documentation clean up and code review comments. *****************************************************************************/ #include "pthread.h" #include "nm_mgr.h" #include "platform.h" #include "shared/utils/ion_if.h" #include "shared/utils/nm_types.h" #include "shared/utils/utils.h" #include "shared/utils/debug.h" #include "shared/msg/pdu.h" #include "shared/msg/msg_reports.h" #include "shared/msg/msg_admin.h" #include "shared/msg/msg_def.h" #include "shared/msg/msg_ctrl.h" #ifdef HAVE_MYSQL #include "nm_mgr_db.h" #endif /****************************************************************************** * * \par Function Name: msg_rx_data_rpt * * \par Process incoming data report message. * * \return 0 - Success * -1 - Failure * * \param[in] sender_eid - The agent providing the report. * \param[in] cursor - Start of the serialized message. * \param[in] size - The size of the serialized stream holding the msg * \param[out] bytes_used - Bytes used in deserializing the report. * * \par Notes: * - \todo: We do not process Access Control Lists (ACLs) at this time. * * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/20/13 E. Birrane Initial Implementation. *****************************************************************************/ int msg_rx_data_rpt(eid_t *sender_eid, uint8_t *cursor, uint32_t size, uint32_t *bytes_used) { agent_t *agent = NULL; int result = -1; DTNMP_DEBUG_ENTRY("msg_rx_data_rpt","()",NULL); /* Step 0: Sanity Check */ if((sender_eid == NULL) || (cursor == NULL) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("msg_rx_data_rpt","Bad Parms", NULL); DTNMP_DEBUG_EXIT("msg_rx_data_rpt","-->-1",NULL); return -1; } DTNMP_DEBUG_ALWAYS("msg_rx_data_rpt", "Processing a data report.\n", NULL); /* Step 1: Retrieve stored information about this agent. */ if((agent = mgr_agent_get(sender_eid)) == NULL) { DTNMP_DEBUG_WARN("msg_rx_data_rpt", "Received group is from an unknown sender (%s); ignoring it.", sender_eid->name); } else { rpt_data_t *report = NULL; if((report = rpt_deserialize_data(cursor, size, bytes_used)) == NULL) { DTNMP_DEBUG_ERR("msg_rx_data_rpt","Can't deserialize rpt",NULL); } else { /* Step 1.1: Add the report. */ lockResource(&(agent->mutex)); lyst_insert_last(agent->reports, report); unlockResource(&(agent->mutex)); result = 0; /* Step 1.2: Update statistics. */ g_reports_total++; } } DTNMP_DEBUG_EXIT("msg_rx_data_rpt","-->%d", result); return result; } /****************************************************************************** * * \par Function Name: mgr_rx_thread * * \par Process incoming messages from the DTNMP agent. * * \return POSIC thread info... * * \param[in] threadId - Thread identifier... * * \par Notes: * - \todo: We do not process Access Control Lists (ACLs) at this time. * * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/20/13 E. Birrane Code cleanup and documentation. *****************************************************************************/ void *mgr_rx_thread(void * threadId) { DTNMP_DEBUG_ENTRY("mgr_rx_thread","(0x%x)", (unsigned long) threadId); DTNMP_DEBUG_INFO("mgr_rx_thread","Receiver thread running...", NULL); uint32_t num_msgs = 0; uint8_t *buf = NULL; uint8_t *cursor = NULL; uint32_t bytes = 0; uint32_t i = 0; pdu_header_t *hdr = NULL; pdu_acl_t *acl = NULL; uint32_t size = 0; pdu_metadata_t meta; uvast val; eid_t *sender_eid = NULL; agent_t *agent = NULL; time_t group_timestamp; uint32_t incoming_idx = 0; uint32_t hdr_len = 0; /* * g_running controls the overall execution of threads in the * NM Agent. */ while(g_running) { /* Step 1: Receive a message from the Bundle Protocol Agent. */ buf = iif_receive(&ion_ptr, &size, &meta, NM_RECEIVE_TIMEOUT_MILLIS); sender_eid = &(meta.originatorEid); if(buf != NULL) { DTNMP_DEBUG_INFO("mgr_rx_thread","Received buf (%x) of size %d", (unsigned long) buf, size); /* Grab # messages in, and timestamp for, this group. */ cursor = buf; bytes = utils_grab_sdnv(cursor, size, &val); num_msgs = val; cursor += bytes; size -= bytes; bytes = utils_grab_sdnv(cursor, size, &val); group_timestamp = val; cursor += bytes; size -= bytes; DTNMP_DEBUG_INFO("mgr_rx_thread","# Msgs %d, TS %llu", num_msgs, group_timestamp); #ifdef HAVE_MYSQL /* Copy the message group to the database tables */ incoming_idx = db_incoming_initialize(group_timestamp); #endif /* For each message in the group. */ for(i = 0; i < num_msgs; i++) { hdr = pdu_deserialize_hdr(cursor, size, &bytes); cursor += bytes; size -= bytes; hdr_len = bytes; DTNMP_DEBUG_INFO("mgr_rx_thread","Header id %d with len %d", hdr->id, hdr_len); switch (hdr->id) { case MSG_TYPE_RPT_DATA_RPT: { DTNMP_DEBUG_ALWAYS("mgr_rx_thread", "Processing a data report.\n\n", NULL); msg_rx_data_rpt(sender_eid, cursor, size, &bytes); cursor += bytes; size -= bytes; } break; case MSG_TYPE_ADMIN_REG_AGENT: { DTNMP_DEBUG_ALWAYS("mgr_rx_thread", "Processing Agent Registration.\n\n", NULL); adm_reg_agent_t *reg = NULL; reg = msg_deserialize_reg_agent(cursor, size, &bytes); cursor += bytes; size -= bytes; mgr_agent_add(reg->agent_id); msg_release_reg_agent(reg); } break; default: { DTNMP_DEBUG_WARN("mgr_rx_thread","Unknown message type: %d", hdr->type); bytes = 0; } break; } #ifdef HAVE_MYSQL if(bytes > 0) { db_incoming_process_message(incoming_idx, cursor - (hdr_len + bytes), hdr_len + bytes); } #endif } #ifdef HAVE_MYSQL db_incoming_finalize(incoming_idx); #endif } } DTNMP_DEBUG_EXIT("mgr_rx_thread","->.", NULL); pthread_exit(NULL); } ion-3.2.0~dfsg1.orig/nm/mgr/nm_mgr_db.c0000644000175000017500000020276312260400056016167 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2011 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** \file nm_mgr_db.c ** ** File Name: nm_mgr_db.c ** ** ** Subsystem: ** Network Manager Daemon: Database Utilities ** ** Description: This file implements the DTNMP Manager interface to a back- ** end SQL database. ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 07/10/13 S. Jacobs Initial Implementation ** 08/19/13 E. Birrane Documentation clean up and code review comments. *****************************************************************************/ #ifdef HAVE_MYSQL #include #include "nm_mgr.h" #include "nm_mgr_db.h" /* Global conngection to the MYSQL Server. */ static MYSQL *gConn; /****************************************************************************** * * \par Function Name: db_add_agent() * * \par Adds a Registered Agent to the database * * \return 0 Failure * !0 Success * * \param[in] agent_eid - The Agent EID being added to the DB. * * \par Notes: * - Only the agent EID is kept in the database, and used as a recipient * ID. No other agent information is persisted at this time. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ uint32_t db_add_agent(eid_t agent_eid) { char query[1024]; /* Step 1: Create Query */ sprintf(query, "INSERT INTO dbtRegisteredAgents(AgentIdSDNV) " "VALUES(%s)", agent_eid.name); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_add_agent", "Database error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_add_agent", "-->0", NULL); return 0; } DTNMP_DEBUG_ERR("db_add_agent", "-->1", NULL); return 1; } /****************************************************************************** * * \par Function Name: db_add_mid * * \par Creates a MID in the database. This function will populate both the * dbtMIDs table and dbtMIDDetails table. * * \retval 0 Failure * >0 The index of the inserted MID from the dbtMIDs table. * * \param[in] attr - DB attribute of the new MID. * \param[in] flag - The flag byte of the new MID. * \param[in] issuer - The issuer, or NULL if no issuer. * \param[in] OID - The serialized OID for the MID. * \param[in] tag - The tag, or NULL if no tag. * \param[in] mib - MIB information for the MID. * \param[in] mib_iso - MIB ISO information for MIS descriptor table. * \param[in] name - MIB item name. * \param[in] descr - MIB item description. * * \par Notes: * - This function allows null names, decriptions, mib and mib_iso * values. However, an OID is required. * - We count duplicate MID and other failures together. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ uint32_t db_add_mid(int attr, uint8_t flag, uvast issuer, char *OID, uvast tag, char *mib, char *mib_iso, char *name, char *descr) { char query[1024]; uint32_t result = 0; char last_insert_id[1024]; DTNMP_DEBUG_ENTRY("db_add_mid", "(%d, %d, %ld, %s, %ld, %s, %s, %s, %s)", attr, flag, (unsigned long) issuer, OID, (unsigned long) tag, mib, mib_iso, name, descr); /* Step 0: Sanity check arguments. */ if(OID == NULL) { DTNMP_DEBUG_ERR("db_add_mid","Can't add mid, bad args",NULL); DTNMP_DEBUG_EXIT("db_add_mid","-->0",NULL); return 0; } /* Step 1: Make sure the ID is not already in the DB. */ if ((result = db_fetch_mid_idx(attr, flag, issuer, OID, tag)) > 0) { DTNMP_DEBUG_WARN("db_add_mid", "Can't add dup. MID (idx is %d).", result); DTNMP_DEBUG_EXIT("db_add_mid", "-->0", NULL); return 0; } /* * Step 2: Build and execute query to add row to dbtMIDs. Also, store the * row ID of the inserted row. */ sprintf(query, "INSERT INTO dbtMIDs \ (Attributes,Type,Category,IssuerFlag,TagFlag,OIDType,IssuerID,OIDValue,TagValue) \ VALUES (%d,b'%d',b'%d',b'%d',b'%d',%d,"UVAST_FIELDSPEC",'%s',"UVAST_FIELDSPEC")", attr, MID_GET_FLAG_TYPE(flag), MID_GET_FLAG_CAT(flag), (MID_GET_FLAG_ISS(flag)) ? 1 : 0, (MID_GET_FLAG_TAG(flag)) ? 1 : 0, MID_GET_FLAG_OID(flag), issuer, (OID == NULL) ? "0" : OID, tag); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_add_mid", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_add_mid", "-->0", NULL); return 0; } if((result = (uint32_t) mysql_insert_id(gConn)) == 0) { DTNMP_DEBUG_ERR("db_add_mid", "Unknown last inserted row.", NULL); DTNMP_DEBUG_EXIT("db_add_mid", "-->0", NULL); return 0; } /* Step 3: Build and execute query to add row to dbtMIDDetails. */ sprintf(query, "INSERT INTO dbtMIDDetails \ (MIDID,MIBName,MIBISO,Name,Description) VALUES \ (%d,'%s','%s','%s','%s')", result, (mib == NULL) ? "" : mib, (mib_iso == NULL) ? "" : mib_iso, (name == NULL) ? "" : name, (descr == NULL) ? "" : descr); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_add_mid", "Database Error: %s", mysql_error(gConn)); /* Step 3.1: If we can't update dbtMIDDetails, remove row from dbtMids */ sprintf(query, "DELETE FROM dbtMIDs WHERE ID=%d", result); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_add_mid", "Can't remove dbtMID row %d as part of rollback.", result); } /* Step 3.2 reset the auto increment to maintain numbering. */ sprintf(query, "ALTER TABLE dbtMIDs AUTO_INCREMENT=%d", result); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_add_mid", "Error resetting auto increment during rollback.", NULL); } } DTNMP_DEBUG_EXIT("db_add_mid", "-->%d", result); return result; } uint32_t db_add_mid_collection(Lyst collection, char *comment) { DTNMP_DEBUG_ERR("db_add_mid_collection", "NOT IMPLEMENTED YET", NULL); return 0; } uint32_t db_add_rpt_data(rpt_data_t *rpt_data) { DTNMP_DEBUG_ERR("db_add_rpt_data", "NOT IMPLEMENTED YET", NULL); return 0; } uint32_t db_add_rpt_defs(rpt_defs_t *defs) { DTNMP_DEBUG_ERR("db_add_rpt_defs", "NOT IMPLEMENTED YET", NULL); return 0; } uint32_t db_add_rpt_items(rpt_items_t *items) { DTNMP_DEBUG_ERR("db_add_rpt_items", "NOT IMPLEMENTED YET", NULL); return 0; } uint32_t db_add_rpt_sched(rpt_prod_t *sched) { DTNMP_DEBUG_ERR("db_add_rpt_sched", "NOT IMPLEMENTED YET", NULL); return 0; } /****************************************************************************** * * \par Function Name: db_fetch_ctrl * * \par Fetches a control structure from the associated controls table. * * \retval NULL Failure * !NULL The built command structure. * * \param[in] id - The Primary Key of the message controls row used to find * the command. * * \par Notes: * * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ ctrl_exec_t *db_fetch_ctrl(int id) { MYSQL_RES *res = NULL; MYSQL_ROW row; char query[1024]; ctrl_exec_t *result = NULL; /* Step 1: Build Query */ sprintf(query, "SELECT * FROM dbtMessagesControls WHERE ID=%d", id); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_ctrl", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_ctrl", "-->NULL", NULL); return NULL; } /* Step 2: Parse the result. */ if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_ctrl", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_ctrl", "-->NULL", NULL); return NULL; } if ((row = mysql_fetch_row(res)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_ctrl", "Unable to find ctrl with ID of %d\n", id); mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_ctrl", "-->NULL",NULL); return NULL; } /* Step 3: Validate and parse the structure. */ int type = atoi(row[1]); if (type != EXEC_CTRL_MSG) { DTNMP_DEBUG_ERR("db_fetch_ctrl", "Bad row type. Expecting %d and got %d\n", EXEC_CTRL_MSG, type); mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_ctrl", "-->NULL",NULL); return NULL; } time_t time = (time_t) atoll(row[2]); Lyst contents = db_fetch_mid_col(atoi(row[6])); if (contents == NULL) { DTNMP_DEBUG_ERR("db_fetch_ctrl", "Can't grab mid col.", NULL); mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_ctrl", "-->NULL",NULL); return NULL; } /* Step 4: Build the control structure. */ result = ctrl_create_exec(time, contents); /* Step 5: Clean up memory. */ mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_ctrl", "-->%llu", (unsigned long)result); return result; } /****************************************************************************** * * \par Function Name: db_fetch_data_col * * \par Creates a data collection from dbtDataCollections in the database * * \retval NULL Failure * !NULL The built Data collection. * * \param[in] id - The Primary Key in the dbtDataCollection table. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/23/13 S. Jacobs Initial implementation, *****************************************************************************/ Lyst db_fetch_data_col(int dc_id) { char query[1024]; MYSQL_RES *res = NULL; MYSQL_ROW row; Lyst result; datacol_entry_t *dc_entry; /* Step 1: Construct/run the Query and capture results. */ sprintf(query, "SELECT * FROM dbtDataCollection WHERE CollectionID=%d", dc_id); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_data_col", "SQL Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_data_col", "-->NULL", NULL); return NULL; } if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_data_col", "SQL Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_data_col", "-->NULL", NULL); return NULL; } /* Step 2: Allocate a Lyst to hold the collection. */ result = lyst_create(); /* Step 3: For each entry returned as part of the collection. */ while ((row = mysql_fetch_row(res)) != NULL) { if((dc_entry = db_fetch_data_col_entry_from_row(row)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_data_col", "Can't get entry.", NULL); utils_datacol_destroy(&result); mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_data_col","-->NULL",NULL); return NULL; } lyst_insert_last(result, dc_entry); } /* Step 4: Free results. */ mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_data_col", "-->%llu", (unsigned long) result); return result; } /******************************************************************************* * * \par Function Name: db_fetch_data_col_entry * * \par Fetches the appropriate data collection entry * * \retval NULL The entry could not be retrieved * !NULL a datacol_entry_t was created * * \param[in] id - The row of the entry * \param[in] order - The order of the entry within a collection (1,2,3...) * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/24/13 S. Jacobs Initial implementation, ******************************************************************************/ datacol_entry_t *db_fetch_data_col_entry(int id, int order) { char query[1024]; MYSQL_RES *res = NULL; MYSQL_ROW row; datacol_entry_t *result = NULL; /* Step 1: Construct and execute query to get the entry data. */ sprintf(query, "SELECT * FROM dbtDataCollection WHERE CollectionID=%d AND DataOrder=%d", id, order); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_data_col_entry", "Database error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetchdata_col_entry", "-->NULL", NULL); return NULL; } if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_data_col_entry", "Database error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetchdata_col_entry", "-->NULL", NULL); return NULL; } if ((row = mysql_fetch_row(res)) != NULL) { if((result = db_fetch_data_col_entry_from_row(row)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_data_col_entry", "Can't get entry.", NULL); } } else { DTNMP_DEBUG_ERR("db_fetch_data_col_entry", "No rows", NULL) } mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_data_col_entry","-->0x%#llx", (unsigned long) result); return result; } /******************************************************************************* * * \par Function Name: db_fetch_data_col_entry_from_row * * \par Parses a data collection entry from a database row from the * dbtataCollection table. * * \retval NULL The entry could not be retrieved * !NULL The created data collection entry. * * \param[in] row - The row containing the data col entry information. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/19/13 E. Birrane Initial implementation, ******************************************************************************/ datacol_entry_t *db_fetch_data_col_entry_from_row(MYSQL_ROW row) { datacol_entry_t *result = NULL; DTNMP_DEBUG_ENTRY("db_fetch_data_col_entry_from_row","(0x%#llx)", (unsigned long) row); /* Step 1: Allocate space for the entry. */ if((result = (datacol_entry_t*) MTAKE(sizeof(datacol_entry_t))) == NULL) { DTNMP_DEBUG_ERR("db_fetch_data_col_entry_from_row", "Can't allocate %d bytes.", sizeof(datacol_entry_t)); DTNMP_DEBUG_EXIT("db_fetch_data_col_entry_from_row", "-->NULL", NULL); return NULL; } /* Step 2: Populate the entry. */ result->length = atoi(row[1]); result->value = (uint8_t*) MTAKE(result->length); if((result->length == 0) || (result->value == 0)) { DTNMP_DEBUG_ERR("db_fetch_data_col_entry_from_row", "length : %lu",result->length); DTNMP_DEBUG_ERR("db_fetch_data_col_entry_from_row", "value : %lu",result->value); MRELEASE(result); DTNMP_DEBUG_EXIT("db_fetch_data_col_entry_from_row", "-->NULL", NULL); return NULL; } memcpy(result->value, row[2], result->length); DTNMP_DEBUG_EXIT("db_fetch_data_col_entry_from_row", "-->%0x#llx", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: db_fetch_def * * \par Creates a def structure from the database. * * \retval NULL Failure * !NULL The built def structure. * * \param[in] id - The Primary Key of the desired def. * * \par Notes: * - We assume, for now, that there is only 1 type of definition * in the table: custom report definitions. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ def_gen_t *db_fetch_def(int id) { def_gen_t *result = NULL; MYSQL_RES *res = NULL; MYSQL_ROW row; char query[1024]; /*Step 1: Construct and run the query to grab the def information. */ sprintf(query, "SELECT * FROM dbtMessagesDefinitions WHERE ID=%d", id); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_def", "Database error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_def", "-->NULL", NULL); return NULL; } if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_def", "Database error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_def", "-->NULL", NULL); return NULL; } /* Step 2: Grab information from the row, if we got a row. */ if ((row = mysql_fetch_row(res)) != NULL) { int mid_id = atoi(row[2]); int mc_id = atoi(row[3]); mid_t *mid = NULL; Lyst contents = NULL; /*Step 2.1: Find the MID identifying the definition. */ if((mid = db_fetch_mid(mid_id)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_def","Cannot fetch mid (%d)",mid_id); } else { /* Step 2.2: Find the Mid Collection for the definition. */ if((contents = db_fetch_mid_col(mc_id)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_def","Cannot fetch MC (%d)",mc_id); } else { /* Step 2.3: Build the definition. */ result = def_create_gen(mid, contents); } } } else { DTNMP_DEBUG_ENTRY("db_fetch_def", "No rows found for %d.", id); } /* Step 3: Free the db result. */ mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_def", "-->%ld", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: db_fetch_mid * * \par Creates a MID structure from a row in the dbtMIDs database. * * \retval NULL Failure * !NULL The built MID structure. * * \param[in] id - The Primary Key of the desired MID in the dbtMIDs table. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ mid_t *db_fetch_mid(int id) { char query[1024]; MYSQL_RES *res = NULL; MYSQL_ROW row; mid_t *result = NULL; DTNMP_DEBUG_ENTRY("db_fetch_mid", "(%d)", id); /* Step 1: Construct and run the query to get the MID information. */ sprintf(query, "SELECT * FROM dbtMIDs WHERE ID=%d", id); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_mid", "Database error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_mid", "-->NULL", NULL); return NULL; } if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_mid", "Database error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_mid", "-->NULL", NULL); return NULL; } /* Step 2: Parse information out of the returned row. */ if ((row = mysql_fetch_row(res)) != NULL) { uint8_t type = (uint8_t) row[2][0]; uint8_t cat = (uint8_t) row[3][0]; uint8_t issFlag = (uint8_t) atoi(row[4]); uint8_t tagFlag = (uint8_t) atoi(row[5]); uint8_t oidType = (uint8_t) row[6][0]; uvast issuer = (uvast) atoll(row[7]); oid_t *oid = db_fetch_oid(id, oidType, row[8]); uvast tag = (uvast) atoll(row[9]); if(oid == NULL) { DTNMP_DEBUG_ERR("db_fetch_mid","Cannot fetch the oid: %s",row[8]); } else { if ((result = mid_construct(type, cat, issFlag ? &issuer : NULL, tagFlag ? &tag : NULL, oid)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_mid", "Cannot construct MID", NULL); } } } else { DTNMP_DEBUG_ERR("db_fetch_mid", "Did not find MID with ID of %d\n", id); } /* Step 3: Free database resources. */ mysql_free_result(res); /* Step 4: Sanity check the returned MID. */ if (mid_sanity_check(result) == 0) { char *data = mid_pretty_print(result); DTNMP_DEBUG_ERR("db_fetch_mid", "Failed MID sanity check. %s", data); MRELEASE(data); mid_release(result); result = NULL; } DTNMP_DEBUG_EXIT("db_fetch_mid", "-->%ld", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: db_fetch_mid_col * * \par Creates a MID collection from a row in the dbtMIDCollection database. * * \retval NULL Failure * !NULL The built MID collection. * * \param[in] id - The Primary Key in the dbtMIDCollection table. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ Lyst db_fetch_mid_col(int id) { Lyst result = lyst_create(); mid_t *new_mid = NULL; char query[1024]; MYSQL_RES *res = NULL; MYSQL_ROW row; /* Step 1: Construct and run the query to get MC DB info. */ sprintf(query, "SELECT MIDID FROM dbtMIDCollection WHERE CollectionID=%d ORDER BY MIDOrder", id); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_mid_col", "SQL Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_mid_col", "-->NULL",NULL); return NULL; } if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_mid_col", "SQL Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_mid_col", "-->NULL", NULL); return NULL; } /* Step 2: For each MID in the collection... */ while ((row = mysql_fetch_row(res)) != NULL) { /* Step 2.1: For each row, build a MID and add it to the collection. */ if((new_mid = db_fetch_mid(atoi(row[0]))) == NULL) { DTNMP_DEBUG_ERR("db_fetch_mid_col", "Can't grab MID with ID %d.", atoi(row[0])); midcol_destroy(&result); mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_mid_col", "-->NULL", NULL); return NULL; } lyst_insert_last(result, new_mid); } /* Step 3: Free database resources. */ mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_mid_col", "-->%d", (unsigned long) result); return result; } /****************************************************************************** * \par Function Name: db_fetch_mid_idx * * \par Gets a MID and returns the index of the MID * *\retval 0 Failure * !0 The index of the MID * * \param[in] attr - the attribute of the MID * \param[in] flag - MID flag byte. * \param[in] issuer - MID issuer * \param[in] OID - MID OID * \param[in] tag - MID tag value. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/23/13 S. Jacobs Initial implementation, *****************************************************************************/ int db_fetch_mid_idx(int attr, uint8_t flag, uvast issuer, char *OID, uvast tag) { char query[1024]; int result = 0; MYSQL_RES *res = NULL; MYSQL_ROW row; /* Step 0: Sanity check arguments. */ if(OID == NULL) { DTNMP_DEBUG_ERR("db_fetch_mid_idx","Can't fetch mid idx, bad args",NULL); return 0; } /* Step 1: Build and execute query. */ sprintf(query, "SELECT * FROM dbtMIDs WHERE \ Attributes=%d AND Type=%d AND Category=%d AND IssuerFlag=%d \ AND TagFlag=%d AND OIDType=%d AND IssuerID="UVAST_FIELDSPEC" AND OIDValue='%s' \ AND TagValue="UVAST_FIELDSPEC, attr, MID_GET_FLAG_TYPE(flag), MID_GET_FLAG_CAT(flag), (MID_GET_FLAG_ISS(flag)) ? 1 : 0, (MID_GET_FLAG_TAG(flag)) ? 1 : 0, MID_GET_FLAG_OID(flag), issuer, (OID == NULL) ? "0" : OID, tag); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_mid_idx", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_mid_idx", "-->%d", result); return result; } /* Step 2: If we found a row, remember the IDX. */ res = mysql_store_result(gConn); if ((row = mysql_fetch_row(res)) != NULL) { result = atoi(row[0]); } else { DTNMP_DEBUG_INFO("db_fetch_mid_idx", "Can't find MID.", NULL); } mysql_free_result(res); /* Step 3: Return the IDX. */ DTNMP_DEBUG_EXIT("db_fetch_mid_idx", "-->%d", result); return result; } /***************************************************************************** * * \par Function Name: db_fetch_oid * * \par Grabs an OID from the database. * * \retval NULL OID could not be fetched * !NULL The OID * * \param[in] mid_id - The id of the MID whose OID is being fetched * \param[in] oid_type - The OID type (full, parm, comp full, comp parm) * \param[out] oid_root - The root OID with any other necessary attachments * * \par Notes: * - Currently, compressed OIDs are not supported. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/25/13 S. Jacobs Initial implementation, ******************************************************************************/ oid_t *db_fetch_oid(int mid_id, int oid_type, char *oid_root) { oid_t *result = NULL; switch (oid_type) { case OID_TYPE_FULL: return db_fetch_oid_full(mid_id, oid_root); break; case OID_TYPE_PARAM: return db_fetch_oid_parms(mid_id, oid_root); break; /* case OID_TYPE_COMP_FULL: oid_root = oid_deserialize_comp(data, size, &bytes); break; case OID_TYPE_COMP_PARAM: oid_root = oid_deserialize_comp_param(data, size, &bytes); break; */ default: DTNMP_DEBUG_ERR("db_fetch_oid", "Unknown OID Type %d", oid_type); break; } return result; } /***************************************************************************** * * \par Function Name: db_fetch_oid_full * * \par Gets the full OID * * \retval NULL OID could not be fetched * !NULL OID found * * \param[in] mid_id - The id of the MID whose OID that is being fetched * \param[in] oid_root - The root OID * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/25/13 S. Jacobs Initial implementation, ******************************************************************************/ oid_t *db_fetch_oid_full(int mid_id, char *oid_root) { oid_t *result = NULL; uint8_t *data = NULL; uint32_t size = 0; uint32_t bytes = 0; DTNMP_DEBUG_ENTRY("db_fetch_oid_full","(%d,%s)", mid_id, oid_root); /* Step 1: Convert the oid_root to hexadecimal. For the full OID, the * root is the entire OID. */ if((data = utils_string_to_hex((unsigned char *) oid_root, &size)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_oid_full","cannot convert to string",NULL); return NULL; } /* Step 2: Deserialize the OID into the OID type structure. */ if((result = oid_deserialize_full(data, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_oid_full","Cannot deserialize oid",NULL); } MRELEASE(data); DTNMP_DEBUG_EXIT("db_fetch_oid_full","-->%llu",(unsigned long) result); return result; } /***************************************************************************** * * \par Function Name: db_fetch_oid_parms * * \par Gets all the parameters for the parameterized OID * * +----------+---------+--------+ +--------+ * | Base OID | # Parms | Parm 1 | ... | Parm N | * | [VAR] | [SDNV] | [DC] | | [DC] | * +----------+---------+--------+ +--------+ * * \retval NULL the parameters could not be fetched * !NULL the parameters where found * * \param[in] mid_id - The id of the MID whose OID that is being fetched * \param[in] oid_root - The root OID which will have the parameters appended * to the end * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/25/13 S. Jacobs Initial implementation, ******************************************************************************/ oid_t *db_fetch_oid_parms(int mid_id, char* oid_root) { oid_t *result = NULL; uint8_t *data = NULL; uint32_t size = 0; uint32_t bytes = 0; uint8_t *parms = NULL; uint32_t parms_size = 0; uint32_t num_parms = 0; DTNMP_DEBUG_ENTRY("db_fetch_oid_parms","(%d, %s)", mid_id, oid_root); /* Step 1: grab the OID parameters String. */ if((parms = db_fetch_parms_str(mid_id, &parms_size, &num_parms)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_oid_parms", "Can't fetch parms string", NULL); return NULL; } /* Step 2: Allocate data to hold everything. */ size = strlen(oid_root) + parms_size; if ((data = (uint8_t *) MTAKE(size)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_oid_parms", "Can't allocate data of size %d", size); MRELEASE(parms); return NULL; } /* Step 3: Copy everything into data. */ uint8_t *cursor = data; uint32_t root_size = 0; uint8_t *root_data = utils_string_to_hex((unsigned char *) oid_root, &root_size); if(root_data == NULL) { DTNMP_DEBUG_ERR("db_fetch_oid_parms","Can't convert %s to hex.", oid_root); MRELEASE(data); MRELEASE(parms); return NULL; } memcpy(cursor, root_data, root_size); cursor += root_size; MRELEASE(root_data); memcpy(cursor, parms, parms_size); cursor += parms_size; /* Step 4: Build OID */ if((result = oid_deserialize_param(data, size, &bytes)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_oid_parms","Cannot deserialize param",NULL); } /* Step 5: Release stuff. */ MRELEASE(data); MRELEASE(parms); DTNMP_DEBUG_EXIT("db_fetch_oid_parms","-->%llu",(unsigned long) result); return result; } /***************************************************************************** * * \par Function Name: db_fetch_parms_str * * \par Gets number of params and the params and turns them into a * string, then serializes the string for the parameterized OID. * * +----------+---------+--------+ +--------+ * | Base OID | # Parms | Parm 1 | ... | Parm N | * | [VAR] | [SDNV] | [DC] | | [DC] | * +----------+---------+--------+ +--------+ * * \retval NULL the parameters could not be fetched * !NULL the parameters where converted into a string * * \param[in] mid_id the id of the MID whose OID that is being fetched * \param[out] parm_size the size of the parms needed to be changed into strings * \param[out] num_parms the total number of parameters * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/25/13 S. Jacobs Initial implementation, *******************************************************************************/ uint8_t *db_fetch_parms_str(int mid_id, uint32_t *parm_size, uint32_t *num_parms) { MYSQL_RES *res = NULL; MYSQL_ROW row; char query[1024]; uint8_t *result = NULL; Lyst parms_datacol; *parm_size = 0; *num_parms = 0; DTNMP_DEBUG_ENTRY("db_fetch_parms_str","(%d, %llu, %llu)", mid_id, (unsigned long) parm_size, (unsigned long) num_parms); /* Step 0: Sanity Check. */ if((parm_size == NULL) || (num_parms == NULL)) { DTNMP_DEBUG_ERR("db_fetch_parms_str","Bad args.", NULL); DTNMP_DEBUG_EXIT("db_fetch_parms_str", "-->NULL", NULL); return NULL; } /*Step 1: Query the data base for the Data Collection. */ sprintf(query, "SELECT DataCollectionID FROM dbtMIDParameterizedOIDs WHERE MIDID=%d", mid_id); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_parms_str", "Database error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_parms_str", "-->NULL", NULL); return NULL; } /*Step 2: Grab the Data Collection ID for the DC holding the parameters.*/ if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_parms_str", "Database error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_parms_str", "-->NULL", NULL); return NULL; } /* Step 3: Grab the data collection representing the parameters. */ if ((row = mysql_fetch_row(res)) != NULL) { int dc_idx = atoi(row[0]); if((parms_datacol = db_fetch_data_col(dc_idx)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_parms_str","Can't fetch data col.",NULL); mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_parms_str", "-->NULL", NULL); return NULL; } } else { DTNMP_DEBUG_ERR("db_fetch_parms_str","MID row was empty: %d",mid_id); mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_parms_str", "-->NULL", NULL); return NULL; } mysql_free_result(res); /* Step 4: Grab number of parameters extracted */ *num_parms = lyst_length(parms_datacol); if(*num_parms == 0) { DTNMP_DEBUG_ERR("db_fetch_parms_str","No parameters found.",NULL); DTNMP_DEBUG_EXIT("db_fetch_parms_str", "-->NULL", NULL); return NULL; } /* Step 5: Serialize the parameters. */ if((result = utils_datacol_serialize(parms_datacol, parm_size)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_parms_str","Could not serialize the parms",NULL); utils_datacol_destroy(&parms_datacol); DTNMP_DEBUG_EXIT("db_fetch_parms_str", "-->NULL", NULL); return NULL; } utils_datacol_destroy(&parms_datacol); DTNMP_DEBUG_EXIT("db_fetch_parms_str", "-->%llu", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: db_fetch_pred_rule * * \par Creates a pred rule structure from the database. * * \retval NULL Failure * !NULL The built pred rule structure. * * \param[in] id - The Primary Key of the desired pred rule. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ rule_pred_prod_t *db_fetch_pred_rule(int id) { rule_pred_prod_t *result = NULL; MYSQL_RES *res = NULL; MYSQL_ROW row; DTNMP_DEBUG_ENTRY("db_fetch_pred_rule", "(%d)", id); DTNMP_DEBUG_ERR("db_fetch_pred_rule", "NOT IMPLEMENTED YET!", NULL); DTNMP_DEBUG_EXIT("db_fetch_pred_rule", "-->%ld", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: db_fetch_reg_agent * * \par Creates an adm_reg_agent_t structure from the database. * * \retval NULL Failure * !NULL The built adm_reg_agent_t structure. * * \param[in] id - The Primary Key of the desired registered agent. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ adm_reg_agent_t *db_fetch_reg_agent(int id) { adm_reg_agent_t *result = NULL; MYSQL_RES *res = NULL; MYSQL_ROW row; char query[1024]; DTNMP_DEBUG_ENTRY("db_fetch_reg_agent","(%d)", id); /*Step 1: Build query. */ sprintf(query, "SELECT * FROM dbtRegisteredAgents WHERE ID=%d", id); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ENTRY("db_fetch_reg_agent", "(%d)", id); DTNMP_DEBUG_EXIT("db_fetch_reg_agent", "-->%ld", (unsigned long) result); return NULL; } /*Step 2: Parse results. */ if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ENTRY("db_fetch_reg_agent", "(%d)", id); DTNMP_DEBUG_EXIT("db_fetch_reg_agent", "-->%ld", (unsigned long) result); return NULL; } if ((row = mysql_fetch_row(res)) != NULL) { eid_t eid; strncpy(eid.name, row[1], MAX_EID_LEN); /* Step 3: Create structure for agent */ if((result = msg_create_reg_agent(eid)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_reg_agent","Cannot create a registered agent",NULL); mysql_free_result(res); return NULL; } } mysql_free_result(res); DTNMP_DEBUG_EXIT("db_fetch_reg_agent", "-->%ld", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: db_fetch_table_type * * \par Returns a value corresponding to a macro for a specific message type * \par UNKNOWN_MSG (0) * \par TIME_PROD_MSG (1) * \par PRED_PROD_MSG (2) * \par EXEC_CTRL_MSG (3) * \par CUST_RPT (4) * * \retval 0 uknown message type. * !0 A specific message type mentioned about. * * \param[in] table_idx - the table the message is located in * \param[in] entry_idx - the row in the table the message will be. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/14/13 S. Jacobs Initial Implementation *****************************************************************************/ int db_fetch_table_type(int table_idx, int entry_idx) { int result = UNKNOWN_MSG; MYSQL_RES *res = NULL; MYSQL_RES *entry_res = NULL; MYSQL_ROW row; MYSQL_ROW entry_row; char query[1024]; DTNMP_DEBUG_ENTRY("db_fetch_table_type","(%d,%d)", table_idx, entry_idx); /* Step 1: Grab the table name associated with this ID. */ sprintf(query, "SELECT TableName from lvtMessageTablesList WHERE ID=%d", table_idx); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_table_type", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_table_type", "-->%d", result); return result; } if ((res = mysql_store_result(gConn)) != NULL) { row = mysql_fetch_row(res); if (strcmp(row[0], "dbtMessagesDefinitions") == 0) { mysql_free_result(entry_res); return CUST_RPT; } else if (strcmp(row[0], "dbtMessagesControls") == 0) { /* See the type from the message controls table. */ sprintf(query, "SELECT TYPE FROM dbtMessagesControls where ID=%d", entry_idx); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_table_type", "Database Error: %s", mysql_error(gConn)); mysql_free_result(entry_res); DTNMP_DEBUG_EXIT("db_fetch_table_type", "-->%d", result); return result; } if ((entry_res = mysql_store_result(gConn)) != NULL) { entry_row = mysql_fetch_row(entry_res); int type = atoi(entry_row[0]); switch (type) { case 1: result = TIME_PROD_MSG; break; case 2: result = PRED_PROD_MSG; break; case 3: result = EXEC_CTRL_MSG; break; default: DTNMP_DEBUG_ERR("db_fetch_table_type", "Unknown type %d", type); } } else { DTNMP_DEBUG_ERR("db_fetch_table_type", "Can't find message control.", NULL); } mysql_free_result(entry_res); } } mysql_free_result(res); return result; } /****************************************************************************** * * \par Function Name: db_fetch_time_rule * * \par Creates a time rule from a row in the database. * * \retval NULL Failure * !NULL The built time rule. * * \param[in] id - The Primary Key of the desired time rule. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ rule_time_prod_t *db_fetch_time_rule(int id) { rule_time_prod_t *result = NULL; char query[1024]; MYSQL_RES *res = NULL; MYSQL_ROW row; DTNMP_DEBUG_ENTRY("db_fetch_time_rule","(%d)", id); /* Step 1: Build the query and execute it. */ sprintf(query, "SELECT * FROM dbtMessagesControls WHERE ID=%d", id); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_fetch_time_rule", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_time_rule", "-->NULL", NULL); return NULL; } /* Step 2: Parse the row and populate the structure. */ if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_fetch_time_rule", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_fetch_time_rule", "-->NULL", NULL); return NULL; } if ((row = mysql_fetch_row(res)) != NULL) { /* Step 2.1: Grab the type and make sure it is correct. */ int type = atoi(row[1]); if (type != TIME_PROD_MSG) { DTNMP_DEBUG_ERR("db_fetch_time_rule", "Bad row type. Expecting 1 and got %d\n", type); } else { time_t time = (time_t) atoll(row[2]); uvast period = (uvast) atoll(row[3]); uvast count = (uvast) atoll(row[5]); Lyst contents = db_fetch_mid_col(atoi(row[6])); if(contents == NULL) { DTNMP_DEBUG_ERR("db_fetch_time_rule","Cannot fetch mid collection",NULL); mysql_free_result(res); return NULL; } result = rule_create_time_prod_entry(time, count, period, contents); if(result == NULL) { DTNMP_DEBUG_ERR("db_fetch_time_rule","Cannot create time_prod_entry",NULL); mysql_free_result(res); return NULL; } } } else { DTNMP_DEBUG_ERR("db_fetch_time_rule", "Unable to find rule with ID of %d\n", id); DTNMP_DEBUG_EXIT("db_fetch_time_rule", "-->%ld", (unsigned long) result); } mysql_free_result(res); /* Step 3: Return the created structure. */ DTNMP_DEBUG_EXIT("db_fetch_time_rule","-->%llu", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: db_incoming_initialize * * \par Returns the id of the last insert into dbtIncoming. * * \retval 0 message was not inserted. * !0 message was inserted into database. * * \param[in] timestamp - the generated timestamp * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/07/13 S. Jacobs Initial implementation, *****************************************************************************/ int db_incoming_initialize(time_t timestamp) { MYSQL_RES *res = NULL; MYSQL_ROW row; char query[1024]; int result = 0; DTNMP_DEBUG_ENTRY("db_incoming_initialize","(%llu)", timestamp); /* Step 1: insert message into dbtIncoming*/ sprintf(query, "INSERT INTO dbtIncoming(ReceivedTS,GeneratedTS,State) " "VALUES(NOW(),%lu,0)", (unsigned long) timestamp); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_incoming_initialize", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_incoming_initialize", "-->%d", result); return 0; } /* Step 2: Get the id of the inserted message*/ sprintf(query, "SELECT LAST_INSERT_ID() FROM dbtIncoming"); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_incoming_initialize", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_incoming_initialize", "-->%d", result); return 0; } /* Step 3: Store the result*/ if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_incoming_initialize", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_incoming_initialize", "-->%d", result); return 0; } if ((row = mysql_fetch_row(res)) != NULL) { result = atoi(row[0]); /* Step 3.1: Update State to ready */ sprintf(query,"UPDATE dbtIncoming SET State = State + 1 WHERE ID = %d",result); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_incoming_initialize", "Database Error: %s", mysql_error(gConn)); mysql_free_result(res); DTNMP_DEBUG_EXIT("db_incoming_initialize", "-->%d", result); return 0; } } mysql_free_result(res); return result; } /****************************************************************************** * * \par Function Name: db_incoming_finalize * * \par Finalize processing of the incoming messages. * * \retval 0 failure * !0 success * * \param[in] id - The incoming message group ID. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/07/13 S. Jacobs Initial implementation, *****************************************************************************/ int db_incoming_finalize(uint32_t id) { char query[1024]; /* Step 1: Update dbtIncoming to processed */ sprintf(query,"UPDATE dbtIncoming SET State = State + 1 WHERE ID = %d", id); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_incoming_finalize", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_incoming_finalize", "-->0", NULL); return 0; } return 1; } /****************************************************************************** * * \par Function Name: db_incoming_process_message * * \par Returns number of incoming message groups. * * \retval 0 no message groups ready. * !0 There are message groups ready. * * \param[in] id - The ID for the incoming message. * \param[in] cursor - Cursor pointing to start of message. * \param[in] size - The size of the incoming message. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/07/13 S. Jacobs Initial implementation, *****************************************************************************/ int db_incoming_process_message(int id, uint8_t *cursor, uint32_t size) { char *query; char *result_data = NULL; if((query = (char *) MTAKE(size * 2 + 256)) == NULL) { DTNMP_DEBUG_ERR("db_incoming_process_message","Can't alloc %d bytes.", size * 2 + 256); DTNMP_DEBUG_EXIT("db_incoming_process_message", "-->0", NULL); return 0; } if((result_data = (char *) MTAKE(size * 2 + 1)) == NULL) { DTNMP_DEBUG_ERR("db_incoming_process_message","Can't alloc %d bytes.", size * 2 + 1); MRELEASE(query); DTNMP_DEBUG_EXIT("db_incoming_process_message", "-->0", NULL); return 0; } mysql_real_escape_string(gConn, result_data, (char *) cursor, size); sprintf(query,"INSERT INTO dbtIncomingMessages(IncomingID,Content)" "VALUES(%d,'%s')",id, result_data); MRELEASE(result_data); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_incoming_process_message", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_incoming_process_message", "-->0", NULL); MRELEASE(query); return 0; } MRELEASE(query); return 1; } /****************************************************************************** * * \par Function Name: db_mgt_daemon * * \par Returns number of outgoing message groups ready to be sent. * * \return Thread Information... * * \param[in] threadId - The POSIX thread. * * \par Notes: * - We are being very inefficient here, as we grab the full result and * then ignore it, presumably to query it again later. We should * optimize this. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/13/13 S. Jacobs Initial implementation, *****************************************************************************/ void *db_mgt_daemon(void * threadId) { MYSQL_RES *sql_res; struct timeval start_time; vast delta = 0; DTNMP_DEBUG_ENTRY("db_mgt_daemon","(0x%#llx)", threadId); DTNMP_DEBUG_ALWAYS("db_mgt_daemon","Starting Manager Database Daemon",NULL); while (g_running) { getCurrentTime(&start_time); if (db_outgoing_ready(&sql_res)) { db_outgoing_process(sql_res); mysql_free_result(sql_res); sql_res = NULL; } delta = utils_time_cur_delta(&start_time); // Sleep for 1 second (10^6 microsec) subtracting the processing time. if((delta < 2000000) && (delta > 0)) { microsnooze((unsigned int)(2000000 - delta)); } } DTNMP_DEBUG_ALWAYS("db_mgt_daemon","Cleaning up Manager Database Daemon", NULL); db_mgt_close(); DTNMP_DEBUG_ALWAYS("db_mgt_daemon","Manager Database Daemon Finished.",NULL); pthread_exit(NULL); } /****************************************************************************** * * \par Function Name: db_mgt_init * * \par Initializes the gConnection to the database. * * \retval 0 Failure * !0 Success * * \param[in] server - The machine hosting the SQL database. * \param[in] user - The username for the SQL database. * \param[in] pwd - The password for this user. * \param[in] database - The database housing the DTNMP tables. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ int db_mgt_init(char *server, char *user, char *pwd, char *database, int clear) { DTNMP_DEBUG_ENTRY("db_mgt_init","(%s, %s, %s, %s, %d)", server, user, pwd, database, clear); gConn = mysql_init(NULL); DTNMP_DEBUG_ENTRY("db_mgt_init", "(%s,%s,%s,%s)", server, user, pwd, database); if (!mysql_real_connect(gConn, server, user, pwd, database, 0, NULL, 0)) { DTNMP_DEBUG_ERR("db_mgt_init", "SQL Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_mgt_init", "-->0", NULL); return 0; } DTNMP_DEBUG_INFO("db_mgt_init", "gConnected to Database.", NULL); if(clear != 0) { db_mgt_clear(); } /* Step 2: Make sure the DB knows about the MIDs we need. */ db_mgt_verify_mids(); DTNMP_DEBUG_EXIT("db_mgt_init", "-->1", NULL); return 1; } /****************************************************************************** * * \par Function Name: db_mgt_clear * * \par Clears all of the database tables used by the DTNMP Management Daemon. * * \retval 0 Failure * !0 Success * * * \todo Add support to clear all tables. Maybe add a parm to select a * table to clear (perhaps a string?) * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ int db_mgt_clear() { DTNMP_DEBUG_ENTRY("db_mgt_clear", "()", NULL); if ((mysql_query(gConn, "TRUNCATE TABLE dbtMIDs")) || (mysql_query(gConn, "TRUNCATE TABLE dbtIncomingMessages")) || (mysql_query(gConn, "TRUNCATE TABLE dbtIncoming")) || (mysql_query(gConn, "TRUNCATE TABLE dbtMessagesDefinitions")) || (mysql_query(gConn, "TRUNCATE TABLE dbtMIDDetails")) || (mysql_query(gConn, "TRUNCATE TABLE dbtMIDCollections")) || (mysql_query(gConn, "TRUNCATE TABLE dbtMIDCollection")) || (mysql_query(gConn, "TRUNCATE TABLE dbtMessagesControls")) || (mysql_query(gConn, "TRUNCATE TABLE dbtOutgoingRecipients")) || (mysql_query(gConn, "TRUNCATE TABLE dbtRegisteredAgents")) || (mysql_query(gConn, "TRUNCATE TABLE dbtMIDParameterizedOIDs")) || (mysql_query(gConn, "TRUNCATE TABLE dbtDataCollections")) || (mysql_query(gConn, "TRUNCATE TABLE dbtDataCollection")) || (mysql_query(gConn, "TRUNCATE TABLE dbtOutgoing")) || (mysql_query(gConn, "TRUNCATE TABLE dbtOutgoingMessages"))) { DTNMP_DEBUG_ERR("db_mgt_clear", "SQL Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_mgt_clear", "--> 0", NULL); return 0; } DTNMP_DEBUG_EXIT("db_mgt_clear", "--> 1", NULL); return 1; } /****************************************************************************** * * \par Function Name: db_mgt_close * * \par Close the database gConnection. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/12/13 S. Jacobs Initial implementation, *****************************************************************************/ void db_mgt_close() { DTNMP_DEBUG_ENTRY("db_mgt_close","()",NULL); mysql_close(gConn); DTNMP_DEBUG_EXIT("db_mgt_close","-->.", NULL); } /****************************************************************************** * * \par Function Name: db_mgt_verify_mids * * \par Adds MIDS to the DB, if necessary, to make sure that dbtMIDs and * dbtMIDDetails contain all MIDs known to this manager. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/13/13 E. Birrane Initial implementation, * 08/01/13 S. Jacobs Reflect Changes in MIDs *****************************************************************************/ void db_mgt_verify_mids() { int i = 0; int size = 0; char *oid_str = NULL; LystElt elt; adm_datadef_t *admData = NULL; DTNMP_DEBUG_ENTRY("db_mgt_verify_mids","()", NULL); /* Step 1: For each ADM item defined... */ for(elt = lyst_first(gAdmData); elt; elt = lyst_next(elt)) { admData = (adm_datadef_t *) lyst_data(elt); mid_t *mid = admData->mid; int attr = 1; uint8_t flags = mid->flags; uvast issuer = mid->issuer; oid_t *oid = mid->oid; char *oid_str = utils_hex_to_string(oid->value, oid->value_size); uvast tag = mid->tag; if(oid_str != NULL) { uint32_t idx = db_add_mid(attr,flags,issuer,&(oid_str[2]),tag,0,0,0,0); MRELEASE(oid_str); } else { DTNMP_DEBUG_ERR("db_mgt_verify_mids", "%s", oid_str); MRELEASE(oid_str); } } DTNMP_DEBUG_EXIT("db_mgt_verify_mid","-->.", NULL); return; } /****************************************************************************** * * \par Function Name: db_outgoing_process * * \par Returns 1 if the message is ready to be sent * * \retval 0 no message groups ready. * !0 There are message groups ready to be sent. * * \param[out] sql_res - The outgoing messages. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/13/13 E. Birrane Initial implementation, * 07/18/13 S. Jacobs Added outgoing agents *****************************************************************************/ int db_outgoing_process(MYSQL_RES *sql_res) { MYSQL_ROW row; pdu_group_t *msg_group = NULL; uint32_t idx = 0; Lyst agents; mid_t *id; def_gen_t *debugPrint; LystElt elt; adm_reg_agent_t *agent_reg = NULL; char query[128]; DTNMP_DEBUG_ENTRY("db_outgoing_process","(0x%#llx)",(unsigned long) sql_res); /* Step 1: For each message group that is ready to go... */ while ((row = mysql_fetch_row(sql_res)) != NULL) { /* Step 1.1 Create and populate the message group. */ idx = atoi(row[0]); if((msg_group = pdu_create_empty_group()) == NULL) { DTNMP_DEBUG_ERR("db_outgoing_process","Cannot create group.", NULL); return 0; } int result = db_outgoing_process_messages(idx, msg_group); if(result != 0) { /* Step 1.2: Collect list of agents receiving the group. */ agents = db_outgoing_process_recipients(idx); if(agents == NULL) { DTNMP_DEBUG_ERR("db_outgoing_process","Cannot process outgoing recipients",NULL); pdu_release_group(msg_group); return 0; } /* Step 1.3: For each agent, send a message. */ for (elt = lyst_first(agents); elt; elt = lyst_next(elt)) { agent_reg = (adm_reg_agent_t *) lyst_data(elt); DTNMP_DEBUG_INFO("db_outgoing_process", "Sending to name %s", agent_reg->agent_id.name); iif_send(&ion_ptr, msg_group, agent_reg->agent_id.name); msg_release_reg_agent(agent_reg); } lyst_destroy(agents); agents = NULL; } else { DTNMP_DEBUG_ERR("db_outgoing_process","Cannot process out going message",NULL); pdu_release_group(msg_group); return 0; } /* Step 1.4: Release the message group. */ pdu_release_group(msg_group); msg_group = NULL; /* Step 1.5: Update the state of the message group in the database. */ sprintf(query, "UPDATE dbtOutgoing SET State=2 WHERE ID=%d", idx); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_outgoing_process", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_outgoing_process", "-->0", NULL); return 0; } } DTNMP_DEBUG_EXIT("db_outgoing_process", "-->1", NULL); return 1; } /****************************************************************************** * * \par Function Name: db_outgoing_process_messages * * \par Returns 1 if the outgoing messages have been processed * * \retval 0 no message groups ready. * !0 There are message groups ready to be sent. * * \param[in] idx - the index of the message that corresponds to outgoing and * outgoing messages * \param[in] msg_group - the group that the message is in. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/13/13 E. Birrane Initial implementation, *****************************************************************************/ int db_outgoing_process_messages(uint32_t idx, pdu_group_t *msg_group) { int result = 0; char query[1024]; MYSQL_RES *res = NULL; MYSQL_ROW row; DTNMP_DEBUG_ENTRY("db_outgoing_process_messages","(%d, 0x%#llx)", idx, (unsigned long) msg_group); /* Step 1: Find all messages for this outgoing group. */ sprintf(query, "SELECT * FROM dbtOutgoingMessages WHERE OutgoingID=%d", idx); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_outgoing_process_messages", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_outgoing_process_messages", "-->%d", result); return result; } /* Step 2: Parse the row and populate the structure. */ while ((res = mysql_store_result(gConn)) != NULL) { row = mysql_fetch_row(res); int table_idx = atoi(row[2]); int entry_idx = atoi(row[3]); if (db_outgoing_process_one_message(table_idx, entry_idx, msg_group, row) == 0) { DTNMP_DEBUG_ERR("db_outgoing_process_messages", "Error processing message.", NULL); result = 0; break; } result = 1; } mysql_free_result(res); return result; } /****************************************************************************** * * \par Function Name: db_outgoing_process_one_message * * \retval 0 no message groups ready. * !0 There are message groups ready to be sent. * * \param[in] table_idx - the index of the table used * \param[in] entry_idx - the row in the table needed * \param[in] message_group - the group name * \param[in] row - a result from a query * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/15/13 E. Birrane Initial implementation, * 07/15/13 S. Jacobs Initial implementation, * 07/16/13 S. Jacobs Added custom report case, *****************************************************************************/ int db_outgoing_process_one_message(uint32_t table_idx, uint32_t entry_idx, pdu_group_t *msg_group, MYSQL_ROW row) { int result = 1; DTNMP_DEBUG_ENTRY("db_outgoing_process_one_message","(%d, %d, 0x%#llx, 0x%#llx)", table_idx, entry_idx, (unsigned long) msg_group, (unsigned long) row); /* * Step 1: Find out what kind of message we have based on the * table that is holding it. */ switch (db_fetch_table_type(table_idx, entry_idx)) { case TIME_PROD_MSG: { rule_time_prod_t *entry = NULL; uint32_t size = 0; uint8_t *data = NULL; pdu_msg_t *pdu_msg = NULL; result = 0; if((entry = db_fetch_time_rule(entry_idx)) != NULL) { if((data = ctrl_serialize_time_prod_entry(entry, &size)) != NULL) { if((pdu_msg = pdu_create_msg(MSG_TYPE_CTRL_PERIOD_PROD, data, size, NULL)) != NULL) { pdu_add_msg_to_group(msg_group, pdu_msg); result = 1; } else { DTNMP_DEBUG_ERR("db_outgoing_process_one_message", "Cannot create msg", NULL); } } else { DTNMP_DEBUG_ERR("db_outgoing_process_one_message", "Cannot serialize time_prod_entry",NULL); } rule_release_time_prod_entry(entry); } else { DTNMP_DEBUG_ERR("db_outgoing_process_one_message","cannot fetch time rule",NULL); } } break; case CUST_RPT: { def_gen_t *entry = NULL; uint32_t size = 0; uint8_t *data = NULL; pdu_msg_t *pdu_msg = NULL; result = 0; if((entry = db_fetch_def(entry_idx)) != NULL) { if((data = def_serialize_gen(entry, &size)) != NULL) { if((pdu_msg = pdu_create_msg(MSG_TYPE_DEF_CUST_RPT, data, size, NULL)) != NULL) { pdu_add_msg_to_group(msg_group, pdu_msg); result = 1; } else { DTNMP_DEBUG_ERR("db_outgoing_process_one_message", "Cannot create msg", NULL); } } else { DTNMP_DEBUG_ERR("db_outgoing_process_one_message", "Cannot serialize def_gen_t",NULL); } def_release_gen(entry); } else { DTNMP_DEBUG_ERR("db_outgoing_process_one_message", "Cannot fetch definition",NULL); } } break; case EXEC_CTRL_MSG: { ctrl_exec_t *entry = NULL; uint32_t size = 0; uint8_t *data = NULL; pdu_msg_t *pdu_msg = NULL; result = 0; if((entry = db_fetch_ctrl(entry_idx)) != NULL) { if((data = ctrl_serialize_exec(entry, &size)) != NULL) { if((pdu_msg = pdu_create_msg(MSG_TYPE_CTRL_EXEC, data, size, NULL)) != NULL) { pdu_add_msg_to_group(msg_group, pdu_msg); result = 1; } else { DTNMP_DEBUG_ERR("db_outgoing_process_one_message","Cannot create msg", NULL); } } else { DTNMP_DEBUG_ERR("db_outgoing_process_one_message","Cannot serialize control",NULL); } ctrl_release_exec(entry); } else { DTNMP_DEBUG_ERR("db_outgoing_process_one_message", "Can't construct control.", NULL); } } break; default: { DTNMP_DEBUG_ERR("db_outgoing_process_one_message", "Unknown table type (%d) entry_idx (%d)", table_idx, entry_idx); } } DTNMP_DEBUG_EXIT("db_outgoing_process_one_message", "-->%d", result); return result; } /****************************************************************************** * * \par Function Name: db_outgoing_process_recipients * * \par Returns a lyst of the agents to send a message to * * \retval 0 no recipients. * !0 There are recipients to be sent to. * * \param[in] outgoingId - The id in the table that holds the receiving agents that * correspond to the id on the outgoing messages * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/18/13 S. Jacobs Initial Implementation *****************************************************************************/ Lyst db_outgoing_process_recipients(uint32_t outgoingId) { Lyst result; MYSQL_RES *res = NULL; MYSQL_ROW row; adm_reg_agent_t *reg_agent = NULL; char query[1024]; int cur_row = 0; int max_row = 0; DTNMP_DEBUG_ENTRY("db_outgoing_process_recipients","(%d)", outgoingId); result = lyst_create(); /* Step 1: Query the database */ sprintf(query, "SELECT AgentID FROM dbtOutgoingRecipients " "WHERE OutgoingID=%d", outgoingId); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_outgoing_process_recipients", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_outgoing_process_recipients", "-->", NULL); return NULL; } /* Step 2: Parse the results and fetch agent */ if((res = mysql_store_result(gConn)) == NULL) { DTNMP_DEBUG_ERR("db_outgoing_process_recipients", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_outgoing_process_recipients", "-->", NULL); return NULL; } /* Step 3: For each row returned.... */ max_row = mysql_num_rows(res); for(cur_row = 0; cur_row < max_row; cur_row++) { if ((row = mysql_fetch_row(res)) != NULL) { /* Step 3.1: Grab the agent information.. */ if((reg_agent = db_fetch_reg_agent(atoi(row[0]))) != NULL) { DTNMP_DEBUG_INFO("db_outgoing_process_recipients", "Adding agent name %s.", reg_agent->agent_id.name); lyst_insert_last(result, reg_agent); } else { DTNMP_DEBUG_ERR("db_outgoing_process_recipients", "Cannot fetch registered agent",NULL); } } } mysql_free_result(res); DTNMP_DEBUG_EXIT("db_outgoing_process_recipients","-->0x%#llx", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: db_outgoing_ready * * \par Returns number of outgoing message groups ready to be sent. * * \retval 0 no message groups ready. * !0 There are message groups ready to be sent. * * \param[out] sql_res - The outgoing messages. * * \par Notes: * - We are being very inefficient here, as we grab the full result and * then ignore it, presumably to query it again later. We should * optimize this. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 07/13/13 E. Birrane Initial implementation, *****************************************************************************/ int db_outgoing_ready(MYSQL_RES **sql_res) { int result = 0; char query[1024]; *sql_res = NULL; DTNMP_DEBUG_ENTRY("db_outgoing_ready","(0x%#llx)", (unsigned long) sql_res); /* Step 0: Sanity check. */ if(sql_res == NULL) { DTNMP_DEBUG_ERR("db_outgoing_ready", "Bad Parms.", NULL); DTNMP_DEBUG_EXIT("db_outgoing_ready","-->0",NULL); return 0; } /* Step 1: Build and execute query. */ sprintf(query, "SELECT * FROM dbtOutgoing WHERE State=%d", TX_READY); if (mysql_query(gConn, query)) { DTNMP_DEBUG_ERR("db_outgoing_ready", "Database Error: %s", mysql_error(gConn)); DTNMP_DEBUG_EXIT("db_outgoing_ready", "-->%d", result); return result; } /* Step 2: Parse the row and populate the structure. */ if ((*sql_res = mysql_store_result(gConn)) != NULL) { result = mysql_num_rows(*sql_res); } else { DTNMP_DEBUG_ERR("db_outgoing_ready", "Database Error: %s", mysql_error(gConn)); } /* Step 3: Return whether we have results waiting. */ DTNMP_DEBUG_EXIT("db_outgoing_ready", "-->%d", result); return result; } #endif // HAVE_MYSQL ion-3.2.0~dfsg1.orig/nm/mgr/nm_mgr_ui.c0000644000175000017500000015276512260400056016225 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2012 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** ** \file nm_mgr_ui.c ** ** ** Description: A text-based DTNMP Manager. ** ** Notes: ** 1. Currently we do not support ACLs. ** 2. Currently we do not support multiple DTNMP Agents. ** 3. When defining new MID, add to list so it can be IDX selected. ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 01/18/13 E. Birrane Code comments and cleanup ** 06/25/13 E. Birrane Removed references to priority field. Add ISS flag. ** 06/25/13 E. Birrane Renamed message "bundle" message "group". *****************************************************************************/ #include "ctype.h" #include "platform.h" #include "shared/utils/utils.h" #include "shared/adm/adm.h" #include "shared/primitives/rules.h" #include "shared/primitives/mid.h" #include "shared/primitives/oid.h" #include "shared/msg/pdu.h" #include "nm_mgr_ui.h" /* #define UI_MAIN_MENU 0 #define UI_DEF_MENU 1 #define UI_CTRL_MENU 2 #define UI_RPT_MENU 3 */ int gContext; /****************************************************************************** * * \par Function Name: ui_build_mid * * \par Builds a MID object from user input. * * \par Notes: * * \retval NULL - Error * !NULL - The constructed MID. * * \param[in] mid_str The user input to define the MID. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ mid_t *ui_build_mid(char *mid_str) { mid_t *result = NULL; uint8_t *tmp = NULL; uint32_t len = 0; uint32_t bytes = 0; adm_datadef_t adu; DTNMP_DEBUG_ENTRY("ui_build_mid","(0x%x)", mid_str); /* Step 0: Sanity check. */ if(mid_str == NULL) { DTNMP_DEBUG_ERR("ui_build_mid","Bad args.", NULL); DTNMP_DEBUG_EXIT("ui_build_mid","->NULL", NULL); return NULL; } /* Step 1: Convert the string into a binary buffer. */ if((tmp = utils_string_to_hex((unsigned char*)mid_str, &len)) == NULL) { DTNMP_DEBUG_ERR("ui_build_mid","Can't Parse MID ID of %s.", mid_str); DTNMP_DEBUG_EXIT("ui_build_mid","->NULL", NULL); return NULL; } /* Step 2: Build an ADU from the buffer. */ // memcpy(adu.mid, tmp, len); // adu.mid_len = len; // MRELEASE(tmp); /* Step 3: Build a mid by "deserializing" the ADU into a MID. */ // result = mid_deserialize((unsigned char*)&(adu.mid),ADM_MID_ALLOC,&bytes); result = mid_deserialize(tmp, len, &bytes); DTNMP_DEBUG_EXIT("ui_build_mid","->0x%x", result); return result; } /****************************************************************************** * * \par Function Name: ui_select_agent * * \par Prompts the user to select a known agent from a list. * * \par Notes: * * \par Returns the selected agent's EID, or NULL if cancelled (or an error occurs). * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 04/18/13 V.Ramachandran Initial implementation * 06/17/13 E. Birrane Working implementation *****************************************************************************/ agent_t* ui_select_agent() { char line[10]; int idx = -1; int total; agent_t *agent = NULL; eid_t *agent_eid; LystElt elt; printf("Select an Agent:"); total = ui_print_agents(); if(ui_get_user_input("Agent (#), or 'x' to cancel:", (char **) &line, 10) == 0) { DTNMP_DEBUG_ERR("ui_select_agent","Unable to read user input.", NULL); DTNMP_DEBUG_EXIT("ui_select_agent","->.", NULL); return NULL; } else if(strcmp(line, "x") == 0) { DTNMP_DEBUG_EXIT("ui_select_agent","->[cancelled]", NULL); return NULL; } sscanf(line, "%d", &idx); if(idx < 0 || idx >= total) { printf("Invalid option.\n"); DTNMP_DEBUG_ALWAYS("ui_select_agent", "User selected invalid option (%d).", idx); DTNMP_DEBUG_EXIT("ui_select_agent", "->NULL", NULL); return NULL; } if(idx == 0) { DTNMP_DEBUG_ALWAYS("ui_select_agent", "User opted to cancel.", NULL); DTNMP_DEBUG_EXIT("ui_select_agent", "->NULL", NULL); return NULL; } idx--; // Switch from 1-index to 0-index. elt = lyst_first(known_agents); if(elt == NULL) { DTNMP_DEBUG_ERR("ui_select_agent","Empty known_agents lyst.", NULL); DTNMP_DEBUG_EXIT("ui_select_agent","->.", NULL); return NULL; } while(idx != 0) { idx--; elt = lyst_next(elt); if(elt == NULL) { DTNMP_DEBUG_ERR("ui_select_agent","Out-of-bounds index in known_agents lyst (%d).", idx); DTNMP_DEBUG_EXIT("ui_select_agent","->.", NULL); return NULL; } } if((agent = (agent_t *) lyst_data(elt)) == NULL) { DTNMP_DEBUG_ERR("ui_select_agent","Null EID in known_agents lyst.", NULL); DTNMP_DEBUG_EXIT("ui_select_agent","->.", NULL); return NULL; } DTNMP_DEBUG_EXIT("ui_select_agent","->%s", agent->agent_eid.name); return agent; } /****************************************************************************** * * \par Function Name: ui_clear_reports * * \par Clears the list of received data reports from an agent. * * \par Notes: * \todo - Add ability to clear reports from a particular agent, or of a * \todo particular type, or for a particular timeframe. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 08/10/11 V.Ramachandran Initial implementation, * 01/18/13 E. Birrane Debug updates. * 04/18/13 V.Ramachandran Multiple-agent support (added param) *****************************************************************************/ void ui_clear_reports(agent_t* agent) { if(agent == NULL) { DTNMP_DEBUG_ENTRY("ui_clear_reports","(NULL)", NULL); DTNMP_DEBUG_ERR("ui_clear_reports", "No agent specified.", NULL); DTNMP_DEBUG_EXIT("ui_clear_reports","->.",NULL); return; } DTNMP_DEBUG_ENTRY("ui_clear_reports","(%s)",agent->agent_eid.name); int num = lyst_length(agent->reports); rpt_clear_lyst(&(agent->reports), NULL, 0); g_reports_total -= num; DTNMP_DEBUG_ALWAYS("ui_clear_reports","Cleared %d reports.", num); DTNMP_DEBUG_EXIT("ui_clear_reports","->.",NULL); } /****************************************************************************** * * \par Function Name: ui_construct_ctrl_by_idx * * \par Constructs a "execute control" message by selecting the control from * a list of controls. Puts the control in a PDU and sends to agent. * * \par Notes: * \todo Add ability to select which agent, and to apply ACL. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation * 04/18/13 V.Ramachandran Multiple-agent support (added param) * 06/25/13 E. Birrane Renamed message "bundle" message "group". *****************************************************************************/ void ui_construct_ctrl_by_idx(agent_t* agent) { char line[256]; uint32_t offset; char mid_str[256]; Lyst mids = lyst_create(); uint32_t size = 0; if(agent == NULL) { DTNMP_DEBUG_ENTRY("ui_construct_ctrl_by_idx","(NULL)", NULL); DTNMP_DEBUG_ERR("ui_construct_ctrl_by_idx", "No agent specified.", NULL); DTNMP_DEBUG_EXIT("ui_construct_ctrl_by_idx","->.",NULL); return; } DTNMP_DEBUG_ENTRY("ui_construct_ctrl_by_idx","(%s)", agent->agent_eid.name); /* Step 0: Read the user input. */ if(ui_get_user_input("Enter ctrl as follows: Offset ", (char **)&line, 256) == 0) { DTNMP_DEBUG_ERR("ui_construct_ctrl_by_idx","Unable to read user input.", NULL); DTNMP_DEBUG_EXIT("ui_construct_ctrl_by_idx","->.", NULL); return; } /* Step 1: Parse the user input. */ sscanf(line,"%d %s", &offset, mid_str); mids = ui_parse_mid_str(mid_str, lyst_length(gAdmCtrls)-1, MID_TYPE_CONTROL); /* Step 2: Construct the control primitive. */ ctrl_exec_t *entry = ctrl_create_exec(offset, mids); /* Step 3: Construct a PDU to hold the primitive. */ uint8_t *data = ctrl_serialize_exec(entry, &size); pdu_msg_t *pdu_msg = pdu_create_msg(MSG_TYPE_CTRL_EXEC, data, size, NULL); pdu_group_t *pdu_group = pdu_create_group(pdu_msg); /* Step 4: Send the PDU. */ iif_send(&ion_ptr, pdu_group, agent->agent_eid.name); /* Step 5: Release remaining resources. */ pdu_release_group(pdu_group); ctrl_release_exec(entry); DTNMP_DEBUG_EXIT("ui_construct_ctrl_by_idx","->.", NULL); } /****************************************************************************** * * \par Function Name: ui_construct_time_rule_by_idx * * \par Constructs a "time production report" control by selecting data from * a list of MIDs. Puts the control in a PDU and sends to agent. * * \par Notes: * \todo Add ability to select which agent, and to apply ACL. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation * 06/25/13 E. Birrane Renamed message "bundle" message "group". *****************************************************************************/ void ui_construct_time_rule_by_idx(agent_t* agent) { char line[256]; time_t offset = 0; uint32_t period = 0; uint32_t evals = 0; char mid_str[256]; Lyst mids = lyst_create(); uint32_t size = 0; if(agent == NULL) { DTNMP_DEBUG_ENTRY("ui_construct_time_rule_by_idx","(NULL)", NULL); DTNMP_DEBUG_ERR("ui_construct_time_rule_by_idx", "Null EID", NULL); DTNMP_DEBUG_EXIT("ui_construct_time_rule_by_idx","->.", NULL); return; } DTNMP_DEBUG_ENTRY("ui_construct_time_rule_by_idx","(%s)", agent->agent_eid.name); /* Step 1: Read and parse the rule. */ if(ui_get_user_input("Enter rule as follows: Offset Period #Evals MID1,MID2,MID3,...,MIDn", (char **) &line, 256) == 0) { DTNMP_DEBUG_ERR("ui_construct_time_rule_by_idx","Unable to read user rule input.", NULL); DTNMP_DEBUG_EXIT("ui_construct_time_rule_by_idx","->.", NULL); return; } sscanf(line,"%ld %d %d %s", &offset, &period, &evals, mid_str); mids = ui_parse_mid_str(mid_str, lyst_length(gAdmData)-1, MID_TYPE_DATA); /* Step 2: Construct the control primitive. */ rule_time_prod_t *entry = rule_create_time_prod_entry(offset, evals, period, mids); /* Step 3: Construct a PDU to hold the primitive. */ uint8_t *data = ctrl_serialize_time_prod_entry(entry, &size); pdu_msg_t *pdu_msg = pdu_create_msg(MSG_TYPE_CTRL_PERIOD_PROD, data, size, NULL); pdu_group_t *pdu_group = pdu_create_group(pdu_msg); /* Step 4: Send the PDU. */ iif_send(&ion_ptr, pdu_group, agent->agent_eid.name); /* Step 5: Release remaining resources. */ pdu_release_group(pdu_group); rule_release_time_prod_entry(entry); DTNMP_DEBUG_EXIT("ui_construct_time_rule_by_idx","->.", NULL); } /****************************************************************************** * * \par Function Name: ui_construct_time_rule_by_mid * * \par Constructs a "time production report" control by building a MID. Put * the control in a PDU and sends to agent. * * \par Notes: * \todo Add ability to select which agent, and to apply ACL. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation * 06/25/13 E. Birrane Renamed message "bundle" message "group". *****************************************************************************/ void ui_construct_time_rule_by_mid(agent_t* agent) { char line[256]; time_t offset = 0; uint32_t period = 0; uint32_t evals = 0; char mid_str[256]; Lyst mids = lyst_create(); mid_t *midp = NULL; uint32_t size = 0; if(agent == NULL) { DTNMP_DEBUG_ENTRY("ui_construct_time_rule_by_mid","(NULL)", NULL); DTNMP_DEBUG_ERR("ui_construct_time_rule_by_mid", "Null EID", NULL); DTNMP_DEBUG_EXIT("ui_construct_time_rule_by_mid","->.", NULL); return; } DTNMP_DEBUG_ENTRY("ui_construct_time_rule_by_mid","(%s)", agent->agent_eid.name); /* Step 0: Read the user input. */ if(ui_get_user_input("Enter rule as follows: Offset Period #Evals MID", (char **) &line, 256) == 0) { DTNMP_DEBUG_ERR("ui_construct_time_rule_by_mid","Unable to read user input.", NULL); DTNMP_DEBUG_EXIT("ui_construct_time_rule_by_mid","->.", NULL); return; } /* Step 1: Parse the user input. */ sscanf(line,"%ld %d %d %s", &offset, &period, &evals, mid_str); midp = ui_build_mid(mid_str); char *str = mid_to_string(midp); printf("MID IS %s\n", str); MRELEASE(str); lyst_insert_last(mids,midp); /* Step 2: Construct the control primitive. */ rule_time_prod_t *entry = rule_create_time_prod_entry(offset, evals, period, mids); /* Step 3: Construct a PDU to hold the primitive. */ uint8_t *data = ctrl_serialize_time_prod_entry(entry, &size); pdu_msg_t *pdu_msg = pdu_create_msg(MSG_TYPE_CTRL_PERIOD_PROD, data, size, NULL); pdu_group_t *pdu_group = pdu_create_group(pdu_msg); /* Step 4: Send the PDU. */ iif_send(&ion_ptr, pdu_group, agent->agent_eid.name); /* Step 5: Release remaining resources. */ pdu_release_group(pdu_group); rule_release_time_prod_entry(entry); DTNMP_DEBUG_EXIT("ui_construct_time_rule_by_mid","->.", NULL); } /****************************************************************************** * * \par Function Name: ui_define_report * * \par Define a custom report and send the definition to the agent. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation * 06/25/13 E. Birrane Renamed message "bundle" message "group". *****************************************************************************/ void ui_define_report(agent_t* agent) { mid_t *new_id = NULL; char line[256]; char mid_str[256]; Lyst mids; def_gen_t *rpt_def = NULL; uint32_t size = 0; if(agent == NULL) { DTNMP_DEBUG_ENTRY("ui_define_report","(NULL)", NULL); DTNMP_DEBUG_ERR("ui_define_report", "Null EID", NULL); DTNMP_DEBUG_EXIT("ui_define_report","->.", NULL); return; } DTNMP_DEBUG_ENTRY("ui_define_report","(%s)", agent->agent_eid.name); /* Step 0: Grab the identifier for the new report. */ new_id = ui_input_mid(); /* Step 1:Grab the MID list defining the report. */ if(ui_get_user_input("MIDS comprising this report: IDX1,IDX2,...,IDX_N", (char **)&line, 256) == 0) { DTNMP_DEBUG_ERR("ui_define_report","Unable to read user input.", NULL); DTNMP_DEBUG_EXIT("ui_define_report","->.", NULL); return; } /* Step 1: Parse the user input. */ sscanf(line,"%s", mid_str); mids = ui_parse_mid_str(mid_str, lyst_length(gAdmData)-1, MID_TYPE_DATA); /* Step 2: Construct the control primitive. */ rpt_def = def_create_gen(new_id, mids); /* Step 3a: Record this definition in the agent def lyst. */ lockResource(&(agent->mutex)); lyst_insert_last(agent->custom_defs, rpt_def); lockResource(&(agent->mutex)); /* Step 4: Construct a PDU to hold the primitive. */ uint8_t *data = def_serialize_gen(rpt_def, &size); pdu_msg_t *pdu_msg = pdu_create_msg(MSG_TYPE_DEF_CUST_RPT, data, size, NULL); pdu_group_t *pdu_group = pdu_create_group(pdu_msg); /* Step 5: Send the PDU. */ iif_send(&ion_ptr, pdu_group, agent->agent_eid.name); /* Step 6: Release remaining resources. */ pdu_release_group(pdu_group); /* * Remember, we do not free the report definition because we added it * to the list of local custom definitions for this agent. */ DTNMP_DEBUG_EXIT("ui_define_report","->.", NULL); } /****************************************************************************** * * \par Function Name: ui_define_macro * * \par Define a custom macro and send the definition to the agent. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/22/13 E. Birrane Initial Implementation * 06/25/13 E. Birrane Renamed message "bundle" message "group". *****************************************************************************/ void ui_define_macro(agent_t* agent) { mid_t *new_id = NULL; char line[256]; char mid_str[256]; Lyst mids; def_gen_t *macro_def = NULL; uint32_t size = 0; /* Step 0: Grab the identifier for the new macro. */ new_id = ui_input_mid(); /* Step 1:Grab the MID list defining the macro. */ if(ui_get_user_input("Controls comprising this macro: IDX1,IDX2,...,IDX_N", (char **)&line, 256) == 0) { DTNMP_DEBUG_ERR("ui_define_macro","Unable to read user input.", NULL); DTNMP_DEBUG_EXIT("ui_define_macro","->.", NULL); return; } /* Step 1: Parse the user input. */ sscanf(line,"%s", mid_str); mids = ui_parse_mid_str(mid_str, lyst_length(gAdmCtrls)-1, MID_TYPE_DATA); /* Step 2: Construct the control primitive. */ macro_def = def_create_gen(new_id, mids); /* Step 3: Remember this definition for future use. */ lockResource(¯o_defs_mutex); lyst_insert_last(macro_defs, macro_def); unlockResource(¯o_defs_mutex); /* Step 4: Construct a PDU to hold the primitive. */ uint8_t *data = def_serialize_gen(macro_def, &size); pdu_msg_t *pdu_msg = pdu_create_msg(MSG_TYPE_DEF_MACRO, data, size, NULL); pdu_group_t *pdu_group = pdu_create_group(pdu_msg); /* Step 5: Send the PDU. */ iif_send(&ion_ptr, pdu_group, agent->agent_eid.name); /* Step 6: Release remaining resources. */ pdu_release_group(pdu_group); DTNMP_DEBUG_EXIT("ui_define_report","->.", NULL); } /****************************************************************************** * * \par Function Name: ui_define_mid_params * * \par Allows user to input MID parameters. * * \par Notes: * \todo Find a way to name each parameter. * * \param[in] name The name of the MID needing parameters. * \param[out] num_parms The number of parameters needed. * \param[out] mid The augmented MID. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ void ui_define_mid_params(char *name, int num_parms, mid_t *mid) { char mid_str[256]; char line[256]; int cmdFile = fileno(stdin); int len = 0; int i = 0; uint32_t size = 0; DTNMP_DEBUG_ENTRY("ui_define_mid_params", "(0x%x, %d, 0x%x)", (unsigned long) name, num_parms, (unsigned long) mid); if((name == NULL) || (mid == NULL)) { DTNMP_DEBUG_ERR("ui_define_mid_params", "Bad Args.", NULL); DTNMP_DEBUG_EXIT("ui_define_mid_params","->.", NULL); return; } printf("MID %s needs %d parameters.\n", name, num_parms); for(i = 0; i < num_parms; i++) { printf("Enter Parm %d:\n",i); if (igets(cmdFile, (char *)line, (int) sizeof(line), &len) == NULL) { if (len != 0) { DTNMP_DEBUG_ERR("ui_define_mid_params","igets failed.", NULL); DTNMP_DEBUG_EXIT("ui_define_mid_params","->.", NULL); return; } } sscanf(line,"%s", mid_str); //result = utils_string_to_hex((unsigned char*) mid_str, &size); size = strlen(mid_str); mid_add_param(mid, (unsigned char*)mid_str, size); } DTNMP_DEBUG_EXIT("ui_define_mid_params","->.", NULL); } /****************************************************************************** * * \par Function Name: ui_register_agent * * \par Register a new agent. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 04/18/13 V.Ramachandran Initial Implementation *****************************************************************************/ void ui_register_agent() { char line[MAX_EID_LEN]; eid_t agent_eid; agent_t *agent; DTNMP_DEBUG_ENTRY("register_agent", "()", NULL); /* Grab the new agent's EID. */ if(ui_get_user_input("Enter EID of new agent:", (char **)&line, MAX_EID_LEN) == 0) { DTNMP_DEBUG_ERR("register_agent","Unable to read user input.", NULL); DTNMP_DEBUG_EXIT("register_agent","->.", NULL); return; } else DTNMP_DEBUG_INFO("register_agent", "User entered agent EID name %s", line); /* Check if the agent is already known. */ sscanf(line, "%s", agent_eid.name); mgr_agent_add(agent_eid); DTNMP_DEBUG_EXIT("register_agent", "->.", NULL); } /****************************************************************************** * * \par Function Name: ui_deregister_agent * * \par Remove and deallocate an agent. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 04/23/13 V.Ramachandran Initial Implementation *****************************************************************************/ void ui_deregister_agent(agent_t* agent) { char line[MAX_EID_LEN]; DTNMP_DEBUG_ENTRY("ui_deregister_agent","(%llu)", (unsigned long)agent); if(agent == NULL) { DTNMP_DEBUG_ERR("ui_deregister_agent", "No agent specified.", NULL); DTNMP_DEBUG_EXIT("ui_deregister_agent","->.",NULL); return; } DTNMP_DEBUG_ENTRY("ui_deregister_agent","(%s)",agent->agent_eid.name); lockResource(&agents_mutex); if(mgr_agent_remove(&(agent->agent_eid)) != 0) { DTNMP_DEBUG_WARN("ui_deregister_agent","No agent by that name is currently registered.\n", NULL); } else { DTNMP_DEBUG_ALWAYS("ui_deregister_agent","Successfully deregistered agent.\n", NULL); } unlockResource(&agents_mutex); } /****************************************************************************** * * \par Function Name: ui_eventLoop * * \par Main event loop for the UI thread. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ void ui_eventLoop() { int cmdFile = fileno(stdin); char choice[3]; int len; /* #define UI_MAIN_MENU 0 #define UI_DEF_MENU 1 #define UI_CTRL_MENU 2 #define UI_RPT_MENU 3 */ int gContext = UI_MAIN_MENU; while(g_running) { switch(gContext) { case UI_MAIN_MENU: ui_print_menu_main(); break; case UI_ADMIN_MENU: ui_print_menu_admin(); break; case UI_DEF_MENU: ui_print_menu_def(); break; case UI_CTRL_MENU: ui_print_menu_ctrl(); break; case UI_RPT_MENU: ui_print_menu_rpt(); break; default: printf("Error. Unknown menu context.\n"); break; } if ((igets(cmdFile, (char *)choice, (int) sizeof(choice), &len) != NULL) && (len > 0)) { char cmd = toupper(choice[0]); switch(gContext) { case UI_MAIN_MENU: switch(cmd) { case '1' : gContext = UI_ADMIN_MENU; break; case '2' : gContext = UI_DEF_MENU; break; case '3' : gContext = UI_RPT_MENU; break; case '4' : gContext = UI_CTRL_MENU; break; case '5' : exit(1); break; default: printf("Unknown command.\n");break; } break; case UI_ADMIN_MENU: switch(cmd) { case '0' : gContext = UI_MAIN_MENU; break; case '1' : ui_register_agent(); break; case '2' : ui_print_agents(); break; case '3' : ui_deregister_agent(ui_select_agent()); break; default: printf("Unknown command.\n"); break; } break; case UI_DEF_MENU: switch(cmd) { // Custom Reports //case '1' : ui_print_custom_rpt_def(); break; // List Mgr Custom Rpt Def. case '2' : ui_define_report(ui_select_agent()); break; // Define Custom Report //case '3' : ui_print_cust_rpt_by_idx(); break; // Identify custom report by idx. //case '4' : ui_clear_cust_rpt_by_idx(); break; // Remove custom rept using index. // Computed Data //case '5' : ui_print_comp_data_def(); break; // List Computed Data Def //case '6' : ui_define_comp_data(); break; // Define Computed Data //case '7' : ui_print_comp_data_by_idx(); break; // Identify computed data by idx. //case '8' : ui_clear_comp_data_by_idx(); break; // Remove computed data using index. // Macro //case '9' : ui_print_macro_def(); break; // List Macro Def case 'A' : ui_define_macro(ui_select_agent()); break; // Define Macro //case 'B' : ui_print_macro_by_idx(); break; // Identify macro by idx. //case 'C' : ui_clear_macro_by_idx(); break; // Remove macro using index. case 'D' : gContext = UI_MAIN_MENU; break; default: printf("Unknown command.\n"); break; } break; case UI_CTRL_MENU: switch(cmd) { //case '1' : ui_print_adms(); break; // List supported ADMs case '2' : ui_print_mids(); break; // List Data MIDS by Index case '3' : ui_print_ctrls(); break; // List Control MIDs by Index //case '4' : ui_print_literals(); break; // List Literal MIDs by Index //case '5' : ui_print_operators(); break; // List Operator MIDs by Index // time based production case '6' : ui_construct_time_rule_by_idx(ui_select_agent()); break; // Construct from indices case '7' : ui_construct_time_rule_by_mid(ui_select_agent()); break; // Construct from user-input MID //case '8' : ui_cancel_time_rule_by_idx(); break; // Cancel sent production // Content-Based Production //case '9' : ui_construct_pred_rule_by_idx(); break; // Construct from indices //case 'A' : ui_construct_pred_rule_by_mid(); break; // Construct from user-input MID //case 'B' : ui_cancel_pred_rule_by_idx(); break; // Cancel sent production // Perform Control case 'C' : ui_construct_ctrl_by_idx(ui_select_agent()); break; // Construct from indices //case 'D' : ui_construct_ctrl_by_mid(); break; // Construct user-input MID //case 'E' : ui_print_sent_ctrls(); break; // List Sent Controls //case 'F' : ui_cancel_ctrl_by_idx(); break; // Cancel Sent Control by Idx case 'G' : gContext = UI_MAIN_MENU; break; default: printf("Unknown command.\n"); break; } break; case UI_RPT_MENU: switch(cmd) { // Data List //case '1' : ui_print_agent_comp_data_def(); break; // LIst agent computed data defs // Definitions List //case '2' : ui_print_agent_cust_rpt_defs(); break; // List agent custom report defs //case '3' : ui_print_agent_macro_defs(); break; // LIst agent macro defs. // Report List case '4' : ui_print_reports(ui_select_agent()); break; // Print received reports. case '5' : ui_clear_reports(ui_select_agent()); break; // Clear received reports. // Production Schedules. //case '6' : ui_print_agent_prod_rules(); break; // List agent production rules. case '7' : gContext = UI_MAIN_MENU; break; default: printf("Unknown command.\n"); break; } break; default: printf("Error. Unknown menu context.\n"); break; } } } } /****************************************************************************** * * \par Function Name: ui_get_user_input * * \par Read a line of input from the user. * * \par Notes: * * \retval 0 - Could not get user input. * 1 - Got user input. * * \param[in] prompt The prompt to the user. * \param[out] line The line of text read from the user. * \param [in] max_len The maximum size of the line. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ int ui_get_user_input(char *prompt, char **line, int max_len) { int len = 0; DTNMP_DEBUG_ENTRY("ui_get_user_input","(%s,0x%x,%d)",prompt, *line, max_len); while(len == 0) { printf("Note: Only the first %d characters will be read.\n%s\n", max_len, prompt); if (igets(fileno(stdin), (char *)line, max_len, &len) == NULL) { if (len != 0) { DTNMP_DEBUG_ERR("ui_get_user_input","igets failed.", NULL); DTNMP_DEBUG_EXIT("ui_get_user_input","->0.",NULL); return 0; } } } DTNMP_DEBUG_INFO("ui_get_user_input","Read user input.", NULL); DTNMP_DEBUG_EXIT("ui_get_user_input","->1.",NULL); return 1; } /****************************************************************************** * * \par Function Name: ui_input_mid * * \par Construct a MID object completely from user input. * * \par Notes: * * \retval NULL - Problem building the MID. * !NULL - The constructed MID. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation * 06/25/13 E. Birrane Removed references to priority field. Add ISS flag. *****************************************************************************/ mid_t *ui_input_mid() { uint8_t flag; char line[256]; uint32_t size = 0; uint8_t *data = NULL; mid_t *result = NULL; uint32_t bytes = 0; /* Step 0: Allocate the resultant MID. */ if((result = (mid_t*)MTAKE(sizeof(mid_t))) == NULL) { DTNMP_DEBUG_ERR("ui_input_mid","Can't alloc %d bytes.", sizeof(mid_t)); DTNMP_DEBUG_EXIT("ui_input_mid", "->NULL.", NULL); return NULL; } else { memset(result,0,sizeof(mid_t)); } /* Step 1: Get the MID flag. */ ui_input_mid_flag(&(result->flags)); result->type = MID_GET_FLAG_TYPE(result->flags); result->category = MID_GET_FLAG_CAT(result->flags); /* Step 2: Grab Issuer, if necessary. */ if(MID_GET_FLAG_ISS(result->flags)) { ui_get_user_input("Issuer (up to 18 hex): 0x", (char**)&line, 256); data = utils_string_to_hex((unsigned char*)line, &size); memcpy(&(result->issuer), data, 4); MRELEASE(data); if(size > 4) { DTNMP_DEBUG_ERR("ui_input_mid", "Issuer too big: %d.", size); DTNMP_DEBUG_EXIT("ui_input_mid","->NULL.", NULL); mid_release(result); return NULL; } } /* Step 3: Grab the OID. */ ui_get_user_input("OID: 0x", (char**)&line, 256); data = utils_string_to_hex((unsigned char *)line, &size); result->oid = NULL; switch(MID_GET_FLAG_OID(result->flags)) { case OID_TYPE_FULL: result->oid = oid_deserialize_full(data, size, &bytes); printf("OID value size is %d\n", result->oid->value_size); break; case OID_TYPE_PARAM: result->oid = oid_deserialize_param(data, size, &bytes); break; case OID_TYPE_COMP_FULL: result->oid = oid_deserialize_comp(data, size, &bytes); break; case OID_TYPE_COMP_PARAM: result->oid = oid_deserialize_comp_param(data, size, &bytes); break; default: DTNMP_DEBUG_ERR("ui_input_mid","Unknown OID Type %d", MID_GET_FLAG_OID(result->flags)); break; } MRELEASE(data); if((result->oid == NULL) || (bytes != size)) { DTNMP_DEBUG_ERR("ui_input_mid", "Bad OID. Size %d. Bytes %d.", size, bytes); mid_release(result); DTNMP_DEBUG_EXIT("ui_input_mid","->NULL.", NULL); return NULL; } /* Step 4: Grab a tag, if one exists. */ if(MID_GET_FLAG_TAG(result->flags)) { ui_get_user_input("Tag (up to 18 hex): 0x", (char**)&line, 256); data = utils_string_to_hex((unsigned char*)line, &size); memcpy(&(result->tag), data, 4); MRELEASE(data); if(size > 4) { DTNMP_DEBUG_ERR("ui_input_mid", "Tag too big: %d.", size); DTNMP_DEBUG_EXIT("ui_input_mid","->NULL.", NULL); mid_release(result); return NULL; } } mid_internal_serialize(result); /* Step 5: Sanity check this mid. */ if(mid_sanity_check(result) == 0) { DTNMP_DEBUG_ERR("ui_input_mid", "Sanity check failed.", size); DTNMP_DEBUG_EXIT("ui_input_mid","->NULL.", NULL); mid_release(result); return NULL; } char *mid_str = mid_to_string(result); DTNMP_DEBUG_ALWAYS("ui_input_mid", "Defined MID: %s", mid_str); MRELEASE(mid_str); DTNMP_DEBUG_EXIT("ui_input_mid", "->0x%x", (unsigned long) result); return result; } /****************************************************************************** * * \par Function Name: ui_input_mid_flag * * \par Construct a MID flag byte completely from user input. * * \par Notes: * * \retval 0 - Can't construct flag byte * 1 - Flag byte constructed * * \param[out] flag The resulting flags * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation * 06/25/13 E. Birrane Removed references to priority field.Add ISS Flag. *****************************************************************************/ int ui_input_mid_flag(uint8_t *flag) { int result = 0; char line[256]; int tmp; *flag = 0; ui_get_user_input("Type: Data (0), Ctrl (1), Literal (2), Op (3):", (char**)&line, 256); sscanf(line,"%d",&tmp); *flag = (tmp & 0x3); ui_get_user_input("Cat: Atomic (0), Computed (1), Collection (2):", (char**)&line, 256); sscanf(line,"%d",&tmp); *flag |= (tmp & 0x3) << 2; ui_get_user_input("Issuer Field Present? Yes (1) No (0):", (char**)&line, 256); sscanf(line,"%d",&tmp); *flag |= (tmp & 0x1) << 4; ui_get_user_input("Tag Field Present? Yes (1) No (0):", (char**)&line, 256); sscanf(line,"%d",&tmp); *flag |= (tmp & 0x1) << 5; ui_get_user_input("OID Type: Full (0), Parm (1), Comp (2), Parm+Comp(3):", (char**)&line, 256); sscanf(line,"%d",&tmp); *flag |= (tmp & 0x3) << 6; printf("Constructed Flag Byte: 0x%x\n", *flag); return 1; } /****************************************************************************** * * \par Function Name: ui_parse_mid_str * * \par Convert a series of MID indices into a lyst of actual MID objects. * * \par Notes: * * \retval NULL - Problem parsing MIDs. * !NULL - The list of MIDs * * \param[in] mid_str String of MID indices. * \param[in] max_idx The largest valid MID idx. * \param[in] type Type of MID being indexed. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ Lyst ui_parse_mid_str(char *mid_str, int max_idx, int type) { char *cur_mid = NULL; char *tmp = NULL; int cur_mid_idx = 0; uint32_t mid_size = 0; Lyst mids = NULL; DTNMP_DEBUG_ENTRY("ui_parse_mid_str","(0x%x)",mid_str); /* Step 0: Sanity Check. */ if(mid_str == NULL) { DTNMP_DEBUG_ERR("ui_parse_mid_str","Bad args.", NULL); DTNMP_DEBUG_EXIT("ui_parse_mid_str","->NULL.", NULL); return NULL; } mids = lyst_create(); /* Step 1: Walk through each MID */ for(cur_mid = strtok_r(mid_str, ", ", &tmp); cur_mid != NULL; cur_mid = strtok_r(NULL, ", ", &tmp)) { DTNMP_DEBUG_INFO("ui_parse_mid_str","Read MID index of %s", cur_mid); /* Step 1a. Convert and check MID index. */ if((cur_mid_idx = atoi(cur_mid)) <= max_idx) { uint32_t bytes = 0; mid_t *midp = NULL; char *name = NULL; int num_parms = 0; int mid_len = 0; /* Step 1b: Grab MID and put it into the list. */ switch(type) { case MID_TYPE_DATA: { adm_datadef_t *cur = adm_find_datadef_by_idx(cur_mid_idx); midp = mid_copy(cur->mid); num_parms = cur->num_parms; /*** name = adus[cur_mid_idx].name; num_parms = adus[cur_mid_idx].num_parms; mid_len = adus[cur_mid_idx].mid_len; midp = mid_deserialize((unsigned char*)&(adus[cur_mid_idx].mid), adus[cur_mid_idx].mid_len,&bytes); */ } break; case MID_TYPE_CONTROL: { adm_ctrl_t *cur = adm_find_ctrl_by_idx(cur_mid_idx); midp = mid_copy(cur->mid); num_parms = cur->num_parms; /** name = ctrls[cur_mid_idx].name; num_parms = ctrls[cur_mid_idx].num_parms; mid_len = ctrls[cur_mid_idx].mid_len; midp = mid_deserialize((unsigned char*)&(ctrls[cur_mid_idx].mid), ctrls[cur_mid_idx].mid_len,&bytes); **/ } break; case MID_TYPE_LITERAL: /* \todo: Write this. */ case MID_TYPE_OPERATOR: /* \todo: Write this. */ default: DTNMP_DEBUG_ERR("ui_parse_mid_str","Unknown type %d", type); DTNMP_DEBUG_EXIT("ui_parse_mid_str","->NULL.",NULL); lyst_destroy(mids); return NULL; } /* If this MID has parameters, get them from the user. */ if(num_parms > 0) { ui_define_mid_params(name, num_parms, midp); mid_internal_serialize(midp); } mid_size += mid_len; lyst_insert_last(mids, midp); } else { DTNMP_DEBUG_ERR("ui_parse_mid_str", "Bad MID index: %d. Max is %d. Skipping.", cur_mid_idx, max_idx); } } DTNMP_DEBUG_EXIT("ui_parse_mid_str","->0x%x.", mids); return mids; } /****************************************************************************** * * \par Function Name: ui_print_agents * * \par Prints list of known agents * * \par Returns number of agents * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 04/18/13 V.Ramachandran Initial Implementation *****************************************************************************/ int ui_print_agents() { int i = 1; LystElt element; DTNMP_DEBUG_ENTRY("ui_print_agents","()",NULL); printf("\n------------- Known Agents --------------\n"); element = lyst_first(known_agents); if(element == NULL) { printf("[None]\n"); } while(element != NULL) { printf("%d) %s\n", i++, (char *) lyst_data(element)); element = lyst_next(element); } printf("\n------------- ************ --------------\n"); printf("\n"); DTNMP_DEBUG_EXIT("ui_print_agents","->%d", (i-1)); return i; } /****************************************************************************** * * \par Function Name: ui_print_ctrls * * \par Prints list of configured controls and their associated index * * \par Notes: * 1. Assuming 80 column display, 2 column are printed of length 40 each. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ void ui_print_ctrls() { int i = 0; int num_full_rows = 0; int num_rows = 0; LystElt elt = 0; adm_ctrl_t *cur = NULL; DTNMP_DEBUG_ENTRY("ui_print_ctrls","()",NULL); num_full_rows = (int) (lyst_length(gAdmCtrls) / 2); for(elt = lyst_first(gAdmCtrls); elt; elt = lyst_next(elt)) { cur = (adm_ctrl_t*) lyst_data(elt); printf("%3d) %-35s ", i, cur->name); i++; if(num_rows < num_full_rows) { elt = lyst_next(elt); cur = (adm_ctrl_t*) lyst_data(elt); printf("%3d) %-35s\n", i, cur->name); i++; } else { printf("\n\n\n"); } num_rows++; } DTNMP_DEBUG_EXIT("ui_print_ctrls","->.", NULL); } /****************************************************************************** * * \par Function Name: ui_print_custom_rpt * * \par Prints a custom report received by a DTNMP Agent. * * \par Notes: * * \param[in] rpt_entry The entry containing the report data to print. * \param[in] rpt_def The static definition of the report. * * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ void ui_print_custom_rpt(rpt_data_entry_t *rpt_entry, def_gen_t *rpt_def) { LystElt elt; uint64_t idx = 0; mid_t *cur_mid = NULL; adm_datadef_t *adu = NULL; uint64_t data_used; for(elt = lyst_first(rpt_def->contents); elt; elt = lyst_next(elt)) { char *mid_str; cur_mid = (mid_t*)lyst_data(elt); mid_str = mid_to_string(cur_mid); if((adu = adm_find_datadef(cur_mid)) != NULL) { DTNMP_DEBUG_INFO("ui_print_custom_rpt","Printing MID %s", mid_str); ui_print_predefined_rpt(cur_mid, (uint8_t*)&(rpt_entry->contents[idx]), rpt_entry->size - idx, &data_used, adu); idx += data_used; } else { DTNMP_DEBUG_ERR("ui_print_custom_rpt","Unable to find MID %s", mid_str); } MRELEASE(mid_str); } } void ui_print_menu_admin() { printf("============ Administration Menu =============\n"); printf("\n------------ Agent Registration ------------\n"); printf("1) Register Agent.\n"); printf("2) List Registered Agent.\n"); printf("3) De-Register Agent.\n"); printf("\n------------ Reporting Policies ------------\n"); printf("\n-------------- Status Message --------------\n"); printf("X) Not Implemented.\n"); printf("\n--------------------------------------------\n"); printf("0) Return to Main Menu.\n"); } void ui_print_menu_ctrl() { printf("=============== Controls Menu ================\n"); printf("\n------------- ADM Information --------------\n"); printf("1) List supported ADMs.\n"); printf("2) List Data MIDs by Index. (%ld MIDs)\n", lyst_length(gAdmData)); printf("3) List Control MIDs by Index. (%ld MIDs)\n", lyst_length(gAdmCtrls)); printf("4) List Literal MIDs by Index. (%ld MIDs)\n", lyst_length(gAdmLiterals)); printf("5) List Operator MIDs by Index. (%ld MIDs)\n", lyst_length(gAdmOps)); printf("\n---------- Time-Based Production -----------\n"); printf("6) Construct from indices.\n"); printf("7) Construct from user-input MID.\n"); printf("8) Cancel Sent Production.\n"); printf("\n--------- Content-Based Production ---------\n"); printf("X) Construct from indices.\n"); printf("X) Construct from user-input MID.\n"); printf("X) Cancel Sent Production.\n"); printf("\n-------------- Perform Control -------------\n"); printf("C) Construct from indices.\n"); printf("D) Construct from user-input MID.\n"); printf("E) List Sent Controls.\n"); printf("F) Cancel Sent Control by index.\n"); printf("\n--------------------------------------------\n"); printf("G) Return to Main Menu.\n"); } void ui_print_menu_def() { printf("============== Definitions Menu ==============\n"); printf("\n-------------- Custom Reports --------------\n"); printf("1) List Manager Custom Report Definitions.\n"); printf("2) Define Custom Report.\n"); printf("3) Identify Custom Report Using Index.\n"); printf("4) Remove Custom Report Using Index.\n"); printf("\n--------------- Computed Data --------------\n"); printf("5) List Manager Computed Data Definitions.\n"); printf("6) Define Computed Data.\n"); printf("7) Identify Computed Data Using Index.\n"); printf("8) Remove Computed Data Using Index.\n"); printf("\n------------------- Macros -----------------\n"); printf("9) List Manager Macro Definitions.\n"); printf("A) Define Macro.\n"); printf("B) Identify Macro Using Index.\n"); printf("C) Remove Macro Using Index.\n"); printf("\n--------------------------------------------\n"); printf("D) Return to Main Menu.\n"); } /****************************************************************************** * * \par Function Name: ui_print_menu * * \par Prints the user menu. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ void ui_print_menu_main() { printf("================== Main Menu =================\n"); printf("1) Administrative Menu.\n"); printf("2) Definitions Menu.\n"); printf("3) Reporting Menu.\n"); printf("4) Control Menu. \n"); printf("5) Exit.\n"); // printf("2) Define Custom MID. (We have %ld defined.)\n", lyst_length(custom_defs)); // printf("3) Construct and Send Production Rule Using Index.\n"); // printf("4) Construct and Send Production Rule Using MID.\n"); // printf("5) Go to Reports Menu.\n"); // printf("6) Go to Controls Menu.\n"); // printf("9) Exit.\n"); // printf("10) Run Tests.\n"); } void ui_print_menu_rpt() { printf("========================= Reporting Menu =========================\n"); printf("\n--------------------------- Data List --------------------------\n"); printf("1) List Agent Computed Data Definitions.\n"); printf("\n------------------------ Definitions List ----------------------\n"); printf("2) List Agent Custom Report Definition.\n"); printf("3) List Agent Macro Definitions.\n"); printf("\n-------------------------- Report List -------------------------\n"); printf("4) Print Reports Received from an Agent (We have %d reports).\n", g_reports_total); printf("5) Clear Reports Received from an Agent.\n"); printf("\n---------------------- Production Schedules --------------------\n"); printf("6) List Agent Production Rules.\n"); printf("------------------------------------------------------------------\n"); printf("7) Return to Main Menu.\n"); } /****************************************************************************** * * \par Function Name: ui_print_mids * * \par Prints list of configured data items and their associated index * * \par Notes: * 1. Assuming 80 column display, 2 column are printed of length 40 each. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ void ui_print_mids() { int i = 0; int num_full_rows = 0; int num_rows = 0; LystElt elt = 0; adm_datadef_t *cur = NULL; DTNMP_DEBUG_ENTRY("ui_print_mids","()",NULL); num_full_rows = (int) (lyst_length(gAdmData) / 2); for(elt = lyst_first(gAdmData); elt; elt = lyst_next(elt)) { cur = (adm_datadef_t*) lyst_data(elt); printf("%3d) %-35s ", i, cur->name); i++; if(num_rows < num_full_rows) { elt = lyst_next(elt); cur = (adm_datadef_t*) lyst_data(elt); printf("%3d) %-35s\n", i, cur->name); i++; } else { printf("\n\n\n"); } num_rows++; } DTNMP_DEBUG_EXIT("ui_print_mids","->.", NULL); } /****************************************************************************** * * \par Function Name: ui_print_predefined_rpt * * \par Prints a pre-defined report received by a DTNMP Agent. * * \par Notes: * * \param[in] mid The identifier of the data item being printed. * \param[in] data The contents of the data item. * \param[in] data_size The size of the data to be printed. * \param[out] data_used The bytes of the data consumed by printing. * \param[in] adu The static definition of the report. * * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ void ui_print_predefined_rpt(mid_t *mid, uint8_t *data, uint64_t data_size, uint64_t *data_used, adm_datadef_t *adu) { uint64_t len; char *mid_str = NULL; char *mid_val = NULL; uint32_t val_size = adu->get_size(data, data_size); uint32_t str_size = 0; mid_str = mid_to_string(mid); if((mid_val = adu->to_string(data, data_size, val_size, &str_size)) == NULL) { DTNMP_DEBUG_ERR("ui_print_predefined_rpt","Can't print data value for %s.", mid_str); MRELEASE(mid_str); return; } *data_used = val_size; printf("Data Name: %s\n", adu->name); printf("MID : %s\n", mid_str); printf("Value : %s\n", mid_val); MRELEASE(mid_val); MRELEASE(mid_str); } /****************************************************************************** * * \par Function Name: ui_print_reports * * \par Print all reports in the received reports queue. * * \par Notes: * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation *****************************************************************************/ void ui_print_reports(agent_t* agent) { LystElt report_elt; LystElt entry_elt; rpt_data_t *cur_report = NULL; rpt_data_entry_t *cur_entry = NULL; if(agent == NULL) { DTNMP_DEBUG_ENTRY("ui_print_reports","(NULL)", NULL); DTNMP_DEBUG_ERR("ui_print_reports", "No agent specified", NULL); DTNMP_DEBUG_EXIT("ui_print_reports", "->.", NULL); return; } DTNMP_DEBUG_ENTRY("ui_print_reports","(%s)", agent->agent_eid.name); if(lyst_length(agent->reports) == 0) { DTNMP_DEBUG_ALWAYS("ui_print_reports","[No reports received from this agent.]", NULL); DTNMP_DEBUG_EXIT("ui_print_reports", "->.", NULL); return; } /* Free any reports left in the reports list. */ for (report_elt = lyst_first(agent->reports); report_elt; report_elt = lyst_next(report_elt)) { /* Grab the current report */ if((cur_report = (rpt_data_t*)lyst_data(report_elt)) == NULL) { DTNMP_DEBUG_ERR("ui_print_reports","Unable to get report from lyst!", NULL); } else { unsigned long mid_sizes = 0; unsigned long data_sizes = 0; adm_datadef_t *adu = NULL; def_gen_t *report = NULL; /* Print the Report Header */ printf("\n-----------------\nDTNMP DATA REPORT\n-----------------\n"); printf("Sent to : %s\n", cur_report->recipient.name); printf("Rpt. Size: %d\n", cur_report->size); printf("Timestamp: %ld\n", cur_report->time); printf("Num Mids : %ld\n", lyst_length(cur_report->reports)); printf("Value(s)\n---------------------------------\n"); /* For each MID in this report, print it. */ for(entry_elt = lyst_first(cur_report->reports); entry_elt; entry_elt = lyst_next(entry_elt)) { cur_entry = (rpt_data_entry_t*)lyst_data(entry_elt); mid_sizes += cur_entry->id->raw_size; data_sizes += cur_entry->size; /* See if this is a pre-defined report, or a custom report. */ /* Find ADM associated with this entry. */ if((adu = adm_find_datadef(cur_entry->id)) != NULL) { uint64_t used; ui_print_predefined_rpt(cur_entry->id, cur_entry->contents, cur_entry->size, &used, adu); } else if((report = def_find_by_id(agent->custom_defs, &(agent->mutex), cur_entry->id)) != NULL) { ui_print_custom_rpt(cur_entry, report); } else { char *mid_str = mid_to_string(cur_entry->id); DTNMP_DEBUG_ERR("ui_print_reports","Could not print MID %s", mid_str); MRELEASE(mid_str); } } printf("=================\n"); printf("STATISTICS:\n"); printf("MIDs total %ld bytes\n", mid_sizes); printf("Data total: %ld bytes\n", data_sizes); printf("Efficiency: %.2f%%\n", (double)(((double)data_sizes)/((double)cur_report->size)) * (double)100.0); printf("-----------------\n\n\n"); } } } /****************************************************************************** * * \par Function Name: ui_run_tests * * \par Run local manager tests to test out libraries. * * \par Notes: * \todo Move this to a test file. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 01/18/13 E. Birrane Initial Implementation * 06/25/13 E. Birrane Removed references to priority field. *****************************************************************************/ void ui_run_tests() { char *str; unsigned char *msg; /* Test 1: Construct an OID and serialize/deserialize it. */ // # bytes (SDNV), followe dby the bytes. fprintf(stderr,"OID TEST 1\n----------------------------------------\n"); unsigned char tmp_oid[8] = {0x07,0x01,0x02,0x03,0x04,0x05,0x06,0x00}; uint32_t bytes = 0; fprintf(stderr,"Initial is "); utils_print_hex(tmp_oid,8); oid_t *oid = oid_deserialize_full(tmp_oid, 8, &bytes); fprintf(stderr,"Deserialized %d bytes into:\n", bytes); str = oid_pretty_print(oid); fprintf(stderr,"%s",str); MRELEASE(str); msg = oid_serialize(oid,&bytes); fprintf(stderr,"Serialized %d bytes into ", bytes); utils_print_hex(msg,bytes); MRELEASE(msg); fprintf(stderr,"\n----------------------------------------\n"); /* Test 2: Construct a MID and serialize/deserialize it. */ fprintf(stderr,"MID TEST 1\n"); uvast issuer = 0, tag = 0; mid_t *mid = mid_construct(0,0, NULL, NULL, oid); msg = (unsigned char*)mid_to_string(mid); fprintf(stderr,"Constructed mid: %s\n", msg); MRELEASE(msg); msg = mid_serialize(mid, &bytes); fprintf(stderr,"Serialized %d bytes into ", bytes); utils_print_hex(msg, bytes); uint32_t b2; mid_t *mid2 = mid_deserialize(msg, bytes, &b2); MRELEASE(msg); msg = (unsigned char *)mid_to_string(mid2); fprintf(stderr,"Deserialized %d bytes into MID %s\n", b2, msg); MRELEASE(msg); mid_release(mid2); mid_release(mid); } void *ui_thread(void * threadId) { DTNMP_DEBUG_ENTRY("ui_thread","(0x%x)", (unsigned long) threadId); ui_eventLoop(); DTNMP_DEBUG_EXIT("ui_thread","->.", NULL); pthread_exit(NULL); } ion-3.2.0~dfsg1.orig/nm/mgr/Makefile0000644000175000017500000000174012260400056015527 0ustar l3onl3onSOURCES = ../shared/adm/*.c ../shared/msg/*.c ../shared/utils/*.c ../shared/primitives/*.c ./*.c IONDIR = /home/apluser/ion/ion-2013-08-02/ion-open-source/ OPTS = -Wno-write-strings -g all:with-db without-db: g++ ${OPTS} \ -I. -I.. \ -I${IONDIR}/ici/include \ -I${IONDIR}/ltp/include \ -I${IONDIR}/ltp/library \ -I${IONDIR}/bp/include \ -I${IONDIR}/bp/library \ -I${IONDIR}/ici/library \ -I/usr/local/include \ -L${IONDIR}/ \ -L/usr/local/lib \ -lbp -lici -lltp \ -DMAXPATHLEN=2048 \ -c ${SOURCES} g++ -o nm_mgr *.o -lltp -lbp -lici with-db: g++ ${OPTS} \ -I. -I.. \ -I${IONDIR}/ici/include \ -I${IONDIR}/ltp/include \ -I${IONDIR}/ltp/library \ -I${IONDIR}/bp/include \ -I${IONDIR}/bp/library \ -I${IONDIR}/ici/library \ -I/usr/local/include \ -I/usr/include/mysql \ -L${IONDIR}/ \ -L/usr/local/lib \ -L/usr/lib \ -lbp -lici -lltp -lmysqlclient \ -DMAXPATHLEN=2048 \ -DHAVE_MYSQL=1 \ -c ${SOURCES} g++ -o nm_mgr *.o -lltp -lbp -lici -lmysqlclient ion-3.2.0~dfsg1.orig/nm/mgr/nm_mgr.h0000644000175000017500000001032212260400056015513 0ustar l3onl3on/****************************************************************************** ** COPYRIGHT NOTICE ** (c) 2011 The Johns Hopkins University Applied Physics Laboratory ** All rights reserved. ** ** This material may only be used, modified, or reproduced by or for the ** U.S. Government pursuant to the license rights granted under ** FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014 ** ** For any other permissions, please contact the Legal Office at JHU/APL. ******************************************************************************/ /***************************************************************************** ** \file nm_mgr.h ** ** File Name: nm_mgr.h ** ** Subsystem: ** Network Manager Application ** ** Description: This file implements the DTNMP Manager user interface ** ** Notes: ** ** Assumptions: ** ** Modification History: ** MM/DD/YY AUTHOR DESCRIPTION ** -------- ------------ --------------------------------------------- ** 09/01/11 V. Ramachandran Initial Implementation ** 08/19/13 E. Birrane Documentation clean up and code review comments. *****************************************************************************/ #ifndef NM_MGR_H #define NM_MGR_H // Standard includes #include "stdint.h" #include "pthread.h" #include "unistd.h" // ION includes #include "platform.h" #include "lyst.h" #include "sdr.h" // Application includes #include "shared/utils/nm_types.h" #include "shared/utils/ion_if.h" #include "shared/adm/adm.h" #include "shared/primitives/mid.h" #include "shared/msg/pdu.h" #include "shared/msg/msg_def.h" #include "shared/msg/msg_reports.h" #include "shared/msg/msg_admin.h" #include "shared/msg/msg_ctrl.h" /* Constants */ static const int32_t NM_RECEIVE_TIMEOUT_MILLIS = 3600; static const int32_t MSG_TYPE_SIZE = 1; // Change this static const int32_t TIMESTAMP_SIZE = 4; // Change this too? static const int32_t PENDING_LIST_LEN_SIZE = 2; // Change this too. static const char MGR_SDR_PROFILE_NAME[] = "NM_MGR"; static const int32_t MGR_SDR_HEAP_SIZE = 131072; // Do this intelligently? // Likely number of managed agents. Used to initialize the hashtable of agents. #define EST_NUM_AGENTS (5) // Indicates the allowable types of messages that an agent can send to // the manager. //static const unsigned char MSG_TYPE_REPORT[MSG_TYPE_SIZE] = {MSG_TYPE_RPT_DATA_RPT}; /** * Data structure representing a managed remote agent. **/ typedef struct { /** * Agent's endpoint identifier. **/ eid_t agent_eid; /** * Custom MID definitions that have been sent to this agent. **/ Lyst custom_defs; /** * Reports that have been received from this agent. **/ Lyst reports; /** * Mutex controlling read/write access to this structure. **/ ResourceLock mutex; } agent_t; // ============================= Global Data =============================== /** * Indicates if the thread loops should continue to run. This * value is updated by the main() and read by the subordinate * threads. **/ extern uint8_t g_running; /** * Storage list for production rules sent by a manager and received * by the agent. These will be executed at a perscribed time (measured * in ticks) and when ready will be placed in the rules_pending list * for execution. References to this object should be made * within mutexes to make it thread-safe. **/ extern Object agents_hashtable; extern Lyst known_agents; extern ResourceLock agents_mutex; extern Sdr g_sdr; extern Lyst macro_defs; extern ResourceLock macro_defs_mutex; extern uint32_t g_reports_total; /** * The endpoint identifier (EID) of the network manager node. **/ extern eid_t manager_eid; /** * The interface object the ION system. **/ extern iif_t ion_ptr; /* Function Prototypes */ int main(int argc, char *argv[]); agent_t* mgr_agent_get(eid_t* agent_eid); int mgr_agent_add(eid_t agent_eid); agent_t* mgr_agent_create(eid_t* agent_eid); int mgr_agent_remove(eid_t* agent_eid); void mgr_agent_remove_cb(LystElt elt, void *nil); int mgr_cleanup(); int mgr_init(char *argv[]); void* mgr_rx_thread(void* threadId); #endif // NM_MGR_H ion-3.2.0~dfsg1.orig/ici/0000755000175000017500000000000012260400056013432 5ustar l3onl3onion-3.2.0~dfsg1.orig/ici/i86-mingw/0000755000175000017500000000000012260400056015157 5ustar l3onl3onion-3.2.0~dfsg1.orig/ici/i86-mingw/Makefile0000644000175000017500000000730312260400056016622 0ustar l3onl3onSRC = ../library INCL = ../include TEST = ../test UTILS = ../utils DAEMON = ../daemon SDR = ../sdr OPT = -g -Wall -Dmingw CC = gcc $(OPT) -I$(SRC) -I$(TEST) -I$(SDR) -I$(INCL) LDFLAGS = -fPIC -shared LD = gcc $(LDFLAGS) LIBICIOBJS = \ llcv.o \ platform.o \ platform_sm.o \ memmgr.o \ lyst.o \ psm.o \ smlist.o \ smrbt.o \ sptrace.o \ ion.o \ rfx.o \ ionsec.o \ zco.o \ sdrxn.o \ sdrmgt.o \ sdrstring.o \ sdrlist.o \ sdrtable.o \ sdrhash.o \ sdrcatlg.o PUBINCLS = \ $(INCL)/llcv.h \ $(INCL)/platform.h \ $(INCL)/platform_sm.h \ $(INCL)/memmgr.h \ $(INCL)/lyst.h \ $(INCL)/psm.h \ $(INCL)/smlist.h \ $(INCL)/smrbt.h \ $(INCL)/sptrace.h \ $(INCL)/ion.h \ $(INCL)/rfx.h \ $(INCL)/ionsec.h \ $(INCL)/zco.h \ $(INCL)/sdrxn.h \ $(INCL)/sdrmgt.h \ $(INCL)/sdrstring.h \ $(INCL)/sdrlist.h \ $(INCL)/sdrtable.h \ $(INCL)/sdrhash.h \ $(INCL)/sdr.h ICIINCLS = \ $(SRC)/lystP.h \ $(SDR)/sdrP.h UTILITIES = sdrwatch psmwatch ionadmin ionsecadmin sdrmend ionwarn TESTPGMS = file2sm sm2file file2sdr sdr2file psmshell smlistsh smrbtsh owltsim # owlttb ALL = check libici.dll rfxclock killm winion $(UTILITIES) $(TESTPGMS) all: $(ALL) check: $(ICIINCLS) $(PUBINCLS) rm -f *.o touch check clean: rm -f *.o rm -f *.exe rm -f $(ALL) rm -f ./lib/* rm -f ./bin/* install: cp ../include/*.h $(ROOT)/include cp lib/* $(ROOT)/lib cp bin/* $(ROOT)/bin # - - Utility executables - - - - sdrwatch: sdrwatch.o libici.dll $(CC) -o sdrwatch sdrwatch.o -L./lib -lici -lpthread cp sdrwatch ./bin sdrmend: sdrmend.o libici.dll $(CC) -o sdrmend sdrmend.o -L./lib -lici -lpthread cp sdrmend ./bin psmwatch: psmwatch.o libici.dll $(CC) -o psmwatch psmwatch.o -L./lib -lici -lpthread cp psmwatch ./bin ionadmin: ionadmin.o libici.dll $(CC) -o ionadmin ionadmin.o -L./lib -lici -lpthread cp ionadmin ./bin ionwarn: ionwarn.o libici.dll $(CC) -o ionwarn ionwarn.o -L./lib -lici -lpthread cp ionwarn ./bin ionsecadmin: ionsecadmin.o libici.dll $(CC) -o ionsecadmin ionsecadmin.o -L./lib -lici -lpthread cp ionsecadmin ./bin killm: killm.o libici.dll $(CC) -o killm killm.o -L./lib -lici -lpthread cp killm ./bin # - - Test executables - - - - psmshell: psmshell.o libici.dll $(CC) -o psmshell psmshell.o -L./lib -lici -lpthread cp psmshell ./bin smlistsh: smlistsh.o libici.dll $(CC) -o smlistsh smlistsh.o -L./lib -lici -lpthread cp smlistsh ./bin smrbtsh: smrbtsh.o libici.dll $(CC) -o smrbtsh smrbtsh.o -L./lib -lici -lpthread cp smrbtsh ./bin file2sm: file2sm.o libici.dll $(CC) -I. -o file2sm file2sm.o -L./lib -lici -lpthread cp file2sm ./bin sm2file: sm2file.o libici.dll $(CC) -I. -o sm2file sm2file.o -L./lib -lici -lpthread cp sm2file ./bin file2sdr: file2sdr.o libici.dll $(CC) -I. -o file2sdr file2sdr.o -L./lib -lici -lpthread cp file2sdr ./bin sdr2file: sdr2file.o libici.dll $(CC) -o sdr2file sdr2file.o -L./lib -lici -lpthread cp sdr2file ./bin owltsim: owltsim.o libici.dll $(CC) -o owltsim owltsim.o -L./lib -lici -lpthread -lws2_32 cp owltsim ./bin owlttb: owlttb.o libici.dll $(CC) -o owlttb owlttb.o -L./lib -lici -lpthread cp owlttb ./bin # - - Daemon executables - - - - rfxclock: rfxclock.o libici.dll $(CC) -I. -o rfxclock rfxclock.o -L./lib -lici -lpthread cp rfxclock ./bin winion: winion.o libici.dll $(CC) -I. -o winion winion.o -L./lib -lici -lpthread cp winion ./bin # - - Libraries - - - - - libici.dll: $(LIBICIOBJS) libicinm.o $(LD) -o libici.dll $(LIBICIOBJS) libicinm.o -lpthread -lws2_32 cp libici.dll ./lib # - - Object modules - - - - - %.o: $(SRC)/%.c $(CC) -c $< %.o: $(SDR)/%.c $(CC) -c $< %.o: $(UTILS)/%.c $(CC) -c $< %.o: $(DAEMON)/%.c $(CC) -c $< %.o: $(TEST)/%.c $(CC) -c $< ion-3.2.0~dfsg1.orig/ici/doc/0000755000175000017500000000000012260400056014177 5ustar l3onl3onion-3.2.0~dfsg1.orig/ici/doc/Makefile0000644000175000017500000000472712260400056015651 0ustar l3onl3onPODM1 = pod2man -s 1 -c "ICI executables" PODM3 = pod2man -s 3 -c "ICI library functions" PODM5 = pod2man -s 5 -c "ICI configuration files" PODH = pod2html --noindex MANFILES = \ ./man/man1/ionadmin.1 \ ./man/man1/ionsecadmin.1 \ ./man/man1/rfxclock.1 \ ./man/man1/psmwatch.1 \ ./man/man1/sdrwatch.1 \ ./man/man1/sdrmend.1 \ ./man/man1/file2sdr.1 \ ./man/man1/file2sm.1 \ ./man/man1/psmshell.1 \ ./man/man1/sdr2file.1 \ ./man/man1/sm2file.1 \ ./man/man1/smlistsh.1 \ ./man/man1/smrbtsh.1 \ ./man/man1/owltsim.1 \ ./man/man1/owlttb.1 \ ./man/man5/ionconfig.5 \ ./man/man5/ionrc.5 \ ./man/man5/ionsecrc.5 \ ./man/man3/platform.3 \ ./man/man3/memmgr.3 \ ./man/man3/ion.3 \ ./man/man3/llcv.3 \ ./man/man3/lyst.3 \ ./man/man3/psm.3 \ ./man/man3/zco.3 \ ./man/man3/smlist.3 \ ./man/man3/smrbt.3 \ ./man/man3/sdrlist.3 \ ./man/man3/sdrstring.3 \ ./man/man3/sdrtable.3 \ ./man/man3/sdrhash.3 \ ./man/man3/sdr.3 HTMLFILES = \ ./html/man1/ionadmin.html \ ./html/man1/ionsecadmin.html \ ./html/man1/rfxclock.html \ ./html/man1/psmwatch.html \ ./html/man1/sdrwatch.html \ ./html/man1/sdrmend.html \ ./html/man1/file2sdr.html \ ./html/man1/file2sm.html \ ./html/man1/psmshell.html \ ./html/man1/sdr2file.html \ ./html/man1/sm2file.html \ ./html/man1/smlistsh.html \ ./html/man1/smrbtsh.html \ ./html/man1/owltsim.html \ ./html/man1/owlttb.html \ ./html/man5/ionconfig.html \ ./html/man5/ionrc.html \ ./html/man5/ionsecrc.html \ ./html/man3/platform.html \ ./html/man3/memmgr.html \ ./html/man3/ion.html \ ./html/man3/llcv.html \ ./html/man3/lyst.html \ ./html/man3/psm.html \ ./html/man3/zco.html \ ./html/man3/smlist.html \ ./html/man3/smrbt.html \ ./html/man3/sdrlist.html \ ./html/man3/sdrstring.html \ ./html/man3/sdrtable.html \ ./html/man3/sdrhash.html \ ./html/man3/sdr.html ALL = $(MANFILES) $(HTMLFILES) all: $(ALL) clean: rm -f man/man1/*.1 rm -f man/man3/*.3 rm -f man/man5/*.5 rm -f html/man1/*.html rm -f html/man3/*.html rm -f html/man5/*.html rm -f *.tmp install: cp man/man1/*.1 $(ROOT)/man/man1 cp man/man3/*.3 $(ROOT)/man/man3 cp man/man5/*.5 $(ROOT)/man/man5 # - - Man files - - - - - ./man/man1/%.1: pod1/%.pod $(PODM1) $< $@ ./man/man3/%.3: pod3/%.pod $(PODM3) $< $@ ./man/man5/%.5: pod5/%.pod $(PODM5) $< $@ ./html/man1/%.html: pod1/%.pod $(PODH) --infile=$< --outfile=$@ ./html/man3/%.html: pod3/%.pod $(PODH) --infile=$< --outfile=$@ ./html/man5/%.html: pod5/%.pod $(PODH) --infile=$< --outfile=$@ ion-3.2.0~dfsg1.orig/ici/doc/pod1/0000755000175000017500000000000012260400056015042 5ustar l3onl3onion-3.2.0~dfsg1.orig/ici/doc/pod1/psmwatch.pod0000644000175000017500000000414512260400056017400 0ustar l3onl3on=head1 NAME psmwatch - PSM memory partition activity monitor =head1 SYNOPSIS B I I I I I [ verbose ] =head1 DESCRIPTION For I interations, B sleeps I seconds and then invokes the psm_print_trace() function (see psm(3)) to report on PSM dynamic memory management activity in the PSM-managed shared memory partition identified by I during that interval. If the optional B parameter is specified, the printed PSM activity trace will be verbose as described in psm(3). To prevent confusion, the specified I and I are compared to those declared when this shared memory partition was initially managed; if they don't match, B immediately terminates. If I is zero, B merely prints a current usage summary for the indicated shared-memory partition and terminates. B is helpful for detecting and diagnosing memory leaks. For debugging the ION protocol stack: =over 8 =item I Normally "65281", but might be overridden by the value of wmKey in the .ionconfig file used to configure the node under study. =item I As given by the value of wmKey in the .ionconfig file used to configure the node under study. If this value is not stated in the .ionconfig file, the default value is "5000000". =item I Always "ionwm". =back =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS The following diagnostics may be issued to the B log file: =over 4 =item Can't attach to psm. ION system error. One possible cause is that ION has not yet been initialized on the local computer; run ionadmin(1) to correct this. =item Can't start trace. Insufficient ION working memory to contain trace information. Reinitialize ION with more memory. =back =head1 BUGS Report bugs to =head1 SEE ALSO psm(3), sdrwatch(1) ion-3.2.0~dfsg1.orig/ici/doc/pod1/owlttb.pod0000644000175000017500000001072712260400056017070 0ustar l3onl3on=head1 NAME owlttb - one-way light time transmission delay simulator =head1 SYNOPSIS B I I I I I I I [-v] =head1 DESCRIPTION B delays delivery of data between an NTTI and a NetAcquire box (or two, one for uplink and one for downlink) by a specified length of time, simulating the signal propagation delay imposed by distance between the nodes. Its operation is configured by the command-line parameters, except that the delay interval itself may be changed while the program is running. B offers a command prompt (:), and when a new value of one-way light time is entered at this prompt the new delay interval takes effect immediately. =over 4 =item I identifies the port on B accepts the NTTI's TCP connection for uplink traffic (i.e., data destined for the NetAcquire box). =item I identifies the port on B accepts the NTTI's TCP connection for downlink traffic (i.e., data issued by the NetAcquire box). =item I is the IP address (a dotted string) identifying the NetAcquire box to which B will transmit uplink traffic. =item I identifies the TCP port to which B will connect in order to transmit uplink traffic to NetAcquire. =item I is the IP address (a dotted string) identifying the NetAcquire box from which B will receive downlink traffic. =item I identifies the TCP port to which B will connect in order to receive downlink traffic from NetAcquire. =item I specifies the number of seconds to wait before forwarding each received segment of TCP traffic. =back The optional B<-v> ("verbose") parameter causes B to print a message whenever it receives, sends, or discards (due to absence of a connected downlink client) a segment of TCP traffic. B is designed to run indefinitely. To terminate the program, just use control-C to kill it or enter "q" at the prompt. =head1 EXIT STATUS =over 4 =item "0" Nominal termination. =item "1" Termination due to an error condition, as noted in printed messages. =back =head1 EXAMPLES Here is a sample owlttb command: =over 4 =item owlttb 2901 2902 137.7.8.19 10001 137.7.8.19 10002 75 =back This command indicates that B will accept an uplink traffic connection on port 2901, forwarding the received uplink traffic to port 10001 on the NetAcquire box at 137.7.8.19, and it will accept a downlink traffic connection on port 2902, delivering over that connection all downlink traffic that it receives from connecting to port 10002 on the NetAcquire box at 137.7.8.19. 75 seconds of delay (simulating a distance of 75 light seconds) will be imposed on this transmission activity. =head1 FILES Not applicable. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS The following diagnostics may be printed to stdout: =over 4 =item owlttb can't spawn uplink thread The program terminates. =item owlttb can't spawn uplink sender thread The program terminates. =item owlttb can't spawn downlink thread The program terminates. =item owlttb can't spawn downlink receiver thread The program terminates. =item owlttb can't spawn downlink sender thread The program terminates. =item owlttb fgets failed The program terminates. =item owlttb out of memory. The program terminates. =item owlttb lost uplink client. This is an informational message. The NTTI may reconnect at any time. =item owlttb lost downlink client This is an informational message. The NTTI may reconnect at any time. =item owlttb can't open TCP socket to NetAcquire The program terminates. =item owlttb can't connect TCP socket to NetAcquire The program terminates. =item owlttb write() error on socket The program terminates if it was writing to NetAcquire; otherwise it simply recognizes that the client NTTI has disconnected. =item owlttb read() error on socket The program terminates. =item owlttb can't open uplink dialup socket The program terminates. =item owlttb can't initialize uplink dialup socket The program terminates. =item owlttb can't open downlink dialup socket The program terminates. =item owlttb can't initialize downlink dialup socket The program terminates. =item owlttb accept() failed The program terminates. =back =head1 BUGS Report bugs to ion-3.2.0~dfsg1.orig/ici/doc/pod1/smrbtsh.pod0000644000175000017500000000660412260400056017236 0ustar l3onl3on=head1 NAME smrbtsh - shared-memory red-black tree test shell =head1 SYNOPSIS B [I] =head1 DESCRIPTION B allocates a region of shared system memory, attaches to that region, places it under PSM management, creates a temporary "test" red-black tree in that memory region, and executes a series of shared-memory red-black tree commands that exercise various tree access and management functions. If I is provided, then the commands in the indicated file are executed and the program then terminates. Upon termination, the shared memory region allocated to B is detached and destroyed. Otherwise, B offers the user an interactive "shell" for testing the smrbt functions in a conversational manner: B prints a prompt string (": ") to stdout, accepts a command from stdin, executes the command (possibly printing a diagnostic message), then prints another prompt string and so on. Upon execution of the 'q' command, the program terminates. The following commands are supported: =over 4 =item B The B command. Causes B to print a summary of available commands. Same effect as the B command. =item B Another B command. Causes B to print a summary of available commands. Same effect as the B command. =item B [I] The B command. Seeds random data value generator, which is used to generate node values when the B command is used. If I is omitted, uses current time (as returned by time(1)) as seed value. =item B [I] The B command. Inserts I new nodes into the red-black tree, using randomly selected unsigned long integers as the data values of the nodes; I defaults to 1 if omitted. =item B I The B command. Inserts a single new node into the red-black tree, using I as the data value of the node. =item B I The B command. Finds the rbt node whose value is I, within the red-black tree, and prints the address of that node. If the node is not found, prints address zero and prints the address of the successor node in the tree. =item B I The B command. Deletes the rbt node whose data value is I. =item B

The B command. Prints the red-black tree, using indentation to indicate descent along paths of the tree. Note: this function is supported only if the B library was built with compilation flag -DSMRBT_DEBUG=1. =item B The B command. Examines the red-black tree, noting the first violation of red-black structure rules, if any. Note: this function is supported only if the B library was built with compilation flag -DSMRBT_DEBUG=1. =item B The B command. Lists all nodes in the red-black tree in traversal order, noting any nodes whose data values are not in ascending numerical order. =item B The B command. Detaches B from the region of shared memory it is currently using, destroys that shared memory region, and terminates B. =back =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS No diagnostics apply. =head1 BUGS Report bugs to =head1 SEE ALSO smrbt(3) ion-3.2.0~dfsg1.orig/ici/doc/pod1/sm2file.pod0000644000175000017500000000374212260400056017115 0ustar l3onl3on=head1 NAME sm2file - shared-memory linked list data extraction test program =head1 SYNOPSIS B =head1 DESCRIPTION B stress-tests shared-memory linked list data extraction by retrieving and deleting all text file lines inserted into a shared-memory linked list that is the root object of a PSM partition named "file2sm". The operation of B echoes the cyclical operation of B: the EOF lines inserted into the linked list by B punctuate the writing of files that are copies of B's original source text file. The name of each file written by B is file_copy_I, where I is, in effect, the count of EOF lines encountered in the linked list up to the point at which the writing of this file began. B may catch up with the data ingestion activity of B, in which case it blocks (taking the B test semaphore) until the linked list is no longer empty. =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS =over 4 =item can't attach to shared memory Operating system error. Check errtext, correct problem, and rerun. =item Can't manage shared memory. PSM error. Check for earlier diagnostics describing the cause of the error; correct problem and rerun. =item Can't create shared memory list. PSM error. Check for earlier diagnostics describing the cause of the error; correct problem and rerun. =item Can't create semaphore. ION system error. Check for earlier diagnostics describing the cause of the error; correct problem and rerun. =item Can't open output file Operating system error. Check errtext, correct problem, and rerun. =item can't write to output file Operating system error. Check errtext, correct problem, and rerun. =back =head1 BUGS Report bugs to =head1 SEE ALSO file2sm(1), smlist(3), psm(3) ion-3.2.0~dfsg1.orig/ici/doc/pod1/ionadmin.pod0000644000175000017500000001054312260400056017347 0ustar l3onl3on=head1 NAME ionadmin - ION node administration interface =head1 SYNOPSIS B [ I | . ] =head1 DESCRIPTION B configures, starts, manages, and stops the ION node on the local computer. It configures the node and sets (and reports on) global operational settings for the DTN protocol stack on the local computer in response to ION configuration commands found in I, if provided; if not, B prints a simple prompt (:) so that the user may type commands directly into standard input. If I is a period (.), the effect is the same as if a command file containing the single command 'x' were passed to B -- that is, the ION node's I task is stopped. The format of commands for I can be queried from B by entering the command 'h' or '?' at the prompt. The commands are documented in ionrc(5). Note that I always computes a congestion forecast immediately before exiting. The result of this forecast -- maximum projected occupancy of the DTN protocol traffic allocation in ION's SDR database -- is retained for application flow control purposes: if maximum projected occupancy is the entire protocol traffic allocation, then a message to this effect is logged and no new bundle origination by any application will be accepted until a subsequent forecast that predicts no congestion is computed. (Congestion forecasts are constrained by I times, which can be established by commands issued to I. One way to re-enable data origination temporarily while long-term traffic imbalances are being addressed is to declare a congestion forecast horizon in the near future, before congestion would occur if no adjustments were made.) =head1 EXIT STATUS =over 4 =item "0" Successful completion of ION node administration. =back =head1 EXAMPLES =over 4 =item ionadmin Enter interactive ION configuration command entry mode. =item ionadmin host1.ion Execute all configuration commands in I, then terminate immediately. =back =head1 FILES Status and diagnostic messages from B and from other software that utilizes the ION node are nominally written to a log file in the current working directory within which B was run. The log file is typically named B. See also ionconfig(5) and ionrc(5). =head1 ENVIRONMENT Environment variables ION_NODE_LIST_DIR and ION_NODE_WDNAME can be used to enable the operation of multiple ION nodes on a single workstation computer. See section 2.1.3 of the ION Design and Operations Guide for details. =head1 DIAGNOSTICS B: all ION administration utilities expect source file input to be lines of ASCII text that are NL-delimited. If you edit the ionrc file on a Windows machine, be sure to B before presenting it to B. Otherwise B will detect syntax errors and will not function satisfactorily. The following diagnostics may be issued to the log file: =over 4 =item Can't open command file... The I specified in the command line doesn't exist. =item ionadmin SDR definition failed. A node initialization command was executed, but an SDR database already exists for the indicated node. It is likely that an ION node is already running on this computer or that destruction of a previously started the previous ION node was incomplete. For most ION installations, incomplete node destruction can be repaired by (a) killing all ION processes that are still running and then (b) using B to remove all SVr4 IPC objects owned by ION. =item ionadmin can't get SDR parms. A node initialization command was executed, but the I passed to that command contains improperly formatted commands. Please see ionconfig(5) for further details. =back Various errors that don't cause B to fail but are noted in the log file may be caused by improperly formatted commands given at the prompt or in the I. Please see ionrc(5) for details. =head1 BUGS If the I parameter passed to a node initialization command refers to a nonexistent filename, then B uses default values are used rather than reporting an error in the command line argument. Report bugs to =head1 SEE ALSO ionrc(5), ionconfig(5) ion-3.2.0~dfsg1.orig/ici/doc/pod1/rfxclock.pod0000644000175000017500000000471712260400056017372 0ustar l3onl3on=head1 NAME rfxclock - ION daemon task for managing scheduled events =head1 SYNOPSIS B =head1 DESCRIPTION B is a background "daemon" task that periodically applies scheduled changes in node connectivity and range to the ION node's database. It is spawned automatically by B in response to the 's' command that starts operation of the ION node infrastructure, and it is terminated by B in response to an 'x' (STOP) command. Once per second, B takes the following action: =over 4 For each neighboring node that has been refusing custody of bundles sent to it to be forwarded to some destination node, to which no such bundle has been sent for at least N seconds (where N is twice the one-way light time from the local node to this neighbor), B turns on a I flag authorizing transmission of the next such bundle in hopes of learning that this neighbor is now able to accept custody. Then B purges the database of all range and contact information that is no longer applicable, based on the stop times of the records. Finally, B applies to the database all range and contact information that is currently applicable, i.e., those records whose start times are before the current time and whose stop times are in the future. =back =head1 EXIT STATUS =over 4 =item "0" B terminated, for reasons noted in the B file. If this termination was not commanded, investigate and solve the problem identified in the log file and use B to restart B. =item "1" B was unable to attach to the local ION node, probably because B has not yet been run. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS The following diagnostics may be issued to the B log file: =over 4 =item rfxclock can't attach to ION. B has not yet initialized the ION database. =item Can't apply ranges. An unrecoverable database error was encountered. B terminates. =item Can't apply contacts. An unrecoverable database error was encountered. B terminates. =item Can't purge ranges. An unrecoverable database error was encountered. B terminates. =item Can't purge contacts. An unrecoverable database error was encountered. B terminates. =back =head1 BUGS Report bugs to =head1 SEE ALSO ionadmin(1) ion-3.2.0~dfsg1.orig/ici/doc/pod1/smlistsh.pod0000644000175000017500000000670712260400056017426 0ustar l3onl3on=head1 NAME smlistsh - shared-memory linked list test shell =head1 SYNOPSIS B I =head1 DESCRIPTION B attaches to a region of system memory (allocating it if necessary, and placing it under PSM management as necessary) and offers the user an interactive "shell" for testing various shared-memory linked list management functions. B prints a prompt string (": ") to stdout, accepts a command from stdin, executes the command (possibly printing a diagnostic message), then prints another prompt string and so on. The following commands are supported: =over 4 =item B The B command. Causes B to print a summary of available commands. Same effect as the B command. =item B Another B command. Causes B to print a summary of available commands. Same effect as the B command. =item B The B command. Computes and prints an unused shared-memory key, for possible use in attaching to a shared-memory region. =item B<+> I I The B command. Attaches B to a region of shared memory. I identifies an existing shared-memory region, in the event that you want to attach to an existing shared-memory region (possibly created by another B process running on the same computer). To create and attach to a new shared-memory region that other processes can attach to, use a I as returned by the B command and supply the I of the new region. If you want to create and attach to a new shared-memory region that is for strictly private use, use -1 as key and supply the I of the new region. =item B<-> The B command. Detaches B from the region of shared memory it is currently using, but does not free any memory. =item B The B command. Creates a new shared-memory list to operate on, within the currently attached shared-memory region. Prints the address of the list. =item B I The B command. Selects an existing shared-memory list to operate on, within the currently attached shared-memory region. =item B I The B command. Appends a new list element, containing I, to the list on which B is currently operating. =item B

I The B command. Prepends a new list element, containing I, to the list on which B is currently operating. =item B The B command. Prints the addresses and contents of all elements of the list on which B is currently operating. =item B I The B command. Finds the list element that contains I, within the list on which B is currently operating, and prints the address of that list element. =item B I The B command. Deletes the list element located at I. =item B The B command. Prints a partition usage report, as per psm_report(3). =item B The B command. Detaches B from the region of shared memory it is currently using (without freeing any memory) and terminates B. =back =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS No diagnostics apply. =head1 BUGS Report bugs to =head1 SEE ALSO smlist(3) ion-3.2.0~dfsg1.orig/ici/doc/pod1/sdrwatch.pod0000644000175000017500000000305612260400056017371 0ustar l3onl3on=head1 NAME sdrwatch - SDR non-volatile data store activity monitor =head1 SYNOPSIS B I I I [ verbose ] =head1 DESCRIPTION For I interations, B sleeps I seconds and then invokes the sdr_print_trace() function (see sdr(3)) to report on SDR data storage management activity in the SDR data store identified by I during that interval. If the optional B parameter is specified, the printed SDR activity trace will be verbose as described in sdr(3). If I is zero, B merely prints a current usage summary for the indicated data store and terminates. B is helpful for detecting and diagnosing storage space leaks. For debugging the ION protocol stack, I is normally "ion" but might be overridden by the value of sdrName in the .ionconfig file used to configure the node under study. =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS The following diagnostics may be issued to the B log file: =over 4 =item Can't attach to sdr. ION system error. One possible cause is that ION has not yet been initialized on the local computer; run ionadmin(1) to correct this. =item Can't start trace. Insufficient ION working memory to contain trace information. Reinitialize ION with more memory. =back =head1 BUGS Report bugs to =head1 SEE ALSO sdr(3), psmwatch(1) ion-3.2.0~dfsg1.orig/ici/doc/pod1/psmshell.pod0000644000175000017500000000511112260400056017373 0ustar l3onl3on=head1 NAME psmshell - PSM memory management test shell =head1 SYNOPSIS B I =head1 DESCRIPTION B allocates a region of I bytes of system memory, places it under PSM management, and offers the user an interactive "shell" for testing various PSM management functions. B prints a prompt string (": ") to stdout, accepts a command from stdin, executes the command (possibly printing a diagnostic message), then prints another prompt string and so on. The locations of objects allocated from the PSM-managed region of memory are referred to as "cells" in psmshell operations. That is, when an object is to be allocated, a cell number in the range 0-99 must be specified as the notional "handle" for that object, for use in future commands. The following commands are supported: =over 4 =item B The B command. Causes B to print a summary of available commands. Same effect as the B command. =item B Another B command. Causes B to print a summary of available commands. Same effect as the B command. =item B I I The B command. Allocates a large-pool object of the indicated size and associates that object with I. =item B I I The B command. Allocates a small-pool object of the indicated size and associates that object with I. =item B

I The B command. Prints the address (i.e., the offset within the managed block of memory) of the object associated with I. =item B I The B command. Frees the object associated with I, returning the space formerly occupied by that object to the appropriate free block list. =item B The B command. Prints a partition usage report, as per psm_report(3). =item B The B command. Frees the allocated system memory in the managed block and terminates B. =back =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS =over 4 =item IPC initialization failed. ION system error. Investigate, correct problem, and try again. =item psmshell: can't allocate space; quitting. Insufficient available system memory for selected partition size. =item psmshell: can't allocate test variables; quitting. Insufficient available system memory for selected partition size. =back =head1 BUGS Report bugs to =head1 SEE ALSO psm(3) ion-3.2.0~dfsg1.orig/ici/doc/pod1/sdr2file.pod0000644000175000017500000000331412260400056017261 0ustar l3onl3on=head1 NAME sdr2file - SDR data extraction test program =head1 SYNOPSIS B I =head1 DESCRIPTION B stress-tests SDR data extraction by retrieving and deleting all text file lines inserted into a test SDR data store named "testsdrI" by the complementary test program file2sdr(1). The operation of B echoes the cyclical operation of B: each linked list created by B is used to create in the current working directory a copy of B's original source text file. The name of each file written by B is file_copy_I, where I identifies the linked list from which the file's text lines were obtained. B may catch up with the data ingestion activity of B, in which case it blocks (taking the B test semaphore) until the linked list it is currently draining is no longer empty. =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS =over 4 =item Can't use sdr. ION system error. Check for diagnostics in the ION log file I. =item Can't create semaphore. ION system error. Check for diagnostics in the ION log file I. =item SDR transaction failed. ION system error. Check for diagnostics in the ION log file I. =item Can't open output file Operating system error. Check errtext, correct problem, and rerun. =item can't write to output file Operating system error. Check errtext, correct problem, and rerun. =back =head1 BUGS Report bugs to =head1 SEE ALSO file2sdr(1), sdr(3) ion-3.2.0~dfsg1.orig/ici/doc/pod1/sdrmend.pod0000644000175000017500000000324312260400056017204 0ustar l3onl3on=head1 NAME sdrmend - SDR corruption repair utility =head1 SYNOPSIS B I I I I I [I I] =head1 DESCRIPTION The B program simply invokes the sdr_reload_profile() function (see sdr(3)) to effect necessary repairs in a potentially corrupt SDR, e.g., due to the demise of a program that had an SDR transaction in progress at the moment it crashed. Note that B need not be run to repair ION's data store in the event of a hardware reboot: restarting ION will automatically reload the data store's profile. B is needed only when it is desired to repair the data store without requiring all ION software to terminate and restart. =head1 EXIT STATUS =over 4 =item "0" B has terminated successfully. =item "1" B has terminated unsuccessfully. See diagnostic messages in the B log file for details. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS The following diagnostics may be issued to the B log file: =over 4 =item Can't initialize the SDR system. Probable operations error: ION appears not to be initialized, in which case there is no point in running B. =item Can't reload profile for SDR. ION system error. See earlier diagnostic messages posted to B for details. In this event it is unlikely that B can be run successfully, and it is also unlikely that it would have any effect if it did run successfully. =back =head1 BUGS Report bugs to =head1 SEE ALSO sdr(3), ionadmin(1) ion-3.2.0~dfsg1.orig/ici/doc/pod1/file2sm.pod0000644000175000017500000000444112260400056017112 0ustar l3onl3on=head1 NAME file2sm - shared-memory linked list data ingestion test program =head1 SYNOPSIS B I =head1 DESCRIPTION B stress-tests shared-memory linked list data ingestion by repeatedly writing all text lines of the file named I to a shared-memory linked list that is the root object of a PSM partition named "file2sm". After writing each line to the linked list, B gives a semaphore to indicate that the list is now non-empty. This is mainly for the benefit of the complementary test program sm2file(1). The operation of B is cyclical. After copying all text lines of the source file to the linked list, B appends an EOF line to the linked list, containing the text "*** End of the file ***", and prints a brief performance report: Processing I lines per second. Then it reopens the source file and starts appending the file's text lines to the linked list again. =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS =over 4 =item Can't attach to shared memory Operating system error. Check errtext, correct problem, and rerun. =item Can't manage shared memory. PSM error. Check for earlier diagnostic messages describing the cause of the error; correct problem and rerun. =item Can't create shared memory list. smlist error. Check for earlier diagnostic messages describing the cause of the error; correct problem and rerun. =item Can't create semaphore. ION system error. Check for earlier diagnostic messages describing the cause of the error; correct problem and rerun. =item Can't open input file Operating system error. Check errtext, correct problem, and rerun. =item Can't reopen input file Operating system error. Check errtext, correct problem, and rerun. =item Can't read from input file Operating system error. Check errtext, correct problem, and rerun. =item Ran out of memory. Nominal behavior. B is not extracting data from the linked list quickly enough to prevent it from growing to consume all memory allocated to the test partition. =back =head1 BUGS Report bugs to =head1 SEE ALSO sm2file(1), smlist(3), psm(3) ion-3.2.0~dfsg1.orig/ici/doc/pod1/ionsecadmin.pod0000644000175000017500000000434612260400056020046 0ustar l3onl3on=head1 NAME ionsecadmin - ION security policy administration interface =head1 SYNOPSIS B [ I ] =head1 DESCRIPTION B configures and manages the ION security policy database on the local computer. It configures and manages the ION security policy database on the local computer in response to ION configuration commands found in I, if provided; if not, B prints a simple prompt (:) so that the user may type commands directly into standard input. The format of commands for I can be queried from B by entering the command 'h' or '?' at the prompt. The commands are documented in ionsecrc(5). =head1 EXIT STATUS =over 4 =item "0" Successful completion of ION security policy administration. =back =head1 EXAMPLES =over 4 =item ionsecadmin Enter interactive ION security policy administration command entry mode. =item ionsecadmin host1.ionsecrc Execute all configuration commands in I, then terminate immediately. =back =head1 FILES Status and diagnostic messages from B and from other software that utilizes the ION node are nominally written to a log file in the current working directory within which B was run. The log file is typically named B. See also ionsecrc(5). =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS B: all ION administration utilities expect source file input to be lines of ASCII text that are NL-delimited. If you edit the ionrc file on a Windows machine, be sure to B before presenting it to B. Otherwise B will detect syntax errors and will not function satisfactorily. The following diagnostics may be issued to the log file: =over 4 =item Can't open command file... The I specified in the command line doesn't exist. =back Various errors that don't cause B to fail but are noted in the log file may be caused by improperly formatted commands given at the prompt or in the I. Please see ionsecrc(5) for details. =head1 BUGS Report bugs to =head1 SEE ALSO ionsecrc(5) ion-3.2.0~dfsg1.orig/ici/doc/pod1/file2sdr.pod0000644000175000017500000000457612260400056017274 0ustar l3onl3on=head1 NAME file2sdr - SDR data ingestion test program =head1 SYNOPSIS B I I =head1 DESCRIPTION B stress-tests SDR data ingestion by repeatedly writing all text lines of the file named I to one of a series of non-volatile linked lists created in a test SDR data store named "testsdrI". By incorporating the data store configuration into the name (e.g., "testsdr14") we make it relatively easy to perform comparative testing on SDR data stores that are identical aside from their configuration settings. The operation of B is cyclical: a new linked list is created each time the program finishes copying the file's text lines and starts over again. If you use ^C to terminate B and then restart it, the program resumes operation at the point where it left off. After writing each line to the current linked list, B gives a semaphore to indicate that the list is now non-empty. This is mainly for the benefit of the complementary test program sdr2file(1). At the end of each cycle B appends a final EOF line to the current linked list, containing the text "*** End of the file ***", and prints a brief performance report: Processing I lines per second. =head1 EXIT STATUS =over 4 =item "0" B has terminated. =back =head1 FILES No configuration files are needed. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS Diagnostic messages produced by B are written to the ION log file I. =over 4 =item Can't use sdr. ION system error. Check for earlier diagnostic messages describing the cause of the error; correct problem and rerun. =item Can't create semaphore. ION system error. Check for earlier diagnostic messages describing the cause of the error; correct problem and rerun. =item SDR transaction failed. ION system error. Check for earlier diagnostic messages describing the cause of the error; correct problem and rerun. =item Can't open input file Operating system error. Check errtext, correct problem, and rerun. =item Can't reopen input file Operating system error. Check errtext, correct problem, and rerun. =item Can't read from input file Operating system error. Check errtext, correct problem, and rerun. =back =head1 BUGS Report bugs to =head1 SEE ALSO sdr2file(1), sdr(3) ion-3.2.0~dfsg1.orig/ici/doc/pod1/owltsim.pod0000644000175000017500000001212012260400056017240 0ustar l3onl3on=head1 NAME owltsim - one-way light time transmission delay simulator =head1 SYNOPSIS B I [-v] =head1 DESCRIPTION B delays delivery of data between pairs of ION nodes by specified lengths of time, simulating the signal propagation delay imposed by distance between the nodes. Its operation is configured by delay simulation configuration lines in the file identified by I. A pair of threads is created for each line in the file: one that receives UDP datagrams on a specified port and queues them in a linked list, and a second that later removes queued datagrams from the linked list and sends them on to a specified UDP port on a specified network host. Each configuration line must be of the following form: =over 4 I I I I I I I =back =over 4 =item I identifies the receiving node. This parameter is purely informational, intended to make B's printed messages more helpful to the user. =item I identifies the sending node. A value of '*' may be used to indicate "all nodes". Again, this parameter is purely informational, intended to make B's printed messages more helpful to the user. =item I identifies B's receiving port for this traffic. =item I is a hostname identifying the computer to which B will transmit this traffic. =item I identifies the port to which B will transmit this traffic. =item I specifies the number of seconds to wait before forwarding each received datagram. =item I controls the artificial random data loss imposed on this traffic by B. A value of '0' specifies "no random data loss". Any other modulus value N causes B to randomly drop (i.e., not transmit upon expiration of the delay interval) one out of every N packets. =back The optional B<-v> ("verbose") parameter causes B to print a message whenever it receives, sends, or drops (due to artificial random data loss) a datagram. Note that error conditions may cause one delay simulation (a pair of threads) to terminate without terminating any others. B is designed to run indefinitely. To terminate the program, just use control-C to kill it. =head1 EXIT STATUS =over 4 =item "0" Nominal termination. =item "1" Termination due to an error condition, as noted in printed messages. =back =head1 EXAMPLES Here is a sample owltsim configuration file: =over 4 =item 2 7 5502 ptl07.jpl.nasa.gov 5001 75 0 =item 7 2 5507 ptl02.jpl.nasa.gov 5001 75 16 =back This file indicates that B will receive on port 5502 the ION traffic from node 2 that is destined for node 7, which will receive it at port 5001 on the computer named ptl07.jpl.nasa.gov; 75 seconds of delay (simulating a distance of 75 light seconds) will be imposed on this transmission activity, and B will not simulate any random data loss. In the reverse direction, B will receive on port 5507 the ION traffic from node 7 that is destined for node 2, which will receive it at port 5001 on the computer named ptl02.jpl.nasa.gov; 75 seconds of delay will again be imposed on this transmission activity, and B will randomly discard (i.e., not transmit upon expiration of the transmission delay interval) one datagram out of every 16 received at this port. =head1 FILES Not applicable. =head1 ENVIRONMENT No environment variables apply. =head1 DIAGNOSTICS The following diagnostics may be printed to stdout: =over 4 =item owltsim can't open configuration file The program terminates. =item owltsim failed on fscanf Failure on reading the configuration file. The program terminates. =item owltsim stopped malformed config file line I. Failure on parsing the configuration file. The program terminates. =item owltsim can't spawn receiver thread The program terminates. =item owltsim out of memory. The program terminates. =item owltsim can't open reception socket The program terminates. =item owltsim can't initialize reception socket The program terminates. =item owltsim can't open transmission socket The program terminates. =item owltsim can't initialize transmission socket The program terminates. =item owltsim can't spawn timer thread The program terminates. =item owltsim can't acquire datagram Datagram transmission failed. This causes the threads for the affected delay simulation to terminate, without terminating any other threads. =item owltsim failed on send Datagram transmission failed. This causes the threads for the affected delay simulation to terminate, without terminating any other threads. =item at I