Finished implementing the final dhcpd lease entries parser for the vmware builders and also included its own unit tests.

This commit is contained in:
Ali Rizvi-Santiago 2020-05-28 03:08:50 -05:00
parent cf5332fa20
commit 020b005522
3 changed files with 178 additions and 4 deletions

View File

@ -2290,6 +2290,12 @@ func readDhcpdLeaseEntry(in chan byte) (entry *dhcpLeaseEntry, err error) {
/// Read up to the lease item and validate that it actually matches
lease, ch := consumeOpenClosePair('{', '}', in)
// If we couldn't read the lease, then this item is busted and we're prolly
// done reading the channel.
if len(lease) == 0 {
return nil, nil
}
matches := ipLineRe.FindStringSubmatch(string(lease))
if matches == nil {
res := strings.TrimSpace(string(lease))
@ -2303,7 +2309,7 @@ func readDhcpdLeaseEntry(in chan byte) (entry *dhcpLeaseEntry, err error) {
} else if ok {
// If we didn't see a begin brace, then this entry is mangled which
// means that we should probably ail
// means that we should probably bail
return &dhcpLeaseEntry{address: matches[1]}, fmt.Errorf("Missing parameters for lease entry %v", matches[1])
} else if !ok {
@ -2375,11 +2381,37 @@ func readDhcpdLeaseEntry(in chan byte) (entry *dhcpLeaseEntry, err error) {
return entry, nil
}
func ReadDhcpdLeases(fd *os.File) ([]dhcpLeaseEntry, error) {
func ReadDhcpdLeaseEntries(fd *os.File) ([]dhcpLeaseEntry, error) {
fch := consumeFile(fd)
uncommentedch := uncomment(fch)
wch := filterOutCharacters([]byte{'\n', '\r', '\v'}, uncommentedch)
close(wch)
return []dhcpLeaseEntry{}, fmt.Errorf("Not implemented yet!")
result := make([]dhcpLeaseEntry, 0)
errors := make([]error, 0)
// Consume dhcpd lease entries from the channel until we just plain run out.
for i := 0; ; i += 1 {
if entry, err := readDhcpdLeaseEntry(wch); entry == nil {
// If our entry is nil, then we've run out of input and finished
// parsing the file to completion.
break
} else if err != nil {
// If we received an error, then log it and keep track of it. This
// way we can warn the user later which entries we had issues with.
log.Printf("Error parsing dhcpd lease entry #%d: %s", 1+i, err)
errors = append(errors, err)
} else {
// If we've parsed an entry successfully, then aggregate it to
// our slice of results.
result = append(result, *entry)
}
}
// If we received any errors then include alongside our results.
if len(errors) > 0 {
return result, fmt.Errorf("Errors found while parsing dhcpd lease entries: %v", errors)
}
return result, nil
}

View File

@ -746,3 +746,113 @@ func TestParserReadDhcpdLeaseEntry(t *testing.T) {
t.Errorf("expected ends weekday %v, got %v", 57005, result.ends_weekday)
}
}
func TestParserReadDhcpdLeases(t *testing.T) {
f, err := os.Open(filepath.Join("testdata", "dhcpd-example.leases"))
if err != nil {
t.Fatalf("Unable to open dhcpd.leases sample: %s", err)
}
defer f.Close()
results, err := ReadDhcpdLeaseEntries(f)
if err != nil {
t.Fatalf("Error reading lease: %s", err)
}
// some simple utilities
filter_address := func(address string, items []dhcpLeaseEntry) (result []dhcpLeaseEntry) {
for _, item := range items {
if item.address == address {
result = append(result, item)
}
}
return
}
find_uid := func(uid string, items []dhcpLeaseEntry) *dhcpLeaseEntry {
for _, item := range items {
if uid == hex.EncodeToString(item.uid) {
return &item
}
}
return nil
}
find_ether := func(ether string, items []dhcpLeaseEntry) *dhcpLeaseEntry {
for _, item := range items {
if ether == hex.EncodeToString(item.ether) {
return &item
}
}
return nil
}
// actual unit tests
test_1 := map[string]string{
"address": "127.0.0.19",
"uid": "010dead099aabb",
"ether": "0dead099aabb",
}
test_1_findings := filter_address(test_1["address"], results)
if len(test_1_findings) != 2 {
t.Errorf("expected %d matching entries, got %d", 2, len(test_1_findings))
} else {
res := find_ether(test_1["ether"], test_1_findings)
if res == nil {
t.Errorf("unable to find item with ether %v", test_1["ether"])
} else if hex.EncodeToString(res.uid) != test_1["uid"] {
t.Errorf("expected uid %s, got %s", test_1["uid"], hex.EncodeToString(res.uid))
}
}
test_2 := map[string]string{
"address": "127.0.0.19",
"uid": "010dead0667788",
"ether": "0dead0667788",
}
test_2_findings := filter_address(test_2["address"], results)
if len(test_2_findings) != 2 {
t.Errorf("expected %d matching entries, got %d", 2, len(test_2_findings))
} else {
res := find_ether(test_2["ether"], test_2_findings)
if res == nil {
t.Errorf("unable to find item with ether %v", test_2["ether"])
} else if hex.EncodeToString(res.uid) != test_2["uid"] {
t.Errorf("expected uid %s, got %s", test_2["uid"], hex.EncodeToString(res.uid))
}
}
test_3 := map[string]string{
"address": "127.0.0.17",
"uid": "010dead0334455",
"ether": "0dead0667788",
}
test_3_findings := filter_address(test_3["address"], results)
if len(test_3_findings) != 2 {
t.Errorf("expected %d matching entries, got %d", 2, len(test_3_findings))
} else {
res := find_uid(test_3["uid"], test_3_findings)
if res == nil {
t.Errorf("unable to find item with uid %v", test_3["uid"])
} else if hex.EncodeToString(res.ether) != test_3["ether"] {
t.Errorf("expected ethernet hardware %s, got %s", test_3["ether"], hex.EncodeToString(res.ether))
}
}
test_4 := map[string]string{
"address": "127.0.0.17",
"uid": "010dead0001122",
"ether": "0dead0667788",
}
test_4_findings := filter_address(test_4["address"], results)
if len(test_4_findings) != 2 {
t.Errorf("expected %d matching entries, got %d", 2, len(test_4_findings))
} else {
res := find_uid(test_4["uid"], test_4_findings)
if res == nil {
t.Errorf("unable to find item with uid %v", test_4["uid"])
} else if hex.EncodeToString(res.ether) != test_4["ether"] {
t.Errorf("expected ethernet hardware %s, got %s", test_4["ether"], hex.EncodeToString(res.ether))
}
}
}

View File

@ -0,0 +1,32 @@
# This entry is normal
lease 127.0.0.17 {
starts 3 2020/05/13 12:00:37;
ends 3 2020/05/13 12:30:37;
hardware ethernet 0d:ea:d0:66:77:88;
uid 01:0d:ea:d0:00:11:22;
}
# This entry has tabs
lease 127.0.0.17 {
starts 6 2020/06/12 22:28:54;
ends 6 2020/06/12 22:58:54;
hardware ethernet 0d:ea:d0:66:77:88;
uid 01:0d:ea:d0:33:44:55;
}
# These next two entries have the same address, but different uids
lease 127.0.0.19 {
starts 4 2020/05/28 11:35:06;
ends 4 2020/05/28 12:05:06;
hardware ethernet 0d:ea:d0:66:77:88;
uid 01:0d:ea:d0:66:77:88;
client-hostname "VAGRANT-ADA-LUZ";
}
lease 127.0.0.19 {
starts 5 2020/08/20 20:32:03;
ends 5 2020/08/20 21:02:03;
hardware ethernet 0d:ea:d0:99:aa:bb;
uid 01:0d:ea:d0:99:aa:bb;
client-hostname "WINDOWS-SQABBAS";
}