Compare commits

...

6 Commits

32 changed files with 254 additions and 151 deletions

View File

@ -1,5 +1,7 @@
# pancap # pancap
<img alt="pancap logo" src="pancap.png" width="250px" height="250px">
## Idea ## Idea
If you get access to a [PCAP](https://en.wikipedia.org/wiki/Pcap) file, for example during a CTF or captured on your own, you usually have the problem of overlooking all the relevant information to get a basic idea of the capture file. This gets worse if the capture file includes lots of white noise or irrelevant traffic - often included in the capture file to cloak *interesting* packets in a bunch of packets to YouTube, Reddit, Twitter and others. If you get access to a [PCAP](https://en.wikipedia.org/wiki/Pcap) file, for example during a CTF or captured on your own, you usually have the problem of overlooking all the relevant information to get a basic idea of the capture file. This gets worse if the capture file includes lots of white noise or irrelevant traffic - often included in the capture file to cloak *interesting* packets in a bunch of packets to YouTube, Reddit, Twitter and others.
@ -10,7 +12,7 @@ If you get access to a [PCAP](https://en.wikipedia.org/wiki/Pcap) file, for exam
Simply run Simply run
`go get git.darknebu.la/maride/pancap` `go get github.com/maride/pancap`
This will also build `pancap` and place it into your `GOBIN` directory - means you can directly execute it! This will also build `pancap` and place it into your `GOBIN` directory - means you can directly execute it!

View File

@ -2,15 +2,16 @@ package analyze
import ( import (
"fmt" "fmt"
"git.darknebu.la/maride/pancap/output"
"git.darknebu.la/maride/pancap/protocol"
"github.com/google/gopacket"
"log" "log"
"github.com/google/gopacket"
"github.com/maride/pancap/output"
"github.com/maride/pancap/protocol"
) )
var ( var (
// Store total amount and amount of visited packets // Store total amount and amount of visited packets
totalPackets int totalPackets int
processedPackets int processedPackets int
) )
@ -39,6 +40,9 @@ func Analyze(source *gopacket.PacketSource) error {
} }
} }
// Register communication for graph
output.AddPkgToGraph(packet)
// Raise statistics // Raise statistics
totalPackets += 1 totalPackets += 1
if processed { if processed {
@ -68,4 +72,3 @@ func handleErr(err error) {
log.Printf("Encountered error while examining packets, continuing anyway. Error: %s", err.Error()) log.Printf("Encountered error while examining packets, continuing anyway. Error: %s", err.Error())
} }
} }

View File

