DIS-Tool

FrBa DIS Tool is a collector of Distributed Interactive Simulation (DIS) PDU traffic from a network UDP port. Project was started in 2011 and worked only by Frank. It has proved useful to listen to simulation data to analyze dis enumerations and simulation activities. It relies on the 32-bit UDP extension to access the network port. See ActiveState TCL Recipes for examples by Frank from 2009.

References:

DIS Tool listens for all PDUs that pass its Exercise and Site filters. It offers reports of the data collected, to include Entities, Fire, Detonations, Aggregates, and more. It supports a home-brew http server to allow remote viewing of reports using a web browser. Currently composed of approx 13,268 lines of TCL code. Tested on Windows 7/10/11 with TCL 8.4 and 8.6 (32-bit), and Linux kernel 2.4/2.6, all with UDP library (32-bit). UDP extension will not load if the TCL/TK build is 64-bit.

On startup, most of the code is read from separate module files (via source with error handlers). This modular design provides an easy mechanism to change portions of the code and read in short updated files to make the new code effective during runtime. This allows new PDU decoders to be refined and tested during application run. The main interface is a TK window containing a text widget to provide current statistics, with some clickable <fields> to perform actions. Reports are accessed via a menu in the GUI. Network activity is shown in horizontal scrolling text graph. Example:

Run time           : 1 hour 9 minutes 42 seconds
DIS Port           : 3000
Web URL            : http://localhost:80  <Close>
Filters            : Exercise 1
Entities           : 48,431  <Report>
Stale entities     : 18
Activity           : Current data
PDUs heard         : 2,619,428
PDU Rate          30s            60s            90s            120s
292  * **                                 * *                   
-    | || *     *       *  *       *      | |          **      *
-    | ||*|     |*     *|  |    ** |      |*|  *       ||   *  |
-    | ||||*    || * * ||  |  * || |   *  |||  |       ||  *|  |
-    | |||||    || |*| ||* |  | || |   |  |||**|  * *  ||* ||  |
-   *| |||||*  *|| |||*||| | *| || |   |  ||||||**| |* |||*||  |
-  *|| ||||||* ||| |||||||*|*|| ||*|*  |  ||||||||| || ||||||  |
1  *************************************************************
PDU                Name: Total      Pct   Display    Decode
1          Entity State: 2,385,721  91%  <No>       <Off>   
2                  Fire:    18,396   0%  <No>       <Decode>
3            Detonation:    18,375   0%  <No>       <Off>   
18           Data Query:     2,062   0%  <Display>  <Decode>
28                  IFF:    24,683   0%  <Display>  <Decode>
33      Aggregate State:    33,180   1%  <Display>  <Decode>
122  Logistics Resource:    25,747   0%  <Display>  <Decode>
137  Organization State:   103,740   3%  <Display>  <Decode>
161     Intercom Signal:     7,524   0%  <No>       <Decode>

History: Tool was heavily updated in August 2023 to decode more PDU types and display each PDU decoded to fields and further to textual meaning. The following are the decoders for each PDU using binary scan (listed here for reference):

PDU header (common to all PDU types)

binary scan $pdu ccu1cu1cu1Iu1Su1B8c \
        d(disver) d(exercise) d(pdukind) d(family) d(time) d(length) d(pdustatus) d(pad)
# PARSE TIMESTAMP
        # right shift integer then compute seconds
        set absolutetime [expr {$d(time) & 1}]
        set tint2 [expr {$d(time) >> 1}]
        set d(time) [expr {int(($tint2 * (0.5 + 3600000.0) / 0x7fffffff) / 1000)}]        ;# seconds
        if {$d(time) < 0} {set d(time) [expr {$d(time) % 3600}]}
        if {$absolutetime} {
                append d(time) " absolute time"
        } else {
                append d(time) " relative time [nice_time $d(time)]"
        }

1 Entity State

