Unify logging process

This commit is contained in:
maride 2019-12-03 23:51:03 +01:00
parent a368f18915
commit e9ec8ad46c
11 changed files with 124 additions and 72 deletions

View File

@ -16,15 +16,20 @@ func AppendIfUnique(appendee string, array []string) []string {
return append(array, appendee)
}
// Prints each element, along with a small ASCII tree
func PrintTree(strarr []string) {
// Generates a small ASCII tree for the given string array
func GenerateTree(strarr []string) string {
tmpstr := ""
// iterate over each element
for iter, elem := range strarr {
// check if we got the last element
if iter < len(strarr) - 1 {
fmt.Printf("|- %s\n", elem)
tmpstr = fmt.Sprintf("%s|- %s\n", tmpstr, elem)
} else {
fmt.Printf("'- %s\n\n", elem)
tmpstr = fmt.Sprintf( "%s'- %s\n", tmpstr, elem)
}
}
// Return constructed (grown?) tree
return tmpstr
}

View File

@ -3,7 +3,7 @@ package arp
import (
"fmt"
"git.darknebu.la/maride/pancap/common"
"github.com/fatih/color"
"git.darknebu.la/maride/pancap/output"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"log"
@ -52,15 +52,12 @@ func ProcessARPPacket(packet gopacket.Packet) error {
// Print a summary after all packets are processed
func PrintARPSummary() {
headline := color.New(color.FgRed, color.Bold)
headline.Println("ARP traffic summary")
printTrafficStats()
headline.Println("ARP LAN overview")
printLANOverview()
output.PrintBlock("ARP traffic summary", generateTrafficStats())
output.PrintBlock("ARP LAN overview", generateLANOverview())
}
// Constructs an answer regarding the ARP traffic
func printTrafficStats() {
// Generates an answer regarding the ARP traffic
func generateTrafficStats() string {
var tmparr []string
// Iterate over all participants
@ -82,11 +79,11 @@ func printTrafficStats() {
}
// And print it as a tree
common.PrintTree(tmparr)
return common.GenerateTree(tmparr)
}
// Prints an overview over all connected devices in the LAN
func printLANOverview() {
// Generates an overview over all connected devices in the LAN
func generateLANOverview() string {
var tmparr []string
// iterate over all devices
@ -95,7 +92,7 @@ func printLANOverview() {
}
// And print it as a tree
common.PrintTree(tmparr)
return common.GenerateTree(tmparr)
}
// Returns the arpStats object for the given MAC address, or creates a new one

View File

@ -1,7 +1,7 @@
package dhcpv4
import (
"github.com/fatih/color"
"git.darknebu.la/maride/pancap/output"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
@ -50,13 +50,8 @@ func HandleDHCPv4Packet(packet gopacket.Packet) error {
// Print summary after all packets are processed
func PrintDHCPv4Summary() {
headline := color.New(color.FgRed, color.Bold)
headline.Println("DHCP Network Overview")
printNetworkSummary()
headline.Println("DHCP Requests")
printRequestSummary()
headline.Println("DHCP Responses/Offers")
printResponseSummary()
headline.Println("DHCP Hostnames")
printHostnames()
output.PrintBlock("DHCP Network Overview", generateNetworkSummary())
output.PrintBlock("DHCP Requests", generateRequestSummary())
output.PrintBlock("DHCP Responses/Offers", generateResponseSummary())
output.PrintBlock("DHCP Hostnames", generateHostnamesSummary())
}

View File

@ -39,8 +39,8 @@ func checkForHostname(dhcppacket layers.DHCPv4) {
// None found, means client or server doesn't support Hostname option field. Ignore.
}
// Prints the list of all hostnames encountered.
func printHostnames() {
// Generates the list of all hostnames encountered.
func generateHostnamesSummary() string {
var tmparr []string
// Construct meaningful text
@ -72,7 +72,7 @@ func printHostnames() {
}
// and print it as a tree.
common.PrintTree(tmparr)
return common.GenerateTree(tmparr)
}
// Adds the given hostname to the hostname array, or patches an existing entry if found

View File

@ -140,14 +140,16 @@ func formatDate(rawDate []byte) string {
return formattedDate
}
// Prints the summary of relevant DHCP options
func printNetworkSummary() {
fmt.Printf("Subnet Mask: %s\n", formatIP(networkSetup[layers.DHCPOptSubnetMask]))
fmt.Printf("Broadcast: %s\n", formatIP(networkSetup[layers.DHCPOptBroadcastAddr]))
fmt.Printf("Router: %s\n", formatIP(networkSetup[layers.DHCPOptRouter]))
fmt.Printf("DNS Server: %s\n", formatIP(networkSetup[layers.DHCPOptDNS]))
fmt.Printf("NTP Server: %s\n", formatIP(networkSetup[layers.DHCPOptNTPServers]))
fmt.Printf("Lease Time: %s\n", formatDate(networkSetup[layers.DHCPOptLeaseTime]))
fmt.Printf("Renewal Time: %s\n", formatDate(networkSetup[layers.DHCPOptT1]))
// Generates the summary of relevant DHCP options
func generateNetworkSummary() string {
// It's also possible to use strings.Builder here, but it produces code which is longer than this solution :shrug:
summary := fmt.Sprintf("Subnet Mask: %s\n", formatIP(networkSetup[layers.DHCPOptSubnetMask]))
summary = fmt.Sprintf("%sBroadcast: %s\n", summary, formatIP(networkSetup[layers.DHCPOptBroadcastAddr]))
summary = fmt.Sprintf("%sRouter: %s\n", summary, formatIP(networkSetup[layers.DHCPOptRouter]))
summary = fmt.Sprintf("%sDNS Server: %s\n", summary, formatIP(networkSetup[layers.DHCPOptDNS]))
summary = fmt.Sprintf("%sNTP Server: %s\n", summary, formatIP(networkSetup[layers.DHCPOptNTPServers]))
summary = fmt.Sprintf("%sLease Time: %s\n", summary, formatDate(networkSetup[layers.DHCPOptLeaseTime]))
summary = fmt.Sprintf("%sRenewal Time: %s\n", summary, formatDate(networkSetup[layers.DHCPOptT1]))
return summary
}

View File

@ -15,8 +15,7 @@ func processRequestPacket(dhcppacket layers.DHCPv4) {
requestMAC = common.AppendIfUnique(dhcppacket.ClientHWAddr.String(), requestMAC)
}
// Prints the summary of all DHCP request packets
func printRequestSummary() {
fmt.Printf("%d unique DHCP requests\n", len(requestMAC))
common.PrintTree(requestMAC)
// Generates the summary of all DHCP request packets
func generateRequestSummary() string {
return fmt.Sprintf("%d unique DHCP requests\n%s", len(requestMAC), common.GenerateTree(requestMAC))
}

View File

@ -15,8 +15,8 @@ func processResponsePacket(dhcppacket layers.DHCPv4, ethernetpacket layers.Ether
addResponseEntry(dhcppacket.ClientIP.String(), dhcppacket.YourClientIP.String(), dhcppacket.ClientHWAddr.String(), ethernetpacket.SrcMAC.String())
}
// Prints the summary of all DHCP offer packets
func printResponseSummary() {
// Generates the summary of all DHCP offer packets
func generateResponseSummary() string {
var tmpaddr []string
// Iterate over all responses
@ -31,7 +31,7 @@ func printResponseSummary() {
}
// Draw as tree
common.PrintTree(tmpaddr)
return common.GenerateTree(tmpaddr)
}
// Adds a new response entry. If an IP address was already issued or a MAC asks multiple times for DNS, the case is examined further

View File

@ -62,29 +62,31 @@ func processDNSAnswer(answers []layers.DNSResourceRecord) {
}
}
// Prints a summary of all DNS answers
func printDNSAnswerSummary() {
// Generates a summary of all DNS answers
func generateDNSAnswerSummary() string {
summary := ""
// Overall question stats
fmt.Printf("%d DNS answers in total\n", numAnswers)
fmt.Printf("%s records\n", generateDNSTypeSummary(answerType))
fmt.Printf("%d unique domains of %d base domains, of which are %d private (non-ICANN) TLDs.\n", len(answerDomains), len(answerBaseDomains), len(answerPrivateDomains))
summary = fmt.Sprintf("%s%d DNS answers in total\n", summary, numAnswers)
summary = fmt.Sprintf("%s%s records\n", summary, generateDNSTypeSummary(answerType))
summary = fmt.Sprintf("%s%d unique domains of %d base domains, of which are %d private (non-ICANN) TLDs.\n", summary, len(answerDomains), len(answerBaseDomains), len(answerPrivateDomains))
// Output base domains answered with
if len(answerBaseDomains) > 0 {
fmt.Println("Answered with these base domains:")
common.PrintTree(answerBaseDomains)
summary = fmt.Sprintf("Answered with these base domains:\n%s", common.GenerateTree(answerBaseDomains))
}
// Output private domains
if len(answerPrivateDomains) > 0 {
fmt.Println("Answered with these private (non-ICANN managed) domains:")
common.PrintTree(answerPrivateDomains)
summary = fmt.Sprintf("%sAnswered with these private (non-ICANN managed) domains:\n%s", summary, common.GenerateTree(answerPrivateDomains))
}
// Check for public and private IPs
fmt.Printf("Answered with %d public IP addresses and %d private IP addresses\n", len(answerPublicIPv4), len(answerPrivateIPv4))
summary = fmt.Sprintf("%sAnswered with %d public IP addresses and %d private IP addresses\n", summary, len(answerPublicIPv4), len(answerPrivateIPv4))
if len(answerPrivateIPv4) > 0 {
fmt.Println("Private IP addresses in answer:")
common.PrintTree(answerPrivateIPv4)
summary = fmt.Sprintf("%sPrivate IP addresses in answer:\n%s", summary, common.GenerateTree(answerPrivateIPv4))
}
// Return summary
return summary
}

View File

@ -1,7 +1,7 @@
package dns
import (
"github.com/fatih/color"
"git.darknebu.la/maride/pancap/output"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
@ -27,9 +27,6 @@ func ProcessDNSPacket(packet gopacket.Packet) error {
// Print a summary after all DNS packets were processed
func PrintDNSSummary() {
headline := color.New(color.FgRed, color.Bold)
headline.Println("DNS Request Summary")
printDNSQuestionSummary()
headline.Println("DNS Response Summary")
printDNSAnswerSummary()
output.PrintBlock("DNS Request Summary", generateDNSQuestionSummary())
output.PrintBlock("DNS Response Summary", generateDNSAnswerSummary())
}

View File

@ -51,22 +51,25 @@ func processDNSQuestion(questions []layers.DNSQuestion) {
}
}
// Prints a summary of all DNS questions
func printDNSQuestionSummary() {
// Generates a summary of all DNS questions
func generateDNSQuestionSummary() string {
summary := ""
// Overall question stats
fmt.Printf("%d DNS questions in total\n", numQuestions)
fmt.Printf("%s records\n", generateDNSTypeSummary(questionType))
fmt.Printf("%d unique domains of %d base domains, of which are %d private (non-ICANN) TLDs.\n", len(questionDomains), len(questionBaseDomains), len(questionPrivateDomains))
summary = fmt.Sprintf("%s%d DNS questions in total\n", summary, numQuestions)
summary = fmt.Sprintf("%s%s records\n", summary, generateDNSTypeSummary(questionType))
summary = fmt.Sprintf("%s%d unique domains of %d base domains, of which are %d private (non-ICANN) TLDs.\n", summary, len(questionDomains), len(questionBaseDomains), len(questionPrivateDomains))
// Output base domains asked for
if len(questionBaseDomains) > 0 {
fmt.Println("Asked for these base domains:")
common.PrintTree(questionBaseDomains)
summary = fmt.Sprintf("%sAsked for these base domains:\n%s", summary, common.GenerateTree(questionBaseDomains))
}
// Output private domains
if len(questionPrivateDomains) > 0 {
fmt.Println("Asked for these private (non-ICANN managed) domains:")
common.PrintTree(questionPrivateDomains)
summary = fmt.Sprintf("%sAsked for these private (non-ICANN managed) domains:\n%s", summary, common.GenerateTree(questionPrivateDomains))
}
// And return summary
return summary
}

52
output/output.go Normal file
View File

@ -0,0 +1,52 @@
package output
import (
"fmt"
"github.com/fatih/color"
)
const (
MaxContentLines = 50
)
// Prints a block of information with the given headline
// If content is empty, printing the headline is omitted.
// If the content is longer than MaxContentLines, content is cut.
func PrintBlock(headline string, content string) {
// Print a newline to add some space between blocks
fmt.Println("")
// Check if we need to print a headline
if len(content) > 0 {
// We have content, we can print the headline
headlineColor := color.New(color.FgRed, color.Bold)
headlineColor.Println(headline)
}
// Cut to MaxContentLines if required
cutCont := cutContent(content)
fmt.Print(cutCont)
}
// Cut content after MaxContentLines lines
func cutContent(content string) string {
numNewlines := 0
// iterate over every character
for i, c := range content {
// check if character is newline
if c == '\n' {
// it is, count occurrence
numNewlines++
// Check if we already hit our limit yet
if numNewlines == MaxContentLines {
// Found nth newline, return content up to this position.
return content[:i+1] // +1 to include the last newline as well
}
}
}
// We are done before reaching the cut limit; return the whole content
return content
}