github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/utils/frontman/wrapper_windows.go (about) 1 // +build windows 2 3 package frontman 4 5 import ( 6 "fmt" 7 "strings" 8 "syscall" 9 "unsafe" 10 11 "go.uber.org/zap" 12 "golang.org/x/sys/windows" 13 ) 14 15 // WrapDriver represents convenience wrapper methods for calling our Windows Frontman DLL 16 type WrapDriver interface { 17 GetDestInfo(socket uintptr, destInfo *DestInfo) error 18 ApplyDestHandle(socket, destHandle uintptr) error 19 FreeDestHandle(destHandle uintptr) error 20 NewIpset(name, ipsetType string) (uintptr, error) 21 GetIpset(name string) (uintptr, error) 22 DestroyAllIpsets(prefix string) error 23 ListIpsets() ([]string, error) 24 ListIpsetsDetail(format int) (string, error) 25 IpsetAdd(ipsetHandle uintptr, entry string, timeout int) error 26 IpsetAddOption(ipsetHandle uintptr, entry, option string, timeout int) error 27 IpsetDelete(ipsetHandle uintptr, entry string) error 28 IpsetDestroy(ipsetHandle uintptr, name string) error 29 IpsetFlush(ipsetHandle uintptr) error 30 IpsetTest(ipsetHandle uintptr, entry string) (bool, error) 31 PacketFilterStart(firewallName string, receiveCallback, loggingCallback func(uintptr, uintptr) uintptr) error 32 PacketFilterClose() error 33 PacketFilterForward(info *PacketInfo, packetBytes []byte) error 34 AppendFilter(outbound bool, filterName string, isGotoFilter bool) error 35 InsertFilter(outbound bool, priority int, filterName string, isGotoFilter bool) error 36 DestroyFilter(filterName string) error 37 EmptyFilter(filterName string) error 38 GetFilterList(outbound bool) ([]string, error) 39 AppendFilterCriteria(filterName, criteriaName string, ruleSpec *RuleSpec, ipsetRuleSpecs []IpsetRuleSpec) error 40 DeleteFilterCriteria(filterName, criteriaName string) error 41 GetCriteriaList(format int) (string, error) 42 } 43 44 type wrapper struct { 45 driverHandle uintptr 46 ruleCleaner ruleCleanup 47 } 48 49 // Wrapper is the driver/dll wrapper implementation 50 var Wrapper = WrapDriver(&wrapper{ 51 driverHandle: uintptr(syscall.InvalidHandle), 52 ruleCleaner: newRuleCleanup(), 53 }) 54 55 func (w *wrapper) initDriverHandle() { 56 if w.driverHandle == 0 || syscall.Handle(w.driverHandle) == syscall.InvalidHandle { 57 ret, err := Driver.FrontmanOpenShared() 58 if err != nil { 59 zap.L().Fatal("Unable to initialize Frontman driver. Check Windows Event Viewer System logs for errors, and ensure that no other instances are currently running.", zap.Error(err)) 60 } 61 w.driverHandle = ret 62 } 63 } 64 65 func (w *wrapper) GetDestInfo(socket uintptr, destInfo *DestInfo) error { 66 w.initDriverHandle() 67 if ret, err := Driver.GetDestInfo(w.driverHandle, socket, uintptr(unsafe.Pointer(destInfo))); ret == 0 { 68 return fmt.Errorf("GetDestInfo failed: %v", err) 69 } 70 return nil 71 } 72 73 func (w *wrapper) ApplyDestHandle(socket, destHandle uintptr) error { 74 w.initDriverHandle() 75 if ret, err := Driver.ApplyDestHandle(socket, destHandle); ret == 0 { 76 return fmt.Errorf("ApplyDestHandle failed: %v", err) 77 } 78 return nil 79 } 80 81 func (w *wrapper) FreeDestHandle(destHandle uintptr) error { 82 w.initDriverHandle() 83 if ret, err := Driver.FreeDestHandle(destHandle); ret == 0 { 84 return fmt.Errorf("FreeDestHandle failed: %v", err) 85 } 86 return nil 87 } 88 89 func (w *wrapper) NewIpset(name, ipsetType string) (uintptr, error) { 90 w.initDriverHandle() 91 var ipsetHandle uintptr 92 if ret, err := Driver.NewIpset(w.driverHandle, marshalString(name), marshalString(ipsetType), uintptr(unsafe.Pointer(&ipsetHandle))); ret == 0 { 93 return 0, fmt.Errorf("NewIpset failed: %v", err) 94 } 95 return ipsetHandle, nil 96 } 97 98 func (w *wrapper) GetIpset(name string) (uintptr, error) { 99 w.initDriverHandle() 100 var ipsetHandle uintptr 101 if ret, err := Driver.GetIpset(w.driverHandle, marshalString(name), uintptr(unsafe.Pointer(&ipsetHandle))); ret == 0 { 102 return 0, fmt.Errorf("GetIpset failed: %v", err) 103 } 104 return ipsetHandle, nil 105 } 106 107 func (w *wrapper) DestroyAllIpsets(prefix string) error { 108 w.initDriverHandle() 109 // order important: we must call cleaner routine before telling driver to delete the ipsets 110 errCleaner := w.ruleCleaner.deleteRuleForIpsetByPrefix(w, prefix) 111 if ret, err := Driver.DestroyAllIpsets(w.driverHandle, marshalString(prefix)); ret == 0 { 112 return fmt.Errorf("DestroyAllIpsets failed: %v", err) 113 } 114 return errCleaner 115 } 116 117 func (w *wrapper) ListIpsets() ([]string, error) { 118 w.initDriverHandle() 119 // first query for needed buffer size 120 var bytesNeeded, ignore uint32 121 ret, err := Driver.ListIpsets(w.driverHandle, 0, 0, uintptr(unsafe.Pointer(&bytesNeeded))) 122 if ret != 0 && bytesNeeded == 0 { 123 return []string{}, nil 124 } 125 if err != windows.ERROR_INSUFFICIENT_BUFFER { 126 return nil, fmt.Errorf("ListIpsets failed: %v", err) 127 } 128 if bytesNeeded%2 != 0 { 129 return nil, fmt.Errorf("ListIpsets failed: odd result (%d)", bytesNeeded) 130 } 131 // then allocate buffer for wide string and call again 132 buf := make([]uint16, bytesNeeded/2) 133 ret, err = Driver.ListIpsets(w.driverHandle, uintptr(unsafe.Pointer(&buf[0])), uintptr(bytesNeeded), uintptr(unsafe.Pointer(&ignore))) 134 if ret == 0 { 135 return nil, fmt.Errorf("ListIpsets failed: %v", err) 136 } 137 str := syscall.UTF16ToString(buf) 138 return strings.Split(str, ","), nil 139 } 140 141 func (w *wrapper) ListIpsetsDetail(format int) (string, error) { 142 w.initDriverHandle() 143 // first query for needed buffer size 144 var bytesNeeded, ignore uint32 145 emptyStr := "" 146 ret, err := Driver.ListIpsetsDetail(w.driverHandle, uintptr(format), 0, 0, uintptr(unsafe.Pointer(&bytesNeeded))) 147 if ret != 0 && bytesNeeded == 0 { 148 return emptyStr, nil 149 } 150 if err != windows.ERROR_INSUFFICIENT_BUFFER { 151 return emptyStr, fmt.Errorf("ListIpsetsDetail failed: %v", err) 152 } 153 if bytesNeeded%2 != 0 { 154 return emptyStr, fmt.Errorf("ListIpsetsDetail failed: odd result (%d)", bytesNeeded) 155 } 156 // then allocate buffer for wide string and call again 157 buf := make([]uint16, bytesNeeded/2) 158 ret, err = Driver.ListIpsetsDetail(w.driverHandle, uintptr(format), uintptr(unsafe.Pointer(&buf[0])), uintptr(bytesNeeded), uintptr(unsafe.Pointer(&ignore))) 159 if ret == 0 { 160 return emptyStr, fmt.Errorf("ListIpsetsDetail failed: %v", err) 161 } 162 str := syscall.UTF16ToString(buf) 163 return str, nil 164 } 165 166 func (w *wrapper) IpsetAdd(ipsetHandle uintptr, entry string, timeout int) error { 167 w.initDriverHandle() 168 if ret, err := Driver.IpsetAdd(w.driverHandle, ipsetHandle, marshalString(entry), uintptr(timeout)); ret == 0 { 169 // no error if already exists 170 if err == windows.ERROR_ALREADY_EXISTS { 171 return nil 172 } 173 return fmt.Errorf("IpsetAdd failed: %v", err) 174 } 175 return nil 176 } 177 178 func (w *wrapper) IpsetAddOption(ipsetHandle uintptr, entry, option string, timeout int) error { 179 w.initDriverHandle() 180 if ret, err := Driver.IpsetAddOption(w.driverHandle, ipsetHandle, marshalString(entry), marshalString(option), uintptr(timeout)); ret == 0 { 181 // no error if already exists 182 if err == windows.ERROR_ALREADY_EXISTS { 183 return nil 184 } 185 return fmt.Errorf("IpsetAddOption failed: %v", err) 186 } 187 return nil 188 } 189 190 func (w *wrapper) IpsetDelete(ipsetHandle uintptr, entry string) error { 191 w.initDriverHandle() 192 if ret, err := Driver.IpsetDelete(w.driverHandle, ipsetHandle, marshalString(entry)); ret == 0 { 193 return fmt.Errorf("IpsetDelete failed: %v", err) 194 } 195 return nil 196 } 197 198 func (w *wrapper) IpsetDestroy(ipsetHandle uintptr, name string) error { 199 w.initDriverHandle() 200 errCleaner := w.ruleCleaner.deleteRulesForIpset(w, name) 201 if ret, err := Driver.IpsetDestroy(w.driverHandle, ipsetHandle); ret == 0 { 202 return fmt.Errorf("IpsetDestroy failed: %v", err) 203 } 204 return errCleaner 205 } 206 207 func (w *wrapper) IpsetFlush(ipsetHandle uintptr) error { 208 w.initDriverHandle() 209 if ret, err := Driver.IpsetFlush(w.driverHandle, ipsetHandle); ret == 0 { 210 return fmt.Errorf("IpsetFlush failed: %v", err) 211 } 212 return nil 213 } 214 215 func (w *wrapper) IpsetTest(ipsetHandle uintptr, entry string) (bool, error) { 216 w.initDriverHandle() 217 if ret, err := Driver.IpsetTest(w.driverHandle, ipsetHandle, marshalString(entry)); ret == 0 { 218 if err == nil { 219 return false, nil 220 } 221 return false, fmt.Errorf("IpsetTest failed: %v", err) 222 } 223 return true, nil 224 } 225 226 func (w *wrapper) PacketFilterStart(firewallName string, receiveCallback, loggingCallback func(uintptr, uintptr) uintptr) error { 227 w.initDriverHandle() 228 if ret, err := Driver.PacketFilterStart(w.driverHandle, marshalString(firewallName), syscall.NewCallbackCDecl(receiveCallback), syscall.NewCallbackCDecl(loggingCallback)); ret == 0 { 229 return fmt.Errorf("PacketFilterStart failed: %v", err) 230 } 231 return nil 232 } 233 234 func (w *wrapper) PacketFilterClose() error { 235 w.initDriverHandle() 236 if ret, err := Driver.PacketFilterClose(); ret == 0 { 237 return fmt.Errorf("PacketFilterClose failed: %v", err) 238 } 239 return nil 240 } 241 242 func (w *wrapper) PacketFilterForward(info *PacketInfo, packetBytes []byte) error { 243 w.initDriverHandle() 244 if ret, err := Driver.PacketFilterForward(uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(&packetBytes[0]))); ret == 0 { 245 return fmt.Errorf("PacketFilterForward failed: %v", err) 246 } 247 return nil 248 } 249 250 func (w *wrapper) AppendFilter(outbound bool, filterName string, isGotoFilter bool) error { 251 w.initDriverHandle() 252 if ret, err := Driver.AppendFilter(w.driverHandle, marshalBool(outbound), marshalString(filterName), marshalBool(isGotoFilter)); ret == 0 { 253 // no error if already exists 254 if err == windows.ERROR_ALREADY_EXISTS { 255 return nil 256 } 257 return fmt.Errorf("AppendFilter failed: %v", err) 258 } 259 return nil 260 } 261 262 func (w *wrapper) InsertFilter(outbound bool, priority int, filterName string, isGotoFilter bool) error { 263 w.initDriverHandle() 264 if ret, err := Driver.InsertFilter(w.driverHandle, marshalBool(outbound), uintptr(priority), marshalString(filterName), marshalBool(isGotoFilter)); ret == 0 { 265 return fmt.Errorf("InsertFilter failed: %v", err) 266 } 267 return nil 268 } 269 270 func (w *wrapper) DestroyFilter(filterName string) error { 271 w.initDriverHandle() 272 if ret, err := Driver.DestroyFilter(w.driverHandle, marshalString(filterName)); ret == 0 { 273 return fmt.Errorf("DestroyFilter failed: %v", err) 274 } 275 return nil 276 } 277 278 func (w *wrapper) EmptyFilter(filterName string) error { 279 w.initDriverHandle() 280 if ret, err := Driver.EmptyFilter(w.driverHandle, marshalString(filterName)); ret == 0 { 281 return fmt.Errorf("EmptyFilter failed: %v", err) 282 } 283 return nil 284 } 285 286 func (w *wrapper) GetFilterList(outbound bool) ([]string, error) { 287 w.initDriverHandle() 288 // first query for needed buffer size 289 var bytesNeeded, ignore uint32 290 ret, err := Driver.GetFilterList(w.driverHandle, marshalBool(outbound), 0, 0, uintptr(unsafe.Pointer(&bytesNeeded))) 291 if ret != 0 && bytesNeeded == 0 { 292 return []string{}, nil 293 } 294 if err != windows.ERROR_INSUFFICIENT_BUFFER { 295 return nil, fmt.Errorf("GetFilterList failed: %v", err) 296 } 297 if bytesNeeded%2 != 0 { 298 return nil, fmt.Errorf("GetFilterList failed: odd result (%d)", bytesNeeded) 299 } 300 // then allocate buffer for wide string and call again 301 buf := make([]uint16, bytesNeeded/2) 302 303 // Not sure how this happens, but sometimes on shutdown we get a panic because the len(buf) is zero 304 if len(buf) <= 0 { 305 return nil, fmt.Errorf("GetFilterList returned unexpected bytes needed value: %d", bytesNeeded) 306 } 307 308 ret, err = Driver.GetFilterList(w.driverHandle, marshalBool(outbound), uintptr(unsafe.Pointer(&buf[0])), uintptr(bytesNeeded), uintptr(unsafe.Pointer(&ignore))) 309 if ret == 0 { 310 return nil, fmt.Errorf("GetFilterList failed: %v", err) 311 } 312 str := syscall.UTF16ToString(buf) 313 return strings.Split(str, ","), nil 314 } 315 316 func (w *wrapper) AppendFilterCriteria(filterName, criteriaName string, ruleSpec *RuleSpec, ipsetRuleSpecs []IpsetRuleSpec) error { 317 w.initDriverHandle() 318 if len(ipsetRuleSpecs) > 0 { 319 if ret, err := Driver.AppendFilterCriteria(w.driverHandle, 320 marshalString(filterName), 321 marshalString(criteriaName), 322 uintptr(unsafe.Pointer(ruleSpec)), 323 uintptr(unsafe.Pointer(&ipsetRuleSpecs[0])), 324 uintptr(len(ipsetRuleSpecs))); ret == 0 { 325 return fmt.Errorf("AppendFilterCriteria failed: %v", err) 326 } 327 for _, ipsrs := range ipsetRuleSpecs { 328 if ipsrs.IpsetName != 0 { 329 ipsetName := WideCharPointerToString((*uint16)(unsafe.Pointer(ipsrs.IpsetName))) // nolint:govet 330 w.ruleCleaner.mapIpsetToRule(ipsetName, filterName, criteriaName) 331 } 332 } 333 } else { 334 if ret, err := Driver.AppendFilterCriteria(w.driverHandle, 335 marshalString(filterName), 336 marshalString(criteriaName), 337 uintptr(unsafe.Pointer(ruleSpec)), 0, 0); ret == 0 { 338 return fmt.Errorf("AppendFilterCriteria failed: %v", err) 339 } 340 } 341 return nil 342 } 343 344 func (w *wrapper) DeleteFilterCriteria(filterName, criteriaName string) error { 345 w.initDriverHandle() 346 w.ruleCleaner.deleteRuleFromIpsetMap(filterName, criteriaName) 347 if ret, err := Driver.DeleteFilterCriteria(w.driverHandle, marshalString(filterName), marshalString(criteriaName)); ret == 0 { 348 return fmt.Errorf("DeleteFilterCriteria failed - could not delete %s: %v", criteriaName, err) 349 } 350 return nil 351 } 352 353 func (w *wrapper) GetCriteriaList(format int) (string, error) { 354 w.initDriverHandle() 355 // first query for needed buffer size 356 var bytesNeeded, ignore uint32 357 emptyStr := "" 358 ret, err := Driver.GetCriteriaList(w.driverHandle, uintptr(format), 0, 0, uintptr(unsafe.Pointer(&bytesNeeded))) 359 if ret != 0 && bytesNeeded == 0 { 360 return emptyStr, nil 361 } 362 if err != windows.ERROR_INSUFFICIENT_BUFFER { 363 return emptyStr, fmt.Errorf("GetCriteriaList failed: %v", err) 364 } 365 if bytesNeeded%2 != 0 { 366 return emptyStr, fmt.Errorf("GetCriteriaList failed: odd result (%d)", bytesNeeded) 367 } 368 // then allocate buffer for wide string and call again 369 buf := make([]uint16, bytesNeeded/2) 370 ret, err = Driver.GetCriteriaList(w.driverHandle, uintptr(format), uintptr(unsafe.Pointer(&buf[0])), uintptr(bytesNeeded), uintptr(unsafe.Pointer(&ignore))) 371 if ret == 0 { 372 return emptyStr, fmt.Errorf("GetCriteriaList failed: %v", err) 373 } 374 str := syscall.UTF16ToString(buf) 375 return str, nil 376 } 377 378 func marshalString(str string) uintptr { 379 return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) // nolint 380 } 381 382 func marshalBool(b bool) uintptr { 383 if b { 384 return 1 385 } 386 return 0 387 }