/
beacon.go
107 lines (93 loc) · 2.75 KB
/
beacon.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
package main
import "fmt"
import "math/rand"
import "os"
import "os/signal"
import "time"
import kafka "github.com/Shopify/sarama"
import geoip "github.com/oschwald/geoip2-golang"
import "net"
import "flag"
func producer(ints chan<- uint32, set []uint32, duration time.Duration) {
for {
ints <- set[rand.Intn(len(set))]
time.Sleep(duration)
}
}
func intToIP(i uint32) string {
a := (byte(i >> 24))
b := (byte(i >> 16))
c := (byte(i >> 8))
d := (byte(i))
str := fmt.Sprintf("%d.%d.%d.%d", a, b, c, d)
return str
}
func consumer(src <-chan uint32, dst <-chan uint32, producer kafka.AsyncProducer) {
topic := "network"
db, err := geoip.Open("GeoLite2-City.mmdb")
if err != nil {
fmt.Println(err)
}
defer db.Close()
for {
src_ip := <-src
src_str := intToIP(src_ip)
dst_ip := <-dst
dst_str := intToIP(dst_ip)
src_ip_parsed := net.ParseIP(src_str)
dst_ip_parsed := net.ParseIP(dst_str)
src_record, err := db.City(src_ip_parsed)
if err != nil {
fmt.Println(err)
}
dst_record, err := db.City(dst_ip_parsed)
if err != nil {
fmt.Println(err)
}
src_coords := fmt.Sprintf("[%v,%v]", src_record.Location.Latitude, src_record.Location.Longitude)
dst_coords := fmt.Sprintf("[%v,%v]", dst_record.Location.Latitude, dst_record.Location.Longitude)
t := time.Now()
current_time := fmt.Sprintf("%d-%02d-%02dT%02d:%02d:%02d-00:00",
t.Year(), t.Month(), t.Day(),
t.Hour(), t.Minute(), t.Second())
if (src_coords == "0,0") || dst_coords == "0,0" {
continue
}
str := src_str + "," + dst_str + "," + "\"" + src_coords + "\"" + "," + "\"" + dst_coords + "\"" + "," + current_time
fmt.Println(str)
message := kafka.ProducerMessage{Topic: topic, Value: kafka.StringEncoder(str)}
producer.Input() <- &message
}
}
func main() {
var host = flag.String("kafka", "127.0.0.1:9092", "IP address:port of kafka")
var beacon = flag.Int("duration", 300,"amount of time to sleep between beacons")
flag.Parse()
duration := time.Duration(*beacon) * time.Second
src := make(chan uint32)
dst := make(chan uint32)
notify := make(chan os.Signal, 1)
signal.Notify(notify, os.Interrupt, os.Kill)
config := kafka.NewConfig()
config.Producer.Return.Successes = true
k_producer, err := kafka.NewAsyncProducer([]string{*host}, config)
if err != nil {
panic(err)
}
fmt.Println("src_ip,dst_ip,src_coord,dst_coord,received_at")
//srcs are data center IPs
srcs := []uint32{1222977025}
bads := []uint32{1979570743, 3134782395}
go producer(src, srcs, duration)
go producer(dst, bads, duration)
go consumer(src, dst, k_producer)
//you must read the producer.Successes() or else the producer will block.
go func(producer kafka.AsyncProducer) {
for {
<-producer.Successes()
}
}(k_producer)
s := <-notify
fmt.Println("signal:", s)
fmt.Println("done.")
}