mirror of
https://github.com/maride/pancap.git
synced 2024-12-22 20:27:29 +00:00
Unify logging process
This commit is contained in:
parent
a368f18915
commit
e9ec8ad46c
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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
52
output/output.go
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user