Implemented the dhcpd lease entry decoder and the address decoder for the vmware builder.
This commit is contained in:
parent
efb775accb
commit
e2a7c317eb
|
@ -1,15 +1,19 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
/** low-level parsing */
|
/** low-level parsing */
|
||||||
|
@ -2233,3 +2237,119 @@ func consumeOpenClosePair(openByte, closeByte byte, in chan byte) ([]byte, chan
|
||||||
// the openByte and closeByte pair.
|
// the openByte and closeByte pair.
|
||||||
return result, out
|
return result, out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Basic decoding of a dhcpd lease address
|
||||||
|
func decodeDhcpdLeaseBytes(input string) ([]byte, error) {
|
||||||
|
processed := &bytes.Buffer{}
|
||||||
|
|
||||||
|
// Split the string into pieces as we'll need to validate it.
|
||||||
|
for _, item := range strings.Split(input, ":") {
|
||||||
|
if len(item) != 2 {
|
||||||
|
return []byte{}, fmt.Errorf("bytes are not well-formed (%v)", input)
|
||||||
|
}
|
||||||
|
processed.WriteString(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
length := hex.DecodedLen(processed.Len())
|
||||||
|
|
||||||
|
// Decode the processed data into the result...
|
||||||
|
result := make([]byte, length)
|
||||||
|
if n, err := hex.Decode(result, processed.Bytes()); err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
|
||||||
|
// Check that our decode length corresponds to what was intended
|
||||||
|
} else if n != length {
|
||||||
|
return []byte{}, fmt.Errorf("expected to decode %d bytes, got %d instead", length, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...and then return it.
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Dhcp Leases */
|
||||||
|
type dhcpLeaseEntry struct {
|
||||||
|
address string
|
||||||
|
starts, ends time.Time
|
||||||
|
ether, uid []byte
|
||||||
|
extra []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func readDhcpdLeaseEntry(in chan byte) (entry *dhcpLeaseEntry) {
|
||||||
|
|
||||||
|
// Build the regexes we'll use to legitimately parse each item
|
||||||
|
ipLineRe := regexp.MustCompile(`^lease (.+?) {$`)
|
||||||
|
startTimeLineRe := regexp.MustCompile(`^\s*starts \d (.+?);$`)
|
||||||
|
endTimeLineRe := regexp.MustCompile(`^\s*ends \d (.+?);$`)
|
||||||
|
macLineRe := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`)
|
||||||
|
uidLineRe := regexp.MustCompile(`^\s*uid (.+?);$`)
|
||||||
|
|
||||||
|
/// Read up to the lease item and validate that it actually matches
|
||||||
|
lease, ch := consumeOpenClosePair('{', '}', in)
|
||||||
|
|
||||||
|
matches := ipLineRe.FindStringSubmatch(string(lease))
|
||||||
|
if matches == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we found a lease match and we're definitely beginning a lease
|
||||||
|
// entry, then create our storage.
|
||||||
|
if by, ok := <-ch; ok && by == '{' {
|
||||||
|
entry = &dhcpLeaseEntry{address: matches[1]}
|
||||||
|
|
||||||
|
// Otherwise we bail.
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Now we can parse the inside of the block.
|
||||||
|
for insideBraces := true; insideBraces; {
|
||||||
|
item, ok := consumeUntilSentinel(';', in)
|
||||||
|
item_s := string(item)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
insideBraces = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse out the start time
|
||||||
|
matches = startTimeLineRe.FindStringSubmatch(item_s)
|
||||||
|
if matches != nil {
|
||||||
|
entry.starts, _ = time.Parse("2006/01/02 15:04:05", matches[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse out the end time
|
||||||
|
matches = endTimeLineRe.FindStringSubmatch(item_s)
|
||||||
|
if matches != nil {
|
||||||
|
entry.ends, _ = time.Parse("2006/01/02 15:04:05", matches[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse out the hardware ethernet
|
||||||
|
matches = macLineRe.FindStringSubmatch(item_s)
|
||||||
|
if matches != nil {
|
||||||
|
entry.ether, _ = decodeDhcpdLeaseBytes(item_s)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse out the uid
|
||||||
|
matches = uidLineRe.FindStringSubmatch(item_s)
|
||||||
|
if matches != nil {
|
||||||
|
entry.uid, _ = decodeDhcpdLeaseBytes(item_s)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just stash it for now because we have no idea what it is.
|
||||||
|
entry.extra = append(entry.extra, strings.TrimSpace(item_s))
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadDhcpdLeases(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!")
|
||||||
|
}
|
||||||
|
|
|
@ -634,3 +634,51 @@ func TestParserCombinators(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParserDhcpdLeaseBytesDecoder(t *testing.T) {
|
||||||
|
test_1 := "00:0d:0e:0a:0d:00"
|
||||||
|
expected_1 := []byte{0, 13, 14, 10, 13, 0}
|
||||||
|
|
||||||
|
result, err := decodeDhcpdLeaseBytes(test_1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to decode address: %s", err)
|
||||||
|
}
|
||||||
|
if bytes.Compare(result, expected_1) != 0 {
|
||||||
|
t.Errorf("expected %v, got %v", expected_1, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
test_2 := "11"
|
||||||
|
expected_2 := []byte{17}
|
||||||
|
|
||||||
|
result, err = decodeDhcpdLeaseBytes(test_2)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to decode address: %s", err)
|
||||||
|
}
|
||||||
|
if bytes.Compare(result, expected_2) != 0 {
|
||||||
|
t.Errorf("expected %v, got %v", expected_2, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
failtest_1 := ""
|
||||||
|
result, err = decodeDhcpdLeaseBytes(failtest_1)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expected decoding error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
failtest_2 := "000000"
|
||||||
|
result, err = decodeDhcpdLeaseBytes(failtest_2)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expected decoding error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
failtest_3 := "000:00"
|
||||||
|
result, err = decodeDhcpdLeaseBytes(failtest_3)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expected decoding error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
failtest_4 := "00:00:"
|
||||||
|
result, err = decodeDhcpdLeaseBytes(failtest_4)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expected decoding error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue