-
Notifications
You must be signed in to change notification settings - Fork 7
/
main.go
145 lines (131 loc) · 3.06 KB
/
main.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
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"context"
"curses"
"log"
"net"
"os"
"os/signal"
"syscall"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/pcap"
)
const (
white_blk int = iota + 1
yellow_blk
red_blk
green_blk
white_blue
blk_white
)
func winEnd() {
curses.Endwin()
}
func winInit() {
curses.Initscr()
curses.Start_color()
curses.Init_pair(white_blk, curses.COLOR_WHITE, curses.COLOR_BLACK)
curses.Init_pair(yellow_blk, curses.COLOR_YELLOW, curses.COLOR_BLACK)
curses.Init_pair(red_blk, curses.COLOR_RED, curses.COLOR_BLACK)
curses.Init_pair(green_blk, curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.Init_pair(white_blue, curses.COLOR_WHITE, curses.COLOR_BLUE)
curses.Init_pair(blk_white, curses.COLOR_BLACK, curses.COLOR_WHITE)
go listenKeys()
}
var itfcs []net.Interface
var exit context.CancelFunc
var tabSwitch = make(chan int)
func main() {
//f, _ := os.Create(fmt.Sprintf("profile_file_%v", time.Now().Unix()))
//pprof.StartCPUProfile(f) // 开始cpu profile,结果写到文件f中
//defer pprof.StopCPUProfile() // 结束profile
if os.Geteuid() != 0 {
log.Fatal("ag must run as root.")
}
errFile, _ := os.OpenFile("stack", os.O_WRONLY|os.O_APPEND|os.O_CREATE|os.O_SYNC, 0644)
syscall.Dup2(int(errFile.Fd()), 2)
winInit()
itfcs, _ = net.Interfaces()
for _, itfc := range itfcs {
M.GetIface(itfc.Name)
//ctx, cancel := context.WithCancel(context.Background())
//go listenPacket(itfc.Name, ctx)
//cancels = append(cancels, cancel)
}
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGHUP, syscall.SIGINT)
tick := time.Tick(time.Second * 1)
if len(itfcs) > 0 {
ctx, cancel := context.WithCancel(context.Background())
exit = cancel
go listenPacket(itfcs[0].Name, ctx)
} else {
signalChan <- syscall.SIGINT
}
for {
select {
case <-tabSwitch:
M.Dump()
case <-tick:
M.Dump()
case <-signalChan:
exit()
goto END
}
}
END:
winEnd()
}
func listenPacket(iface string, ctx context.Context) {
handle, err := pcap.OpenLive(iface, 65536, true, pcap.BlockForever)
if err != nil {
log.Fatal("pcap打开失败:", err)
}
handle.SetBPFFilter("udp || tcp")
defer handle.Close()
ps := gopacket.NewPacketSource(handle, handle.LinkType())
for {
select {
case <-ctx.Done():
return
case p := <-ps.Packets():
M.AddPacket(iface, p)
}
}
}
func listenKeys() {
curses.Noecho()
var ch int
win := curses.Stdwin
for {
ch = win.Getch()
switch ch {
case 65: //up
if curIfacePrintStart > 0 {
curIfacePrintStart--
}
case 66: //down
if curIface < len(M.ifaces) && len(M.ifaces[curIface].IPV4PTPFlows) > curIfacePrintStart {
curIfacePrintStart++
}
case 67: //right
case 68: //left
curIfacePrintStart = 0
case 9: //tab
if curIface+1 >= len(M.ifaces) {
curIface = 0
} else {
curIface++
}
exit()
ctx, cancel := context.WithCancel(context.Background())
exit = cancel
go listenPacket(itfcs[curIface].Name, ctx)
tabSwitch <- 1
default:
//log.Printf("keydown %v", ch)
//log.Printf("cols:%d,rows:%d", *curses.Cols, *curses.Rows)
}
}
}