DNS TTL blogpost
package main | |
import ( | |
"bufio" | |
"encoding/json" | |
"flag" | |
"fmt" | |
"log" | |
"os" | |
"strconv" | |
"time" | |
) | |
type ProbeInfo struct { | |
ReportedTimes map[int64]TimeReport | |
UsedResolvers map[string]int | |
} | |
type TimeReport struct { | |
FirstSeen int | |
LastSeen int | |
} | |
type RipeData struct { | |
From string `json:"from"` | |
PrbID int `json:"prb_id"` | |
Resultset []struct { | |
Result struct { | |
Answers []struct { | |
NAME string `json:"NAME"` | |
RDATA []string `json:"RDATA"` | |
TYPE string `json:"TYPE"` | |
} `json:"answers"` | |
Rt float64 `json:"rt"` | |
Size float64 `json:"size"` | |
} `json:"result"` | |
Time float64 `json:"time"` | |
DstAddr string `json:"dst_addr"` | |
} `json:"resultset"` | |
Timestamp int `json:"timestamp"` | |
Type string `json:"type"` | |
} | |
func main() { | |
detailedmode := flag.Bool("detailed", false, "Print individual values") | |
csvmode := flag.Bool("csv", false, "Print results as CSV") | |
flag.Parse() | |
f, err := os.Open(flag.Arg(0)) | |
if err != nil { | |
log.Fatalf("unable to open file, %s", err.Error()) | |
} | |
probes := make(map[int]ProbeInfo) | |
reader := bufio.NewReader(f) | |
for { | |
lnb, _, err := reader.ReadLine() | |
if err != nil { | |
break | |
} | |
datapoint := RipeData{} | |
err = json.Unmarshal(lnb, &datapoint) | |
if err != nil { | |
log.Printf("Unable to decode data point %s", err.Error()) | |
continue | |
} | |
if len(datapoint.Resultset) != 0 && | |
len(datapoint.Resultset[0].Result.Answers) != 0 && | |
len(datapoint.Resultset[0].Result.Answers[0].RDATA) != 0 { | |
i, err := strconv.ParseInt(datapoint.Resultset[0].Result.Answers[0].RDATA[0], 10, 64) | |
if err != nil { | |
continue | |
} | |
if probes[datapoint.PrbID].ReportedTimes == nil { | |
tmp := probes[datapoint.PrbID] | |
tmp.ReportedTimes = make(map[int64]TimeReport) | |
tmp.UsedResolvers = make(map[string]int) | |
probes[datapoint.PrbID] = tmp | |
} | |
probes[datapoint.PrbID].UsedResolvers[datapoint.Resultset[0].DstAddr]++ | |
rt := probes[datapoint.PrbID].ReportedTimes | |
if rt[i].FirstSeen == 0 { | |
rttmp := TimeReport{} | |
rttmp.FirstSeen = datapoint.Timestamp | |
rt[i] = rttmp | |
} else if rt[i].LastSeen < datapoint.Timestamp { | |
rttmp := rt[i] | |
rttmp.LastSeen = datapoint.Timestamp | |
rt[i] = rttmp | |
} else if rt[i].FirstSeen > datapoint.Timestamp { | |
rttmp := rt[i] | |
rttmp.FirstSeen = datapoint.Timestamp | |
rt[i] = rttmp | |
} | |
} | |
} | |
if *csvmode { | |
fmt.Print("timeheld,probeid,resolvers\n") | |
} | |
for probeid, probedata := range probes { | |
if !(*csvmode) { | |
fmt.Printf("For Probe ID %d:\n", probeid) | |
fmt.Printf("Resolvers %v\n", probedata.UsedResolvers) | |
} | |
recordTime := 0.0 | |
for timestamp, tsdata := range probedata.ReportedTimes { | |
if tsdata.LastSeen == 0 { | |
if *detailedmode { | |
fmt.Printf("\tFor value %d, never got cached\n", timestamp) | |
} | |
} else { | |
fs := time.Unix(int64(tsdata.FirstSeen), 0) | |
ls := time.Unix(int64(tsdata.LastSeen), 0) | |
between := ls.Sub(fs) | |
if *detailedmode { | |
fmt.Printf("\tFor value %d, was in cache for %f min\n", timestamp, between.Minutes()) | |
} | |
if between.Minutes() > recordTime { | |
recordTime = between.Minutes() | |
} | |
} | |
} | |
if !(*csvmode) { | |
fmt.Printf("For Probe ID %d held on at best for %f min\n\n", probeid, recordTime) | |
} else { | |
fmt.Printf("%0.f,%d,%v\r\n", recordTime, probeid, probedata.UsedResolvers) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment