-
Notifications
You must be signed in to change notification settings - Fork 0
/
peng.go
133 lines (112 loc) · 2.98 KB
/
peng.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package peng
import (
"log"
"net"
"os"
"os/signal"
"sync/atomic"
"syscall"
"time"
"github.com/google/gopacket"
_ "github.com/google/gopacket/layers" // Used to init internal struct
"github.com/google/gopacket/pcap"
"github.com/alessio-perugini/peng/pkg/portbitmap"
"github.com/alessio-perugini/peng/pkg/storage"
)
type Peng struct {
Config Config
ClientTraffic, ServerTraffic *portbitmap.PortBitmap
}
type Config struct {
NumberOfBin uint
SizeBitmap uint
NumberOfBits uint
NetworkInterface string
Verbose uint
TimeFrame time.Duration
Storages []storage.Storage
MyIPs []net.IP
}
func New(cfg Config) *Peng {
cfg.NumberOfBits = cfg.SizeBitmap / cfg.NumberOfBin
bitmapConfig := portbitmap.Config{
NumberOfBin: cfg.NumberOfBin,
SizeBitmap: cfg.SizeBitmap,
NumberOfBits: cfg.NumberOfBits,
}
return &Peng{
Config: cfg,
ClientTraffic: portbitmap.New(bitmapConfig),
ServerTraffic: portbitmap.New(bitmapConfig),
}
}
func (p *Peng) Start(pHandle *pcap.Handle) {
defer pHandle.Close()
var isLive uint32
atomic.StoreUint32(&isLive, 1)
shutdownDone := make(chan bool, 1)
go func() {
packet := gopacket.NewPacketSource(pHandle, pHandle.LinkType())
t := time.AfterFunc(p.Config.TimeFrame, p.handler)
for packet := range packet.Packets() {
if atomic.LoadUint32(&isLive) == 0 {
break
}
p.inspect(packet)
}
t.Stop()
shutdownDone <- true
}()
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
<-sig
atomic.StoreUint32(&isLive, 0)
<-shutdownDone
for _, v := range p.Config.Storages {
v.Stop()
}
log.Println("Quitting Peng, bye!")
}
func (p *Peng) printAllInfo(client, server *portbitmap.PortBitmap) {
allPortTraffic := []*portbitmap.PortBitmap{client, server}
for i, v := range allPortTraffic {
if p.Config.Verbose == 3 {
log.Println(v)
log.Println("Bit set: ")
for j := 0; j < len(v.InnerBitmap); j++ {
log.Println("bin number [", j, "] num (bit at 1): ", v.InnerBitmap[j].GetBitSets())
}
}
if p.Config.Verbose >= 1 {
if i == 0 {
log.Printf("[%s] [CLIENT] ", time.Now().Local().String())
} else {
log.Printf("[%s] [SERVER] ", time.Now().Local().String())
}
}
if p.Config.Verbose >= 2 {
log.Printf("entropy of each bin: %f\n", v.EntropyOfEachBin())
}
if p.Config.Verbose >= 1 {
log.Printf("total entropy: %f\n", v.EntropyTotal())
}
}
}
func (p *Peng) handler() {
cTotalEntropy, sTotalEntropy := p.ClientTraffic.EntropyTotal(), p.ServerTraffic.EntropyTotal()
for _, v := range p.Config.Storages {
go func(v storage.Storage) {
if err := v.Push(cTotalEntropy, sTotalEntropy); err != nil {
log.Println(err)
}
}(v)
}
if p.Config.Verbose >= 1 {
p.printAllInfo(p.ClientTraffic, p.ServerTraffic)
}
// Clear bitmap for the new reader
p.ClientTraffic.ClearAll()
p.ServerTraffic.ClearAll()
// Wait timeframe time, before further actions
time.AfterFunc(p.Config.TimeFrame, p.handler)
}