binary scan $pdu ccu1cu1cu1Iu1Su1B8cSu1Su1Su1cu1cu1ccScu1cu1cu1cu1ccScu1cu1cu1cu1IIIWWWIIIIcA39cA11I \
        d(disver) d(exercise) d(pdukind) d(family) d(time) d(length) d(pdustatus) d(pad) \
        d(site) d(host) d(ent) d(force) d(art) \
        d(kind) d(domain) d(country) d(cat) d(subcat) d(spec) d(extra) \
        d(altkind) d(altdomain) d(altcountry) d(altcat) d(altsubcat) d(altspec) d(altextra) \
        d(velx) d(vely) d(velz) d(locx) d(locy) d(locz) d(orientx) d(orienty) d(orientz) \
        d(appearance) d(dra) pad d(charset) d(marking) d(cap)

2 Fire

binary scan $pdu @12Su1Su1Su1Su1Su1Su1Su1Su1Su1Su1Su1Su1IWWWccSccccSSSSIIII \
        d(site) d(host) d(ent) d(tgtsite) d(tgthost) d(tgtent) \
        d(munsite) d(munhost) d(munent) d(evtsite) d(evthost) d(evtent) \
        d(mission) d(locx) d(locy) d(locz) \
        d(kind) d(domain) d(country) d(cat) d(subcat) d(spec) d(extra) \
        d(warhead) d(fuse) d(quantity) d(rate) d(velx) d(vely) d(velz) d(range)

3 Detonation

binary scan $pdu @12Su1Su1Su1Su1Su1Su1Su1Su1Su1Su1Su1Su1IIIWWWccSccccSSSSIIIccS \
        d(site) d(host) d(ent) d(tgtsite) d(tgthost) d(tgtent) \
        d(munsite) d(munhost) d(munent) d(evtsite) d(evthost) d(evtent) \
        d(velx) d(vely) d(velz) d(locx) d(locy) d(locz) \
        d(kind) d(domain) d(country) d(cat) d(subcat) d(spec) d(extra) \
        d(warhead) d(fuse) d(quantity) d(rate) d(entx) d(enty) d(entz) d(result) \
        d(parts) d(art)

4 Collision

binary scan $pdu @12Su1Su1Su1Su1Su1Su1Su1ccIIIIWWW \
        d(site) d(host) d(ent) d(collsite) d(collhost) d(collent) \
        d(eventid) d(colltype) pad d(velx) d(vely) d(velz) d(mass) d(locx) d(locy) d(locz)

18 Data Query

binary scan $pdu @12Su1Su1Su1Su1Su1Su1Iu1Iu1Iu1Iu1 \
        d(site) d(host) d(ent) d(rcvsite) d(rcvhost) d(rcvent) \
        d(msgnum) d(interval) d(numfixed) d(numvariable)

19 Set Data

binary scan $pdu @12Su1Su1Su1Su1Su1Su1IIII \
        d(site) d(host) d(entity) d(sitetgt) d(hosttgt) d(enttgt) \
        d(msgnum) d(pad) d(numfixed) d(numvariable)

23 Emission

binary scan $pdu @12Su1Su1Su1Su1Su1Su1ccSccSSu1ccIIIccSu1IIIIIIIIIIccccWSSScc \
        d(site) d(host) d(ent) d(siteevt) d(hostevt) d(entevt) \
        d(state) d(sysnum) pad d(syslen) d(beamnum) pad d(emitname) d(funcid) d(emitid) \
        d(locx) d(locy) d(locz) d(beamlen) d(beamid) d(beamndx) d(beamfreq) d(beamrange) \
        d(beamerpdb) d(beampulsefreq) d(beamplusewidth) d(beamazctr) d(beamazsweep) d(beamelctr) \
        d(beamelsweep) d(beamsweepsync) d(beamfunc) d(tgtnum) d(trackhd) pad d(jamtrack) \
        d(sitetrack) d(hosttrack) d(enttrack) d(jamemitid) d(jambeamid)

25 Transmitter

binary scan $pdu @12Su1Su1Su1Su1ccSu1ccccccSWWWIIISSIIffSSSSSSc \
        d(site) d(host) d(ent) d(radio) \
        d(kind) d(domain) d(country) d(cat) d(subcat) d(spec) d(extra) \
        d(state) d(source) pad \
        d(locx) d(locy) d(locz) d(entx) d(enty) d(entz) \
        d(antenna) d(antlen) d(freqhi) d(freqlo) d(band) d(power) \
        d(spectrum) d(modmajor) d(moddetail) d(system) \
        d(crypto) d(cryptokey) d(lenmod)