@ -1,42 +0,0 @@
package main
import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"testing"
)
func Test_analyzePCAP(t *testing.T) {
type args struct {
source *gopacket.PacketSource
linkType layers.LinkType
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Faulty link type",
args: args{
source: &gopacket.PacketSource{
DecodeOptions: gopacket.DecodeOptions{
Lazy: false,
NoCopy: false,
SkipDecodeRecovery: false,
DecodeStreamsAsDatagrams: false,
},
},
linkType: 2,
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := analyzePCAP(tt.args.source, tt.args.linkType); (err != nil) != tt.wantErr {
t.Errorf("analyzePCAP() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

View File

@ -23,10 +23,10 @@ func GenerateTree(strarr []string) string {
// iterate over each element // iterate over each element
for iter, elem := range strarr { for iter, elem := range strarr {
// check if we got the last element // check if we got the last element
if iter < len(strarr) - 1 { if iter < len(strarr)-1 {
tmpstr = fmt.Sprintf("%s├ %s\n", tmpstr, elem) tmpstr = fmt.Sprintf("%s├ %s\n", tmpstr, elem)
} else { } else {
tmpstr = fmt.Sprintf( "%s╰ %s\n", tmpstr, elem) tmpstr = fmt.Sprintf("%s╰ %s\n", tmpstr, elem)
} }
} }

11
file.go
View File

@ -3,29 +3,30 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap" "github.com/google/gopacket/pcap"
) )
var ( var (
filenameFlag *string filenameFlag string
) )
// Registers the flag --file // Registers the flag --file
func registerFileFlags() { func registerFileFlags() {
filenameFlag = flag.String("file", "", "PCAP file to base analysis on") flag.StringVar(&filenameFlag, "file", "", "PCAP file to base analysis on")
} }
// Opens the PCAP, returns its packets and the link type or an error // Opens the PCAP, returns its packets and the link type or an error
func openPCAP() (*gopacket.PacketSource, layers.LinkType, error) { func openPCAP() (*gopacket.PacketSource, layers.LinkType, error) {
// Check if we even got a file. // Check if we even got a file.
if *filenameFlag == "" { if filenameFlag == "" {
return nil, 0, fmt.Errorf("missing file to analyze. Please specifiy it with --file") return nil, 0, fmt.Errorf("missing file to analyze. Please specifiy it with --file")
} }
// Open specified file // Open specified file
handle, openErr := pcap.OpenOffline(*filenameFlag) handle, openErr := pcap.OpenOffline(filenameFlag)
if openErr != nil { if openErr != nil {
// There were some problems opening the file // There were some problems opening the file
return nil, 0, openErr return nil, 0, openErr
@ -37,4 +38,4 @@ func openPCAP() (*gopacket.PacketSource, layers.LinkType, error) {
// Open given handle as packet source and return it // Open given handle as packet source and return it
packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
return packetSource, handle.LinkType(), nil return packetSource, handle.LinkType(), nil
} }

2
go.mod
View File

@ -1,4 +1,4 @@
module git.darknebu.la/maride/pancap module github.com/maride/pancap
go 1.13 go 1.13

12
main.go
View File

@ -3,11 +3,12 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"git.darknebu.la/maride/pancap/analyze"
"git.darknebu.la/maride/pancap/output"
"log" "log"
"math/rand" "math/rand"
"time" "time"
"github.com/maride/pancap/analyze"
"github.com/maride/pancap/output"
) )
func main() { func main() {
@ -36,6 +37,9 @@ func main() {
// Extract found and requested files // Extract found and requested files
output.StoreFiles() output.StoreFiles()
// Create communication graph
output.CreateGraph()
// Show user analysis // Show user analysis
analyze.PrintSummary() analyze.PrintSummary()
@ -53,13 +57,13 @@ func printMOTD() {
"PanCAP: Analyzer for pancake files", "PanCAP: Analyzer for pancake files",
"You want some syrup with these packets?", "You want some syrup with these packets?",
"Check out CONTRIBUTORS.md!", "Check out CONTRIBUTORS.md!",
"Push your commits to git.darknebu.la/maride/pancap", "Push your commits to github.com/maride/pancap",
"Don't let the white noise traffic confuse you.", "Don't let the white noise traffic confuse you.",
"Grab a Club Mate if you don't have one yet.", "Grab a Club Mate if you don't have one yet.",
"In Soviet Russia, traffic analyzes you.", "In Soviet Russia, traffic analyzes you.",
"Who captures the captors?", "Who captures the captors?",
"Respect other's privacy. Always.", "Respect other's privacy. Always.",
"Make public data available, protect private data.", // https://www.ccc.de/en/hackerethik "Make public data available, protect private data.", // https://www.ccc.de/en/hackerethik
"Most traffic is just there to confuse the russians.", // hat-tip to twitter.com/_harryr_ "Most traffic is just there to confuse the russians.", // hat-tip to twitter.com/_harryr_
} }

View File

@ -6,10 +6,10 @@ import (
) )
type File struct { type File struct {
name string name string
content []byte content []byte
origin string origin string
hash string hash string
} }
// Creates a new file object and calculates the hash of the given content // Creates a new file object and calculates the hash of the given content
@ -21,4 +21,4 @@ func NewFile(name string, content []byte, origin string) File {
origin: origin, origin: origin,
hash: hash, hash: hash,
} }
} }

View File

@ -2,17 +2,18 @@ package output
import ( import (
"fmt" "fmt"
"git.darknebu.la/maride/pancap/common"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"strings" "strings"
"github.com/maride/pancap/common"
) )
var ( var (
registeredFiles []File registeredFiles []File
notFound []string notFound []string
extractedFiles int extractedFiles int
) )
// Registers a file with the given name and content. // Registers a file with the given name and content.
@ -20,12 +21,18 @@ var (
// This means that a module should _always_ call this function when a file is encountered. // This means that a module should _always_ call this function when a file is encountered.
// origin is a descriptive string where the file comes from, e.g. the module name. // origin is a descriptive string where the file comes from, e.g. the module name.
func RegisterFile(filename string, content []byte, origin string) { func RegisterFile(filename string, content []byte, origin string) {
// Check if there even is anything to register
if len(content) == 0 {
// File is empty, won't register the void
log.Printf("Avoided registering file from %s because it is empty.", origin)
return
}
thisFile := NewFile(filename, content, origin) thisFile := NewFile(filename, content, origin)
// To avoid doubles, we need to check if that hash is already present // To avoid doubles, we need to check if that hash is already present
for _, f := range registeredFiles { for _, f := range registeredFiles {
if f.hash == thisFile.hash { if f.hash == thisFile.hash {
// Found - stop here // Found - stop here
log.Printf("Avoided registering file '%s' because it has the same content as an already registered file ", f.name) log.Printf("Avoided registering file from %s because it has the same content as an already registered file ", origin)
return return
} }
} }
@ -39,12 +46,12 @@ func StoreFiles() {
var filesToExtract []File var filesToExtract []File
// Check different flag scenarios // Check different flag scenarios
if *targetAllFiles { if targetAllFiles {
// We should extract all files. // We should extract all files.
filesToExtract = registeredFiles filesToExtract = registeredFiles
} else { } else {
// We should extract only a given set of files // We should extract only a given set of files
fileList := strings.Split(*targetFiles, ",") fileList := strings.Split(targetFiles, ",")
for _, f := range fileList { for _, f := range fileList {
// Iterate over desired files // Iterate over desired files
found := false found := false
@ -73,7 +80,7 @@ func StoreFiles() {
// Writes the given file object to disk, along with a stats file placed next to it. // Writes the given file object to disk, along with a stats file placed next to it.
func writeOut(f File) { func writeOut(f File) {
targetName := fmt.Sprintf("%s%c%s", *targetOutput, os.PathSeparator, f.hash) targetName := fmt.Sprintf("%s%c%s", targetOutput, os.PathSeparator, f.hash)
targetDescName := fmt.Sprintf("%s.info", targetName) targetDescName := fmt.Sprintf("%s.info", targetName)
targetDescription := fmt.Sprintf("Filename: %s\nHash: %s\nOrigin: %s\nSize: %d", f.name, f.hash, f.origin, len(f.content)) targetDescription := fmt.Sprintf("Filename: %s\nHash: %s\nOrigin: %s\nSize: %d", f.name, f.hash, f.origin, len(f.content))

View File

@ -3,19 +3,19 @@ package output
import "flag" import "flag"
var ( var (
fullOutput *bool fullOutput bool
printEmptyBlocks *bool printEmptyBlocks bool
targetFiles *string targetFiles string
targetAllFiles *bool targetAllFiles bool
targetOutput *string targetOutput string
graphOutput string
) )
func RegisterFlags() { func RegisterFlags() {
fullOutput = flag.Bool("full-output", false, "Show full output instead of limiting submodule output") flag.BoolVar(&fullOutput, "full-output", false, "Show full output instead of limiting submodule output")
printEmptyBlocks = flag.Bool("print-empty-blocks", false, "Prints blocks (submodule output) even if the submodule doesn't have any content to print.") flag.BoolVar(&printEmptyBlocks, "print-empty-blocks", false, "Prints blocks (submodule output) even if the submodule doesn't have any content to print.")
targetFiles = flag.String("extract-these", "", "Comma-separated list of files to extract.") flag.StringVar(&targetFiles, "extract-these", "", "Comma-separated list of files to extract.")
targetAllFiles = flag.Bool("extract-all", false, "Extract all files found.") flag.BoolVar(&targetAllFiles, "extract-all", false, "Extract all files found.")
targetOutput = flag.String("extract-to", "./extracted", "Directory to store extracted files in.") flag.StringVar(&targetOutput, "extract-to", "./extracted", "Directory to store extracted files in.")
flag.StringVar(&graphOutput, "create-graph", "", "Create a Graphviz graph out of collected communication")
} }

103
output/graph.go Normal file
View File

@ -0,0 +1,103 @@
package output
import (
"crypto/sha256"
"fmt"
"io/ioutil"
"github.com/google/gopacket"
)
var graphPkgs []GraphPkg
// AddPkgToGraph adds the given packet as communication to the graph
func AddPkgToGraph(pkg gopacket.Packet) {
// Only proceed if pkg contains a network layer
if pkg.NetworkLayer() == nil {
return
}
src := pkg.NetworkLayer().NetworkFlow().Src().String()
dst := pkg.NetworkLayer().NetworkFlow().Dst().String()
// Search for the given communication pair
for _, p := range graphPkgs {
if p.from == src && p.to == dst {
// Communication pair found, add protocol and finish
p.AddProtocol("nil")
return
}
}
// Communcation pair was not in graphPkgs, add to it
graphPkgs = append(graphPkgs, GraphPkg{
from: src,
to: dst,
protocol: []string{""},
})
}
// CreateGraph writes out a Graphviz digraph
func CreateGraph() {
if graphOutput == "" {
// No graph requested
return
}
// Start with the Graphviz-specific header
dot := fmt.Sprintf("# Compile with `neato -Tpng %s > %s.png`\n", graphOutput, graphOutput)
dot += "digraph pancap {\n\toverlap = false;\n"
// First, gather all nodes as-is and write them out
dot += nodedef(graphPkgs)
// Iterate over communication
for _, p := range graphPkgs {
dot += fmt.Sprintf("\tn%s->n%s\n", hash(p.from), hash(p.to))
}
// Close
dot += "}\n"
// Write out
ioutil.WriteFile(graphOutput, []byte(dot), 0644)
}
// Creates a list of distinct nodes, Graphviz-compatible
func nodedef(pkgs []GraphPkg) string {
output := ""
nodes := []string{}
for _, p := range graphPkgs {
// Check if src and dst are already present in nodes array
srcFound := false
dstFound := false
for _, n := range nodes {
if p.from == n {
srcFound = true
}
if p.to == n {
dstFound = true
}
}
if !srcFound {
// src not yet present, add to node list
nodes = append(nodes, p.from)
}
if !dstFound {
// dst not yet present, add to node list
nodes = append(nodes, p.to)
}
}
// Output Graphviz-compatible node definition
for _, n := range nodes {
// As the Graphviz charset for nodes is rather small, rely on hashes
output += fmt.Sprintf("\tn%s[label=\"%s\"]\n", hash(n), n)
}
return output
}
func hash(s string) string {
return fmt.Sprintf("%x", sha256.Sum256([]byte(s)))[:6]
}

19
output/graphpkg.go Normal file
View File

@ -0,0 +1,19 @@
package output
// GraphPkg resembles a directed communication from one address to another
// It wraps up required information to draw a graph of the communication, including spoken protocols.
type GraphPkg struct {
from string
to string
protocol []string
}
// AddProtocol adds the given protocol to the list of protocols if not already present
func (p *GraphPkg) AddProtocol(protocol string) {
for _, p := range p.protocol {
if p == protocol {
return
}
}
p.protocol = append(p.protocol, protocol)
}

View File

@ -23,4 +23,10 @@ func Finalize() {
// User avoided the files // User avoided the files
printer.Println("Files found in stream. Add --extract-all or --extract-these <list> to extract them.") printer.Println("Files found in stream. Add --extract-all or --extract-these <list> to extract them.")
} }
// Check if something graph-worthy was collected
if graphOutput == "" && len(graphPkgs) > 0 {
// User didn't want a graph
printer.Println("To summarize the communcation flow with a Graphviz graph, specify --create-graph <out.dot>.")
}
} }

View File

@ -2,17 +2,18 @@ package output
import ( import (
"fmt" "fmt"
"github.com/fatih/color"
"strings" "strings"
"github.com/fatih/color"
) )
const ( const (
MaxContentLines = 50 MaxContentLines = 50
SnipMark = "----- cut at 50 entries -----" SnipMark = "----- cut at 50 entries -----"
) )
var ( var (
DidSnip bool DidSnip bool
DidAvoidEmptyBlock bool DidAvoidEmptyBlock bool
) )
@ -21,7 +22,7 @@ var (
// If the content is longer than MaxContentLines, content is cut. // If the content is longer than MaxContentLines, content is cut.
func PrintBlock(headline string, content string) { func PrintBlock(headline string, content string) {
// Avoid printing empty blocks - at least if user didn't specify it otherwise // Avoid printing empty blocks - at least if user didn't specify it otherwise
if len(content) == 0 && !*printEmptyBlocks { if len(content) == 0 && !printEmptyBlocks {
// No content and we are not forced to print empty blocks, return // No content and we are not forced to print empty blocks, return
DidAvoidEmptyBlock = true DidAvoidEmptyBlock = true
return return
@ -38,7 +39,7 @@ func PrintBlock(headline string, content string) {
} }
// Cut to MaxContentLines if required // Cut to MaxContentLines if required
if !(*fullOutput) { if !(fullOutput) {
// User states that they don't want to see the whole output - cut content. // User states that they don't want to see the whole output - cut content.
content = cutContent(content) content = cutContent(content)
} }

BIN
pancap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

View File

@ -2,24 +2,24 @@ package arp
import ( import (
"fmt" "fmt"
"git.darknebu.la/maride/pancap/common"
"git.darknebu.la/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"github.com/maride/pancap/output"
"log" "log"
"net" "net"
) )
var ( var (
arpStatsList []arpStats arpStatsList []arpStats
devices []arpDevice devices []arpDevice
linkLocalBlock = net.IPNet{ linkLocalBlock = net.IPNet{
IP: net.IPv4(169, 254, 0, 0), IP: net.IPv4(169, 254, 0, 0),
Mask: net.IPv4Mask(255, 255, 0, 0), Mask: net.IPv4Mask(255, 255, 0, 0),
} }
) )
type Protocol struct {} type Protocol struct{}
// Checks if the given packet is an ARP packet we can process // Checks if the given packet is an ARP packet we can process
func (p *Protocol) CanAnalyze(packet gopacket.Packet) bool { func (p *Protocol) CanAnalyze(packet gopacket.Packet) bool {
@ -118,7 +118,7 @@ func (p *Protocol) getStatOrCreate(macaddr string) *arpStats {
// None found yet, we need to create a new one // None found yet, we need to create a new one
arpStatsList = append(arpStatsList, arpStats{ arpStatsList = append(arpStatsList, arpStats{
macaddr: macaddr, macaddr: macaddr,
}) })
// And return it // And return it

View File

@ -2,5 +2,5 @@ package arp
type arpDevice struct { type arpDevice struct {
macaddr string macaddr string
ipaddr string ipaddr string
} }

View File

@ -1,9 +1,9 @@
package arp package arp
type arpStats struct { type arpStats struct {
macaddr string macaddr string
asked int asked int
answered int answered int
askedList []string askedList []string
answeredList []string answeredList []string
} }

View File

@ -1,16 +1,16 @@
package dhcpv4 package dhcpv4
import ( import (
"git.darknebu.la/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/output"
) )
type Protocol struct { type Protocol struct {
hostnames []hostname hostnames []hostname
networkSetup map[layers.DHCPOpt][]byte networkSetup map[layers.DHCPOpt][]byte
requestMAC []string requestMAC []string
responses []dhcpResponse responses []dhcpResponse
} }
// Checks if the given packet is a DHCP packet we can process // Checks if the given packet is a DHCP packet we can process

View File

@ -1,9 +1,8 @@
package dhcpv4 package dhcpv4
type dhcpResponse struct { type dhcpResponse struct {
destMACAddr string destMACAddr string
newIPAddr string newIPAddr string
serverMACAddr string serverMACAddr string
askedFor bool askedFor bool
} }

View File

@ -1,8 +1,8 @@
package dhcpv4 package dhcpv4
type hostname struct { type hostname struct {
hostname string hostname string
requestedByMAC string requestedByMAC string
granted bool granted bool
deniedHostname string deniedHostname string
} }

View File

@ -2,8 +2,8 @@ package dhcpv4
import ( import (
"fmt" "fmt"
"git.darknebu.la/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"log" "log"
) )

View File

@ -12,13 +12,13 @@ import (
var ( var (
watchedOpts = []layers.DHCPOpt{ watchedOpts = []layers.DHCPOpt{
layers.DHCPOptSubnetMask, // Option 1 layers.DHCPOptSubnetMask, // Option 1
layers.DHCPOptRouter, // Option 3 layers.DHCPOptRouter, // Option 3
layers.DHCPOptDNS, // Option 6 layers.DHCPOptDNS, // Option 6
layers.DHCPOptBroadcastAddr, // Option 28 layers.DHCPOptBroadcastAddr, // Option 28
layers.DHCPOptNTPServers, // Option 42 layers.DHCPOptNTPServers, // Option 42
layers.DHCPOptLeaseTime, // Option 51 layers.DHCPOptLeaseTime, // Option 51
layers.DHCPOptT1, // Option 58 layers.DHCPOptT1, // Option 58
} }
) )
@ -126,7 +126,7 @@ func formatDate(rawDate []byte) (string, bool) {
intDate := binary.LittleEndian.Uint32(rawDate) intDate := binary.LittleEndian.Uint32(rawDate)
seconds := intDate % 60 seconds := intDate % 60
minutes := intDate / 60 % 60 minutes := intDate / 60 % 60
hours := intDate / 60 / 60 % 60 hours := intDate / 60 / 60 % 60
formattedDate := "" formattedDate := ""
// Check which words we need to pick // Check which words we need to pick

View File

@ -2,8 +2,8 @@ package dhcpv4
import ( import (
"fmt" "fmt"
"git.darknebu.la/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
) )
// Processes the DHCP request packet handed over // Processes the DHCP request packet handed over

View File

@ -2,8 +2,8 @@ package dhcpv4
import ( import (
"fmt" "fmt"
"git.darknebu.la/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"log" "log"
) )

View File

@ -2,20 +2,20 @@ package dns
import ( import (
"fmt" "fmt"
"git.darknebu.la/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"golang.org/x/net/publicsuffix" "golang.org/x/net/publicsuffix"
"log" "log"
) )
var ( var (
numAnswers int numAnswers int
answerDomains []string answerDomains []string
answerBaseDomains []string answerBaseDomains []string
answerPrivateDomains []string answerPrivateDomains []string
answerType = make(map[layers.DNSType]int) answerType = make(map[layers.DNSType]int)
answerPublicIPv4 []string answerPublicIPv4 []string
answerPrivateIPv4 []string answerPrivateIPv4 []string
) )
// Called on every DNS packet to process response(s) // Called on every DNS packet to process response(s)

View File

@ -8,7 +8,7 @@ import (
var ( var (
privateBlocks = []net.IPNet{ privateBlocks = []net.IPNet{
{net.IPv4(10, 0, 0, 0), net.IPv4Mask(255, 0, 0, 0)}, // 10.0.0.0/8 {net.IPv4(10, 0, 0, 0), net.IPv4Mask(255, 0, 0, 0)}, // 10.0.0.0/8
{net.IPv4(172, 16, 0, 0), net.IPv4Mask(255, 240, 0, 0)}, // 172.16.0.0/12 {net.IPv4(172, 16, 0, 0), net.IPv4Mask(255, 240, 0, 0)}, // 172.16.0.0/12
{net.IPv4(192, 168, 0, 0), net.IPv4Mask(255, 255, 0, 0)}, // 192.168.0.0/24 {net.IPv4(192, 168, 0, 0), net.IPv4Mask(255, 255, 0, 0)}, // 192.168.0.0/24
{net.IPv4(100, 64, 0, 0), net.IPv4Mask(255, 192, 0, 0)}, // 100.64.0.0/10 {net.IPv4(100, 64, 0, 0), net.IPv4Mask(255, 192, 0, 0)}, // 100.64.0.0/10
@ -58,7 +58,7 @@ func (p *Protocol) generateDNSTypeSummary(typearr map[layers.DNSType]int) string
if iter == 0 { if iter == 0 {
// We don't need to append yet // We don't need to append yet
answerstr = elem answerstr = elem
} else if iter == len(answerarr) - 1 { } else if iter == len(answerarr)-1 {
// Last element, use "and" instead of a comma // Last element, use "and" instead of a comma
answerstr = fmt.Sprintf("%s and %s", answerstr, elem) answerstr = fmt.Sprintf("%s and %s", answerstr, elem)
} else { } else {
@ -68,4 +68,4 @@ func (p *Protocol) generateDNSTypeSummary(typearr map[layers.DNSType]int) string
} }
return answerstr return answerstr
} }

View File

@ -1,12 +1,12 @@
package dns package dns
import ( import (
"git.darknebu.la/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/output"
) )
type Protocol struct {} type Protocol struct{}
func (p *Protocol) CanAnalyze(packet gopacket.Packet) bool { func (p *Protocol) CanAnalyze(packet gopacket.Packet) bool {
return packet.Layer(layers.LayerTypeDNS) != nil return packet.Layer(layers.LayerTypeDNS) != nil

View File

@ -2,18 +2,18 @@ package dns
import ( import (
"fmt" "fmt"
"git.darknebu.la/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"golang.org/x/net/publicsuffix" "golang.org/x/net/publicsuffix"
"log" "log"
) )
var ( var (
numQuestions int numQuestions int
questionDomains []string questionDomains []string
questionBaseDomains []string questionBaseDomains []string
questionPrivateDomains []string questionPrivateDomains []string
questionType = make(map[layers.DNSType]int) questionType = make(map[layers.DNSType]int)
) )
// Called on every DNS packet to process questions // Called on every DNS packet to process questions
@ -72,4 +72,4 @@ func (p *Protocol) generateDNSQuestionSummary() string {
// And return summary // And return summary
return summary return summary
} }

View File

@ -1,20 +1,20 @@
package http package http
import ( import (
"git.darknebu.la/maride/pancap/common"
"git.darknebu.la/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/google/gopacket/tcpassembly" "github.com/google/gopacket/tcpassembly"
"github.com/maride/pancap/common"
"github.com/maride/pancap/output"
) )
type Protocol struct { type Protocol struct {
initialized bool initialized bool
requestFactory *httpRequestFactory requestFactory *httpRequestFactory
responseFactory *httpResponseFactory responseFactory *httpResponseFactory
requestPool *tcpassembly.StreamPool requestPool *tcpassembly.StreamPool
responsePool *tcpassembly.StreamPool responsePool *tcpassembly.StreamPool
requestAssembler *tcpassembly.Assembler requestAssembler *tcpassembly.Assembler
responseAssembler *tcpassembly.Assembler responseAssembler *tcpassembly.Assembler
} }

View File

@ -3,17 +3,17 @@ package http
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"git.darknebu.la/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/tcpassembly" "github.com/google/gopacket/tcpassembly"
"github.com/google/gopacket/tcpassembly/tcpreader" "github.com/google/gopacket/tcpassembly/tcpreader"
"github.com/maride/pancap/output"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
) )
var ( var (
responseSummaryLines []string responseSummaryLines []string
) )
type httpResponseFactory struct{} type httpResponseFactory struct{}

View File

@ -1,10 +1,10 @@
package protocol package protocol
import ( import (
"git.darknebu.la/maride/pancap/protocol/arp" "github.com/maride/pancap/protocol/arp"
"git.darknebu.la/maride/pancap/protocol/dhcpv4" "github.com/maride/pancap/protocol/dhcpv4"
"git.darknebu.la/maride/pancap/protocol/dns" "github.com/maride/pancap/protocol/dns"
"git.darknebu.la/maride/pancap/protocol/http" "github.com/maride/pancap/protocol/http"
) )
var ( var (