While pondering why darkstat all of a sudden shows corrupted timestamps when running on FreeBSD/amd64 stable/9, I wrote a small program to decode the export format. The program is available using

svn co svn://svn.ximalas.info/darkstattype

or http://svnweb.ximalas.info/darkstattype/. The license is the 2-clause BSD license.

Everything is shown correct in the web interface when darkstat starts without reading any export file. As soon as darkstat has written its export file, the computer has been rebooted, and darkstat later reads that file back into memory, the corruption is very visible in the timestamps shown in the web interface:

(clock error: now = 1181, last = 18446744073707737811)

It’s interesting to take a closer look at the “last” value. 18446744073707737811 in decimal, is 0xFFFFFFFFFFE452D3 in hexadecimal. Could this strange value be the result of a negative value, expressed as a 64-bit signed integer, and finally interpreted as a 64-bit unsigned integer? Interpreted as a 64-bit signed integer yields -1813805. Further interpretation as seconds yields a time difference of close to -21 days.

Inspection of the darkstat source code reveals that darkstat has deviated from the format specified in the export-format.txt file. darkstat writes the lastseen timestamp ahead of the MAC address. Luckily, darkstat reads the file the same way, so its handling of the export file is consistent at least. I have made the necessary changes to my own program.

Here’s a censored sample of my program’s output:

File header 0xda314159
  Section header host_db v1 0xda485301
    Host count 2
    Host #1 of 2:
      Host header v3 0x48535403
        IPv4 address family (0x04)
        IPv4 address 157.56.93.40
        Last seen 0x532875d1 = 1395160529 = 2014-03-18T16:35:29+0000
        MAC address 00:17:e0:77:14:45
        Hostname length 34
        Hostname msnbot-157-56-93-40.search.msn.com
        Bytes in 552
        Bytes out 476
        IP Proto count 1
          Protocol #1 of 1:
            Protocol 0x06
            In 552
            Out 476
        TCP proto count 1
          Port 29300:
            SYN 0
            In 552
            Out 476
        UDP proto count 0
    Host #2 of 2:
      Host header v3 0x48535403
        IPv6 address family (0x06)
        IPv6 address fe80:0000:0000:0000:0217:e0ff:fe77:1445
        Last seen 0x532aaba4 = 1395305380 = 2014-03-20T08:49:40+0000
        MAC address 00:17:e0:77:14:45
        Hostname length 12
        Hostname (link-local)
        Bytes in 501120
        Bytes out 650984
        IP Proto count 0
        TCP proto count 0
        UDP proto count 0
  Section header graph_db v1 0xda475201
    Last time 0x532875e9 = 1395160553 = 2014-03-18T16:35:53+0000
    Graph #1 of 4:
      Number of bars 60
      Index of last bar 53
        Bar #1 of 53:
          In 0
          Out 0
        Bar #2 of 53:
          In 0
          Out 0
        Bar #3 of 53:
          In 0
          Out 412316860416
        Bar #4 of 53:
          In 687194767360
          Out 309237645312
        Bar #5 of 53:
          In 0
          Out 0
        Bar #6 of 53:
          In 618475290624
          Out 592705486848
        Bar #7 of 53:
          In 0
          Out 0
        Bar #8 of 53:
          In 326417514496
          Out 171798691840
        Bar #9 of 53:
          In 1546188226560
          Out 927712935936
        Bar #10 of 53:
          In 0
          Out 0
        Bar #11 of 53:
          In 0
          Out 0
        Bar #12 of 53:
          In 0
          Out 0
        Bar #13 of 53:
          In 0
          Out 0
        Bar #14 of 53:
          In 0
          Out 0
        Bar #15 of 53:
          In 0
          Out 0
        Bar #16 of 53:
          In 0
          Out 0
        Bar #17 of 53:
          In 2284922601472
          Out 223338299392
        Bar #18 of 53:
          In 7314329305088
          Out 13602161426432
        Bar #19 of 53:
          In 0
          Out 0
        Bar #20 of 53:
          In 554050781184
          Out 485331304448
        Bar #21 of 53:
          In 0
          Out 0
        Bar #22 of 53:
          In 0
          Out 0
        Bar #23 of 53:
          In 412316860416
          Out 412316860416
        Bar #24 of 53:
          In 0
          Out 0
        Bar #25 of 53:
          In 0
          Out 0
        Bar #26 of 53:
          In 0
          Out 0
        Bar #27 of 53:
          In 309237645312
          Out 274877906944
        Bar #28 of 53:
          In 807453851648
          Out 687194767360
        Bar #29 of 53:
          In 3848290697216
          Out 2602750181376
        Bar #30 of 53:
          In 2456721293312
          Out 223338299392
        Bar #31 of 53:
          In 6764573491200
          Out 7490422964224
        Bar #32 of 53:
          In 687194767360
          Out 6158983102464
        Bar #33 of 53:
          In 2272037699584
          Out 223338299392
        Bar #34 of 53:
          In 5570572582912
          Out 7425998454784
        Bar #35 of 53:
          In 343597383680
          Out 5987184410624
        Bar #36 of 53:
          In 0
          Out 0
        Bar #37 of 53:
          In 0
          Out 0
        Bar #38 of 53:
          In 326417514496
          Out 171798691840
        Bar #39 of 53:
          In 2284922601472
          Out 2284922601472
        Bar #40 of 53:
          In 1649267441664
          Out 1305670057984
        Bar #41 of 53:
          In 498216206336
          Out 326417514496
        Bar #42 of 53:
          In 996432412672
          Out 790273982464
        Bar #43 of 53:
          In 824633720832
          Out 790273982464
        Bar #44 of 53:
          In 1580547964928
          Out 6786048327680
        Bar #45 of 53:
          In 171798691840
          Out 0
        Bar #46 of 53:
          In 0
          Out 0
        Bar #47 of 53:
          In 0
          Out 0
        Bar #48 of 53:
          In 0
          Out 0
        Bar #49 of 53:
          In 910533066752
          Out 755914244096
        Bar #50 of 53:
          In 652835028992
          Out 343597383680
        Bar #51 of 53:
          In 0
          Out 0
        Bar #52 of 53:
          In 0
          Out 0
        Bar #53 of 53:
          In 1047972020224
          Out 2095944040448
    Graph #2 of 4:
      Number of bars 0
      Index of last bar 0
    Graph #3 of 4:
      Number of bars 0
      Index of last bar 0
    Graph #4 of 4:
      Number of bars 0
      Index of last bar 0

The file format and the contents turns out to be sound after all. How come darkstat misinterprets the stored timestamps? A system reboot is the only thing that provokes this bad attitude, simply restarting the darkstat process without a reboot produces no ill side effects. The monotonic time corresponds in reality to the system’s uptime, at least in FreeBSD and quite possibly in every POSIX compliant system.

In conjunction with darkstats’s author, Emil Mikulic, we gather that darkstat’s fails to take negative values into account, both when doing the necessary arithmetic on monotonic time, and when formatting such values for use in the web interface. Improvements might appear within the next few weeks. Stay tuned.