-
Notifications
You must be signed in to change notification settings - Fork 7
/
packetd.go
201 lines (161 loc) · 5.46 KB
/
packetd.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
package main
//#include "common.h"
//#include "netfilter.h"
//#include "conntrack.h"
//#include "netlogger.h"
//#cgo LDFLAGS: -lnetfilter_queue -lnfnetlink -lnetfilter_conntrack -lnetfilter_log
import "C"
import "os"
import "time"
import "sync"
import "bufio"
import "unsafe"
import "github.com/untangle/packetd/support"
import "github.com/untangle/packetd/example"
import "github.com/untangle/packetd/classify"
import "github.com/untangle/packetd/geoip"
/*---------------------------------------------------------------------------*/
/*
* The childsync is used to give the main process something to watch while
* waiting for all of the goroutine children to finish execution and cleanup.
* To give C child functions access we export go_child_startup and goodbye
* functions. For children in normal go packages, we pass the WaitGroup
* directly to the goroutine.
*/
var childsync sync.WaitGroup
/*---------------------------------------------------------------------------*/
func main() {
var counter int
C.common_startup()
support.LogMessage("Untangle Packet Daemon Version %s\n", "1.00")
go C.netfilter_thread()
go C.conntrack_thread()
go C.netlogger_thread()
// ********** Call all plugin startup functions here
go example.Plugin_Startup(&childsync)
go classify.Plugin_Startup(&childsync)
go geoip.Plugin_Startup(&childsync)
// ********** End of plugin startup functions
ch := make(chan string)
go func(ch chan string) {
reader := bufio.NewReader(os.Stdin)
for {
s, err := reader.ReadString('\n')
if err != nil {
close(ch)
return
}
ch <- s
}
close(ch)
}(ch)
support.LogMessage("RUNNING ON CONSOLE - HIT ENTER TO EXIT\n")
stdinloop:
for {
shutdown := C.get_shutdown_flag()
if shutdown != 0 {
break
}
select {
case stdin, ok := <-ch:
if !ok {
break stdinloop
} else {
support.LogMessage("Console input detected - Application shutting down\n")
_ = stdin
break stdinloop
}
case <-time.After(1 * time.Second):
counter++
// support.LogMessage("Waiting for input %d...\n", counter)
}
}
// ********** Call all plugin goodbye functions here
go example.Plugin_Goodbye(&childsync)
go classify.Plugin_Goodbye(&childsync)
go geoip.Plugin_Goodbye(&childsync)
// ********** End of plugin goodbye functions
C.netfilter_goodbye()
C.conntrack_goodbye()
C.netlogger_goodbye()
childsync.Wait()
}
/*---------------------------------------------------------------------------*/
//export go_netfilter_callback
func go_netfilter_callback(mark C.int, data *C.uchar, size C.int) int32 {
// this version creates a Go copy of the buffer
// buffer := C.GoBytes(unsafe.Pointer(data),size)
// this version creates a Go pointer to the buffer
buffer := (*[0xFFFF]byte)(unsafe.Pointer(data))[:int(size):int(size)]
length := int(size)
// ********** Call all plugin netfilter handler functions here
c1 := make(chan int32)
go example.Plugin_netfilter_handler(c1, buffer, length)
c2 := make(chan int32)
go classify.Plugin_netfilter_handler(c2, buffer, length)
c3 := make(chan int32)
go geoip.Plugin_netfilter_handler(c3, buffer, length)
// ********** End of plugin netfilter callback functions
// get the existing mark on the packet
var pmark int32 = int32(C.int(mark))
// add the mark bits returned from each package handler
for i := 0; i < 2; i++ {
select {
case mark1 := <-c1:
pmark |= mark1
case mark2 := <-c2:
pmark |= mark2
case mark3 := <-c3:
pmark |= mark3
}
}
// return the updated mark to be set on the packet
return (pmark)
}
/*---------------------------------------------------------------------------*/
//export go_conntrack_callback
func go_conntrack_callback(info *C.struct_conntrack_info) {
var tracker support.Tracker
tracker.Orig_src_addr = uint32(info.orig_saddr)
tracker.Repl_src_addr = uint32(info.repl_saddr)
tracker.Orig_dst_addr = uint32(info.orig_daddr)
tracker.Repl_dst_addr = uint32(info.repl_daddr)
tracker.Orig_src_port = uint16(info.orig_sport)
tracker.Repl_src_port = uint16(info.repl_sport)
tracker.Orig_dst_port = uint16(info.orig_dport)
tracker.Repl_dst_port = uint16(info.repl_dport)
tracker.Orig_protocol = uint8(info.orig_proto)
tracker.Repl_protocol = uint8(info.repl_proto)
// ********** Call all plugin conntrack handler functions here
go example.Plugin_conntrack_handler(&tracker)
// ********** End of plugin netfilter callback functions
}
/*---------------------------------------------------------------------------*/
//export go_netlogger_callback
func go_netlogger_callback(info *C.struct_netlogger_info) {
var logger support.Logger
logger.Protocol = uint8(info.protocol)
logger.IcmpType = uint16(info.icmp_type)
logger.SrcIntf = uint8(info.src_intf)
logger.DstIntf = uint8(info.dst_intf)
logger.SrcAddr = uint32(info.src_addr)
logger.DstAddr = uint32(info.dst_addr)
logger.SrcPort = uint16(info.src_port)
logger.DstPort = uint16(info.dst_port)
logger.Mark = uint32(info.mark)
logger.Prefix = C.GoString(info.prefix)
// ********** Call all plugin netlogger handler functions here
go example.Plugin_netlogger_handler(&logger)
// ********** End of plugin netlogger callback functions
}
/*---------------------------------------------------------------------------*/
//export go_child_startup
func go_child_startup() {
childsync.Add(1)
}
/*---------------------------------------------------------------------------*/
//export go_child_goodbye
func go_child_goodbye() {
childsync.Done()
}
/*---------------------------------------------------------------------------*/