26 Signal

binary scan $pdu @12Su1Su1Su1Su1B16B16ISu1Su1B* \
        d(site) d(host) d(ent) d(radio) \
        d(enctype) d(tdl) d(rate) d(len) d(samples) d(data)

28 IFF / ATC / Navigational Aids

binary scan $pdu @12Su1Su1Su1Su1Su1Su1IIISScB8SB8cB8B8B16B16B16B16B16B16 \
        d(site) d(host) d(ent) d(eventsite) d(eventhost) d(evententity) \
        d(x) d(y) d(z) d(type) d(name) d(mode) d(option) pad \
        d(status) d(m4alt) d(info) d(modifier) \
        d(m1) d(m2) d(m3) d(m4) d(mcalt) d(ms)

33 Aggregate State

binary scan $pdu @12SSu1Su1ccccSu1ccccIcA31IIIIIIWWWIIIcccc \
        d(site) d(host) d(ent) d(force) d(state) \
        d(kind) d(domain) d(country) d(cat) d(subcat) d(spec) d(extra) \
        d(formation) d(charset) d(marking) \
        d(extentx) d(extenty) d(extentz) d(orientx) d(orienty) d(orientz) \
        d(locx) d(locy) d(locz) d(velx) d(vely) d(velz) \
        d(numdisaggs) d(numdisentities) d(numaggsystems) d(numentitysystems)

63

binary scan $pdu @12Su1Su1Su1Su1Su1Su1IccSII \
        d(site) d(host) d(ent)  d(tgtsite) d(tgthost) d(tgtent) \
        d(reqid) d(reliable) pad d(event) d(serial) d(numrecords)

67 Entity State Update

binary scan $pdu @12Su1Su1Su1IIIIWWWIIIII \
        d(site) d(host) d(ent) pad d(numparam) d(velx) d(vely) d(velz) d(locx) d(locy) d(locz) \
        d(orientx) d(orienty) d(orientz) d(appearance) d(artparams)

122 Logistics Resource

binary scan $pdu @12SSu1Su1SIIIIccA18IIIIccA18IIIIccA18 \
        d(site) d(host) d(ent) d(supplycount) \
        d(onhand1) d(auth1) d(reorder1) d(stockage1) d(class1) d(use1) d(id1) \
        d(onhand2) d(auth2) d(reorder2) d(stockage2) d(class2) d(use2) d(id2) \
        d(onhand3) d(auth3) d(reorder3) d(stockage3) d(class3) d(use3) d(id3)

137 Organizational State

binary scan $pdu @12Su1Su1Su1A12SA26A12A12A12A12A12A46A68ISSA12cA3SSA12cA7SSA12cA7 \
        d(site) d(host) d(ent) \
        d(subid) d(country) d(side) d(othechelon) d(othsymbol) d(othtype) \
        d(urn) d(uic) d(subname) d(jcatsname) d(orgid) d(tasksite) d(taskhost) d(taskid) d(numrel) pad \
        d(supsite1) d(suphost1) d(supid1) d(typerel1) pad \
        d(supsite2) d(suphost2) d(supid2) d(typerel2)

161 Intercom Signal

binary scan $pdu @12Su1Su1Su1Su1B16B16Iu1Su1Su1 \
        d(site1) d(host1) d(ent1) d(intnum) d(enctype) \
        d(tdl) d(sample) d(len) d(samples)

194 LOTS

binary scan $pdu @12Su1Su1Su1ccScu1cu1cu1cu1ccu1A30IIIWWWIIIA16SRcA32 \
        d(1) d(2) d(3) d(4) d(5) d(6) d(7) d(8) d(9) d(10) d(11) d(12) d(13) d(14) d(15) d(16) d(17) d(18) d(19) d(20) d(21) d(22) d(23) d(24) d(25) d(26) d(27)