├── .github └── workflows │ ├── staticcheck.yml │ └── windows.yml ├── .gitignore ├── AUTHORS ├── LICENSE ├── README.md ├── check_license_headers.sh ├── cmd └── wfpcli │ └── main.go ├── compose.go ├── firewall.go ├── firewall_test.go ├── generate.go ├── generators └── gen_guids.go ├── go.mod ├── go.sum ├── malloc.go ├── parse.go ├── syscall.go ├── tooldeps.go ├── types.go ├── zaction_strings.go ├── zconditionflag_strings.go ├── zdatatype_strings.go ├── zfieldtype_strings.go ├── zfilterenumflags_strings.go ├── zfilterenumtype_strings.go ├── zfilterflags_strings.go ├── zguids.go ├── zipproto_strings.go ├── zproviderflags_strings.go ├── zsublayerflags_strings.go └── zsyscall_windows.go /.github/workflows/staticcheck.yml: -------------------------------------------------------------------------------- 1 | name: staticcheck 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - "*" 10 | 11 | jobs: 12 | staticcheck: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Set up Go 17 | uses: actions/setup-go@v1 18 | with: 19 | go-version: 1.18 20 | 21 | - name: Check out code 22 | uses: actions/checkout@v2 23 | with: 24 | fetch-depth: 0 25 | 26 | - name: Check license 27 | run: ./check_license_headers.sh . 28 | 29 | - name: Run staticcheck 30 | run: | 31 | go install honnef.co/go/tools/cmd/staticcheck 32 | GOOS=windows $(go list -f {{.Target}} honnef.co/go/tools/cmd/staticcheck) -checks=inherit,-SA1019 33 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - "*" 10 | 11 | jobs: 12 | test: 13 | runs-on: windows-2019 14 | steps: 15 | - name: Install Go 16 | uses: actions/setup-go@v2 17 | with: 18 | go-version: 1.18 19 | 20 | - name: Checkout code 21 | uses: actions/checkout@v2 22 | with: 23 | fetch-depth: 0 24 | 25 | - name: Test 26 | run: go test ./... 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | includes/ 2 | *.exe 3 | *.txt 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Tailscale Inc. 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 The Inet.af AUTHORS. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Tailscale Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wf 2 | 3 | ## What 4 | 5 | This is a package for controlling the Windows Filtering Platform 6 | (WFP), also known as the Windows firewall. 7 | 8 | See its docs: https://pkg.go.dev/github.com/tailscale/wf 9 | 10 | ## Maturity 11 | 12 | This package is under active development. While [Tailscale][ts] uses 13 | it in production, API stability is not guaranteed, and some 14 | functionality is missing. 15 | 16 | [ts]: https://www.tailscale.com 17 | -------------------------------------------------------------------------------- /check_license_headers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # check_license_headers.sh checks that all Go files have a 3 | # correct-looking license header. 4 | 5 | check_file() { 6 | got=$1 7 | 8 | for year in `seq 2019 2025`; do 9 | want=$(cat <&2 24 | exit 1 25 | fi 26 | 27 | fail=0 28 | for file in $(find . -name '*.go' -not -path '*/.git/*'); do 29 | case $file in 30 | */z*.go) 31 | # No copyright header in autogenerated files. 32 | ;; 33 | *) 34 | header="$(head -3 $file)" 35 | if ! check_file "$header"; then 36 | fail=1 37 | echo "${file#*/} doesn't have the right copyright header:" 38 | echo "$header" | sed -e 's/^/ /g' 39 | fi 40 | ;; 41 | esac 42 | done 43 | 44 | if [ $fail -ne 0 ]; then 45 | exit 1 46 | fi 47 | -------------------------------------------------------------------------------- /cmd/wfpcli/main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // wfpcli is a CLI tool for interacting with the Windows Filtering 6 | // Platform (WFP), aka the Windows firewall. 7 | package main 8 | 9 | import ( 10 | "context" 11 | "flag" 12 | "fmt" 13 | "os" 14 | "sort" 15 | "strings" 16 | 17 | "github.com/peterbourgon/ff/v3/ffcli" 18 | "github.com/tailscale/wf" 19 | "golang.org/x/sys/windows" 20 | ) 21 | 22 | var ( 23 | listProvidersC = &ffcli.Command{ 24 | Name: "list-providers", 25 | ShortUsage: "wfpcli list-providers", 26 | ShortHelp: "List WFP providers.", 27 | Exec: listProviders, 28 | } 29 | 30 | addProviderFS = flag.NewFlagSet("wfpcli add-provider", flag.ExitOnError) 31 | providerName = addProviderFS.String("name", "", "Provider name") 32 | providerDescription = addProviderFS.String("description", "", "Provider description") 33 | providerPersistent = addProviderFS.Bool("persistent", false, "Whether the provider is persistent") 34 | providerServiceName = addProviderFS.String("service", "", "Service name") 35 | addProviderC = &ffcli.Command{ 36 | Name: "add-provider", 37 | ShortUsage: "wfpcli add-provider", 38 | ShortHelp: "Add WFP provider", 39 | FlagSet: addProviderFS, 40 | Exec: addProvider, 41 | } 42 | 43 | delProviderC = &ffcli.Command{ 44 | Name: "del-provider", 45 | ShortUsage: "wfpcli del-provider ", 46 | ShortHelp: "Delete WFP provider.", 47 | Exec: delProvider, 48 | } 49 | 50 | listLayersC = &ffcli.Command{ 51 | Name: "list-layers", 52 | ShortUsage: "wfpcli list-layers", 53 | ShortHelp: "List WFP layers.", 54 | Exec: listLayers, 55 | } 56 | 57 | listSublayerFS = flag.NewFlagSet("wfpcli list-sublayers", flag.ExitOnError) 58 | sublayerProviders = listSublayerFS.String("providers", "", "Limit to given provider GUIDs") 59 | listSublayersC = &ffcli.Command{ 60 | Name: "list-sublayers", 61 | ShortUsage: "wfpcli list-sublayers", 62 | ShortHelp: "List WFP sublayers.", 63 | FlagSet: listSublayerFS, 64 | Exec: listSublayers, 65 | } 66 | 67 | addSublayerFS = flag.NewFlagSet("wfpcli add-sublayer", flag.ExitOnError) 68 | sublayerName = addSublayerFS.String("name", "", "Sublayer name") 69 | sublayerDescription = addSublayerFS.String("description", "", "Sublayer description") 70 | sublayerPersistent = addSublayerFS.Bool("persistent", false, "Whether the sublayer is persistent") 71 | sublayerProvider = addSublayerFS.String("provider", "", "Owner of the sublayer") 72 | sublayerWeight = addSublayerFS.Int("weight", 1, "Sublayer weight") 73 | addSublayerC = &ffcli.Command{ 74 | Name: "add-sublayer", 75 | ShortUsage: "wfpcli add-sublayer", 76 | ShortHelp: "Add WFP sublayer.", 77 | FlagSet: addSublayerFS, 78 | Exec: addSublayer, 79 | } 80 | 81 | delSublayerC = &ffcli.Command{ 82 | Name: "del-sublayer", 83 | ShortUsage: "wfpcli del-sublayer ", 84 | ShortHelp: "Delete WFP sublayer.", 85 | Exec: delSublayer, 86 | } 87 | 88 | listRulesC = &ffcli.Command{ 89 | Name: "list-rules", 90 | ShortUsage: "wfpcli list-rules", 91 | ShortHelp: "List WFP rules.", 92 | Exec: listRules, 93 | } 94 | 95 | listEventsC = &ffcli.Command{ 96 | Name: "list-events", 97 | ShortUsage: "wfpcli list-events", 98 | ShortHelp: "List WFP drop events.", 99 | Exec: listEvents, 100 | } 101 | 102 | testC = &ffcli.Command{ 103 | Name: "test", 104 | ShortUsage: "wfpcli list-events", 105 | ShortHelp: "List WFP drop events.", 106 | Exec: test, 107 | } 108 | 109 | rootFS = flag.NewFlagSet("wfpcli", flag.ExitOnError) 110 | dynamic = rootFS.Bool("dynamic", false, "Use a dynamic WFP session") 111 | root = &ffcli.Command{ 112 | ShortUsage: "wfpcli ", 113 | FlagSet: rootFS, 114 | Subcommands: []*ffcli.Command{listProvidersC, addProviderC, delProviderC, listLayersC, listSublayersC, addSublayerC, delSublayerC, listRulesC, listEventsC, testC}, 115 | Exec: func(context.Context, []string) error { 116 | return flag.ErrHelp 117 | }, 118 | } 119 | ) 120 | 121 | func main() { 122 | if err := root.ParseAndRun(context.Background(), os.Args[1:]); err != nil { 123 | fmt.Fprintf(os.Stderr, "%s", err) 124 | os.Exit(1) 125 | } 126 | } 127 | 128 | func session() (*wf.Session, error) { 129 | return wf.New(&wf.Options{ 130 | Name: "wfpcli", 131 | Description: "WFP CLI", 132 | Dynamic: *dynamic, 133 | }) 134 | } 135 | 136 | func mustGUID() windows.GUID { 137 | ret, err := windows.GenerateGUID() 138 | if err != nil { 139 | panic(err) 140 | } 141 | return ret 142 | } 143 | 144 | func displayName(guid, name string) string { 145 | if name != "" { 146 | return name 147 | } 148 | return guid 149 | } 150 | 151 | func listProviders(_ context.Context, _ []string) error { 152 | sess, err := session() 153 | if err != nil { 154 | return fmt.Errorf("creating WFP session: %w", err) 155 | } 156 | defer sess.Close() 157 | 158 | providers, err := sess.Providers() 159 | if err != nil { 160 | return fmt.Errorf("listing providers: %w", err) 161 | } 162 | 163 | for _, provider := range providers { 164 | fmt.Printf("%s\n", displayName(provider.ID.String(), provider.Name)) 165 | fmt.Printf(" GUID: %s\n", provider.ID) 166 | fmt.Printf(" Name: %q\n", provider.Name) 167 | if provider.Description != "" { 168 | fmt.Printf(" Description: %q\n", provider.Description) 169 | } 170 | fmt.Printf(" Persistent: %v\n", provider.Persistent) 171 | if len(provider.Data) > 0 { 172 | fmt.Printf(" Data: %v\n", provider.Data) 173 | } 174 | if provider.ServiceName != "" { 175 | fmt.Printf(" Service name: %s\n", provider.ServiceName) 176 | } 177 | fmt.Printf(" Disabled: %v\n", provider.Disabled) 178 | fmt.Printf("\n") 179 | } 180 | 181 | return nil 182 | } 183 | 184 | func addProvider(context.Context, []string) error { 185 | sess, err := session() 186 | if err != nil { 187 | return fmt.Errorf("creating WFP session: %w", err) 188 | } 189 | defer sess.Close() 190 | 191 | p := &wf.Provider{ 192 | ID: wf.ProviderID(mustGUID()), 193 | Name: *providerName, 194 | Description: *providerDescription, 195 | Persistent: *providerPersistent, 196 | ServiceName: *providerServiceName, 197 | } 198 | 199 | if err := sess.AddProvider(p); err != nil { 200 | return fmt.Errorf("adding provider: %w", err) 201 | } 202 | 203 | fmt.Printf("Created provider %s\n", p.ID) 204 | 205 | return nil 206 | } 207 | 208 | func delProvider(_ context.Context, args []string) error { 209 | if len(args) != 1 { 210 | fmt.Fprintf(os.Stderr, "GUID is required\n") 211 | return flag.ErrHelp 212 | } 213 | 214 | guid, err := windows.GUIDFromString(args[0]) 215 | if err != nil { 216 | return fmt.Errorf("Parsing GUID: %w", err) 217 | } 218 | 219 | sess, err := session() 220 | if err != nil { 221 | return fmt.Errorf("creating WFP session: %w", err) 222 | } 223 | defer sess.Close() 224 | 225 | if err := sess.DeleteProvider(wf.ProviderID(guid)); err != nil { 226 | return fmt.Errorf("deleting provider: %w", err) 227 | } 228 | 229 | fmt.Printf("Deleted provider %s\n", guid) 230 | 231 | return nil 232 | } 233 | 234 | func listLayers(_ context.Context, _ []string) error { 235 | sess, err := session() 236 | if err != nil { 237 | return fmt.Errorf("creating WFP session: %w", err) 238 | } 239 | defer sess.Close() 240 | 241 | layers, err := sess.Layers() 242 | if err != nil { 243 | return fmt.Errorf("listing layers: %w", err) 244 | } 245 | 246 | for _, layer := range layers { 247 | fmt.Printf("%s\n", displayName(layer.ID.String(), layer.Name)) 248 | fmt.Printf(" GUID: %s\n", layer.ID) 249 | fmt.Printf(" LUID: %d\n", layer.KernelID) 250 | fmt.Printf(" Name: %q\n", layer.Name) 251 | if layer.Description != "" { 252 | fmt.Printf(" Description: %q\n", layer.Description) 253 | } 254 | for _, field := range layer.Fields { 255 | fmt.Printf(" Field: %s\n", field.ID) 256 | fmt.Printf(" GUID: %s\n", field.ID) 257 | fmt.Printf(" Type: %s\n", field.Type) 258 | } 259 | fmt.Printf("\n") 260 | } 261 | 262 | return nil 263 | } 264 | 265 | func listSublayers(_ context.Context, _ []string) error { 266 | sess, err := session() 267 | if err != nil { 268 | return fmt.Errorf("creating WFP session: %w", err) 269 | } 270 | defer sess.Close() 271 | 272 | var providers []wf.ProviderID 273 | for _, f := range strings.Split(*sublayerProviders, ",") { 274 | guid, err := windows.GUIDFromString(f) 275 | if err != nil { 276 | return fmt.Errorf("parsing GUID %q: %v", f, err) 277 | } 278 | providers = append(providers, wf.ProviderID(guid)) 279 | } 280 | 281 | sublayers, err := sess.Sublayers(providers...) 282 | if err != nil { 283 | return fmt.Errorf("listing WFP sublayers: %w", err) 284 | } 285 | 286 | for _, sublayer := range sublayers { 287 | fmt.Printf("%s\n", displayName(sublayer.ID.String(), sublayer.Name)) 288 | fmt.Printf(" GUID: %s\n", sublayer.ID) 289 | fmt.Printf(" Name: %q\n", sublayer.Name) 290 | if sublayer.Description != "" { 291 | fmt.Printf(" Description: %q\n", sublayer.Description) 292 | } 293 | fmt.Printf(" Persistent: %v\n", sublayer.Persistent) 294 | if !sublayer.Provider.IsZero() { 295 | fmt.Printf(" Provider: %s\n", sublayer.Provider) 296 | } 297 | if len(sublayer.ProviderData) > 0 { 298 | fmt.Printf(" Provider data: %v\n", sublayer.ProviderData) 299 | } 300 | fmt.Printf(" Weight: %d\n", sublayer.Weight) 301 | fmt.Printf("\n") 302 | } 303 | 304 | return nil 305 | } 306 | 307 | func addSublayer(_ context.Context, _ []string) error { 308 | sess, err := session() 309 | if err != nil { 310 | return fmt.Errorf("creating WFP session: %w", err) 311 | } 312 | defer sess.Close() 313 | 314 | sl := &wf.Sublayer{ 315 | ID: wf.SublayerID(mustGUID()), 316 | Name: *sublayerName, 317 | Description: *sublayerDescription, 318 | Persistent: *sublayerPersistent, 319 | Weight: uint16(*sublayerWeight), 320 | } 321 | if *sublayerProvider != "" { 322 | guid, err := windows.GUIDFromString(*sublayerProvider) 323 | if err != nil { 324 | return fmt.Errorf("Parsing provider GUID: %w", err) 325 | } 326 | sl.Provider = wf.ProviderID(guid) 327 | } 328 | 329 | if err := sess.AddSublayer(sl); err != nil { 330 | return fmt.Errorf("creating sublayer: %w", err) 331 | } 332 | 333 | fmt.Printf("Created sublayer %s\n", sl.ID) 334 | return nil 335 | } 336 | 337 | func delSublayer(_ context.Context, args []string) error { 338 | if len(args) != 1 { 339 | fmt.Fprintf(os.Stderr, "GUID is required\n") 340 | return flag.ErrHelp 341 | } 342 | 343 | guid, err := windows.GUIDFromString(args[0]) 344 | if err != nil { 345 | return fmt.Errorf("Parsing GUID: %w", err) 346 | } 347 | 348 | sess, err := session() 349 | if err != nil { 350 | return fmt.Errorf("creating WFP session: %w", err) 351 | } 352 | defer sess.Close() 353 | 354 | if err := sess.DeleteSublayer(wf.SublayerID(guid)); err != nil { 355 | return fmt.Errorf("deleting sublayer: %w", err) 356 | } 357 | 358 | fmt.Printf("Deleted sublayer %s\n", guid) 359 | 360 | return nil 361 | } 362 | 363 | func listRules(context.Context, []string) error { 364 | sess, err := session() 365 | if err != nil { 366 | return fmt.Errorf("creating WFP session: %w", err) 367 | } 368 | defer sess.Close() 369 | 370 | rules, err := sess.Rules() 371 | if err != nil { 372 | return fmt.Errorf("getting rules: %w", err) 373 | } 374 | 375 | sort.Slice(rules, func(i, j int) bool { 376 | return rules[i].ID.String() < rules[j].ID.String() 377 | }) 378 | 379 | for _, rule := range rules { 380 | fmt.Printf("%s\n", displayName(rule.ID.String(), rule.Name)) 381 | fmt.Printf(" GUID: %s\n", rule.ID) 382 | fmt.Printf(" Name: %q\n", rule.Name) 383 | if rule.Description != "" { 384 | fmt.Printf(" Description: %q\n", rule.Description) 385 | } 386 | fmt.Printf(" Layer: %s\n", rule.Layer.String()) 387 | fmt.Printf(" Sublayer: %s\n", rule.Sublayer.String()) 388 | fmt.Printf(" Weight: 0x%02x\n", rule.Weight) 389 | fmt.Printf(" Action: %s\n", rule.Action) 390 | if rule.Callout != (wf.CalloutID{}) { 391 | fmt.Printf(" Callout: %s\n", rule.Callout) 392 | } 393 | if rule.Action == wf.ActionCalloutTerminating || rule.Action == wf.ActionCalloutUnknown { 394 | fmt.Printf(" Permit if missing: %v\n", rule.PermitIfMissing) 395 | } 396 | fmt.Printf(" Persistent: %v\n", rule.Persistent) 397 | fmt.Printf(" Boot-time: %v\n", rule.BootTime) 398 | if !rule.Provider.IsZero() { 399 | fmt.Printf(" Provider: %s\n", rule.Provider) 400 | } 401 | if rule.Disabled { 402 | fmt.Printf(" Disabled: %v\n", rule.Disabled) 403 | } 404 | for _, cond := range rule.Conditions { 405 | fmt.Printf(" Condition: %s\n", cond) 406 | } 407 | fmt.Printf("\n") 408 | } 409 | fmt.Printf("Dumped %d rules\n", len(rules)) 410 | return nil 411 | } 412 | 413 | func listEvents(context.Context, []string) error { 414 | sess, err := session() 415 | if err != nil { 416 | return fmt.Errorf("creating WFP session: %w", err) 417 | } 418 | defer sess.Close() 419 | 420 | events, err := sess.DropEvents() 421 | if err != nil { 422 | return fmt.Errorf("getting events: %w", err) 423 | } 424 | 425 | for _, event := range events { 426 | fmt.Printf("%s\n", event.Timestamp) 427 | fmt.Printf(" Protocol: %d\n", event.IPProtocol) 428 | fmt.Printf(" Local addr: %s\n", event.LocalAddr) 429 | fmt.Printf(" Remote addr: %s\n", event.RemoteAddr) 430 | if event.AppID != "" { 431 | fmt.Printf(" App ID: %s\n", event.AppID) 432 | } 433 | fmt.Printf(" Layer ID: %d\n", event.LayerID) 434 | fmt.Printf(" Filter ID: %d\n", event.FilterID) 435 | fmt.Printf("\n") 436 | } 437 | fmt.Printf("Dumped %d events\n", len(events)) 438 | return nil 439 | } 440 | 441 | var guidSublayerUniversal = wf.SublayerID{ 442 | Data1: 0xeebecc03, 443 | Data2: 0xced4, 444 | Data3: 0x4380, 445 | Data4: [8]byte{0x81, 0x9a, 0x27, 0x34, 0x39, 0x7b, 0x2b, 0x74}, 446 | } 447 | 448 | func test(context.Context, []string) error { 449 | sess, err := session() 450 | if err != nil { 451 | return fmt.Errorf("creating WFP session: %w", err) 452 | } 453 | defer sess.Close() 454 | 455 | r := &wf.Rule{ 456 | ID: wf.RuleID(mustGUID()), 457 | Layer: wf.LayerALEAuthRecvAcceptV4, 458 | Sublayer: guidSublayerUniversal, 459 | Weight: 1, 460 | Action: wf.ActionBlock, 461 | Conditions: []*wf.Match{ 462 | &wf.Match{ 463 | Field: wf.FieldIPLocalAddress, 464 | Op: wf.MatchTypeEqual, 465 | Value: uint8(42), 466 | }, 467 | }, 468 | } 469 | return sess.AddRule(r) 470 | } 471 | -------------------------------------------------------------------------------- /compose.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package wf 6 | 7 | import ( 8 | "encoding/binary" 9 | "errors" 10 | "fmt" 11 | "net" 12 | "net/netip" 13 | "reflect" 14 | "unsafe" 15 | 16 | "go4.org/netipx" 17 | "golang.org/x/sys/windows" 18 | ) 19 | 20 | // toSession0 converts opts into an arena-allocated fwpmSession0. 21 | func toSession0(a *arena, opts *Options) *fwpmSession0 { 22 | ret := (*fwpmSession0)(a.Alloc(unsafe.Sizeof(fwpmSession0{}))) 23 | *ret = fwpmSession0{ 24 | DisplayData: fwpmDisplayData0{ 25 | Name: toUint16(a, opts.Name), 26 | Description: toUint16(a, opts.Description), 27 | }, 28 | TxnWaitTimeoutMillis: uint32(opts.TransactionStartTimeout.Milliseconds()), 29 | } 30 | if opts.Dynamic { 31 | ret.Flags = fwpmSession0FlagDynamic 32 | } 33 | return ret 34 | } 35 | 36 | // toSublayerEnumTemplate0 returns an arena-allocated 37 | // fwpmSublayerEnumTemplate0 that filters on the given provider, or 38 | // all if provider is nil. 39 | func toSublayerEnumTemplate0(a *arena, provider ProviderID) *fwpmSublayerEnumTemplate0 { 40 | ret := (*fwpmSublayerEnumTemplate0)(a.Alloc(unsafe.Sizeof(fwpmSublayerEnumTemplate0{}))) 41 | ret.ProviderKey = toGUID(a, windows.GUID(provider)) 42 | return ret 43 | } 44 | 45 | // toSublayer0 converts sl into an arena-allocated fwpmSublayer0. 46 | func toSublayer0(a *arena, sl *Sublayer) *fwpmSublayer0 { 47 | ret := (*fwpmSublayer0)(a.Alloc(unsafe.Sizeof(fwpmSublayer0{}))) 48 | *ret = fwpmSublayer0{ 49 | SublayerKey: sl.ID, 50 | DisplayData: fwpmDisplayData0{ 51 | Name: toUint16(a, sl.Name), 52 | Description: toUint16(a, sl.Description), 53 | }, 54 | ProviderKey: toGUID(a, windows.GUID(sl.Provider)), 55 | ProviderData: fwpByteBlob{ 56 | Size: uint32(len(sl.ProviderData)), 57 | Data: toBytes(a, sl.ProviderData), 58 | }, 59 | Weight: sl.Weight, 60 | } 61 | if sl.Persistent { 62 | ret.Flags = fwpmSublayerFlagsPersistent 63 | } 64 | 65 | return ret 66 | } 67 | 68 | // toProvider0 converts p into an arena-allocated fwpmProvider0. 69 | func toProvider0(a *arena, p *Provider) *fwpmProvider0 { 70 | ret := (*fwpmProvider0)(a.Alloc(unsafe.Sizeof(fwpmProvider0{}))) 71 | *ret = fwpmProvider0{ 72 | ProviderKey: p.ID, 73 | DisplayData: fwpmDisplayData0{ 74 | Name: toUint16(a, p.Name), 75 | Description: toUint16(a, p.Description), 76 | }, 77 | ProviderData: fwpByteBlob{ 78 | Size: uint32(len(p.Data)), 79 | Data: toBytes(a, p.Data), 80 | }, 81 | ServiceName: toUint16(a, p.ServiceName), 82 | } 83 | if p.Persistent { 84 | ret.Flags = fwpmProviderFlagsPersistent 85 | } 86 | 87 | return ret 88 | } 89 | 90 | // toFilter0 converts r into an arena-allocated fwpmFilter0, using lt 91 | // as necessary to correctly cast values. 92 | func toFilter0(a *arena, r *Rule, lt layerTypes) (*fwpmFilter0, error) { 93 | conds, err := toCondition0(a, r.Conditions, lt[r.Layer]) 94 | if err != nil { 95 | return nil, err 96 | } 97 | 98 | typ, val, err := toValue0(a, r.Weight, typeUint64) 99 | if err != nil { 100 | return nil, err 101 | } 102 | 103 | ret := (*fwpmFilter0)(a.Alloc(unsafe.Sizeof(fwpmFilter0{}))) 104 | *ret = fwpmFilter0{ 105 | FilterKey: r.ID, 106 | DisplayData: fwpmDisplayData0{ 107 | Name: toUint16(a, r.Name), 108 | Description: toUint16(a, r.Description), 109 | }, 110 | ProviderKey: toGUID(a, windows.GUID(r.Provider)), 111 | ProviderData: fwpByteBlob{ 112 | Size: uint32(len(r.ProviderData)), // todo: overflow? 113 | Data: toBytes(a, r.ProviderData), 114 | }, 115 | LayerKey: r.Layer, 116 | SublayerKey: r.Sublayer, 117 | Weight: fwpValue0{ 118 | Type: typ, 119 | Value: val, 120 | }, 121 | NumFilterConditions: uint32(len(r.Conditions)), // TODO: overflow? 122 | FilterConditions: conds, 123 | Action: fwpmAction0{ 124 | Type: r.Action, 125 | GUID: r.Callout, 126 | }, 127 | } 128 | 129 | if r.HardAction { 130 | ret.Flags |= fwpmFilterFlagsClearActionRight 131 | } 132 | if r.PermitIfMissing { 133 | ret.Flags |= fwpmFilterFlagsPermitIfCalloutUnregistered 134 | } 135 | if r.Persistent { 136 | ret.Flags |= fwpmFilterFlagsPersistent 137 | } 138 | if r.BootTime { 139 | ret.Flags |= fwpmFilterFlagsBootTime 140 | } 141 | 142 | return ret, nil 143 | } 144 | 145 | // toCondition0 converts ms into an arena-allocated 146 | // fwpmFilterCondition0 array, using lt as necessary to correctly cast 147 | // values. 148 | func toCondition0(a *arena, ms []*Match, ft fieldTypes) (array *fwpmFilterCondition0, err error) { 149 | if len(ms) == 0 { 150 | return nil, nil 151 | } 152 | array = (*fwpmFilterCondition0)(a.Alloc(uintptr(len(ms)) * unsafe.Sizeof(fwpmFilterCondition0{}))) 153 | 154 | var conds []fwpmFilterCondition0 155 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&conds)) 156 | sh.Cap = len(ms) 157 | sh.Len = len(ms) 158 | sh.Data = uintptr(unsafe.Pointer(array)) 159 | 160 | for i, m := range ms { 161 | c := &conds[i] 162 | 163 | typ, val, err := toValue0(a, m.Value, ft[m.Field]) 164 | if err != nil { 165 | return nil, fmt.Errorf("invalid match %v: %w", m, err) 166 | } 167 | 168 | *c = fwpmFilterCondition0{ 169 | FieldKey: m.Field, 170 | MatchType: m.Op, 171 | Value: fwpConditionValue0{ 172 | Type: typ, 173 | Value: val, 174 | }, 175 | } 176 | } 177 | 178 | return array, nil 179 | } 180 | 181 | // toValue0 converts v into the component parts of an fwpValue0 or 182 | // fwpConditionValue0. 183 | func toValue0(a *arena, v interface{}, ftype reflect.Type) (typ dataType, val uintptr, err error) { 184 | mapErr := func() (dataType, uintptr, error) { 185 | return 0, 0, fmt.Errorf("cannot map Go type %T to field type %s", v, ftype) 186 | } 187 | 188 | switch ftype { 189 | case typeUint8: 190 | switch u := v.(type) { 191 | case uint8: 192 | typ = dataTypeUint8 193 | *(*uint8)(unsafe.Pointer(&val)) = u 194 | case IPProto: 195 | typ = dataTypeUint8 196 | *(*uint8)(unsafe.Pointer(&val)) = uint8(u) 197 | case Range: 198 | r0, err := toRange0(a, u, ftype) 199 | if err != nil { 200 | return 0, 0, err 201 | } 202 | typ = dataTypeRange 203 | val = uintptr(unsafe.Pointer(r0)) 204 | default: 205 | return mapErr() 206 | } 207 | case typeUint16: 208 | switch u := v.(type) { 209 | case uint16: 210 | typ = dataTypeUint16 211 | *(*uint16)(unsafe.Pointer(&val)) = u 212 | case Range: 213 | r0, err := toRange0(a, u, ftype) 214 | if err != nil { 215 | return 0, 0, err 216 | } 217 | typ = dataTypeRange 218 | val = uintptr(unsafe.Pointer(r0)) 219 | default: 220 | return mapErr() 221 | } 222 | case typeUint32: 223 | switch u := v.(type) { 224 | case uint32: 225 | typ = dataTypeUint32 226 | *(*uint32)(unsafe.Pointer(&val)) = u 227 | case ConditionFlag: 228 | typ = dataTypeUint32 229 | *(*uint32)(unsafe.Pointer(&val)) = uint32(u) 230 | case Range: 231 | r0, err := toRange0(a, u, ftype) 232 | if err != nil { 233 | return 0, 0, err 234 | } 235 | typ = dataTypeRange 236 | val = uintptr(unsafe.Pointer(r0)) 237 | default: 238 | return mapErr() 239 | } 240 | case typeUint64: 241 | switch u := v.(type) { 242 | case uint64: 243 | typ = dataTypeUint64 244 | p := a.Alloc(unsafe.Sizeof(u)) 245 | *(*uint64)(p) = u 246 | val = uintptr(p) 247 | case Range: 248 | r0, err := toRange0(a, u, ftype) 249 | if err != nil { 250 | return 0, 0, err 251 | } 252 | typ = dataTypeRange 253 | val = uintptr(unsafe.Pointer(r0)) 254 | default: 255 | return mapErr() 256 | } 257 | case typeBytes: 258 | switch bb := v.(type) { 259 | case []byte: 260 | typ = dataTypeByteBlob 261 | p := a.Alloc(unsafe.Sizeof(fwpByteBlob{})) 262 | *(*fwpByteBlob)(p) = fwpByteBlob{ 263 | Size: uint32(len(bb)), 264 | Data: toBytes(a, bb), 265 | } 266 | val = uintptr(p) 267 | case Range: 268 | r0, err := toRange0(a, bb, ftype) 269 | if err != nil { 270 | return 0, 0, err 271 | } 272 | typ = dataTypeRange 273 | val = uintptr(unsafe.Pointer(r0)) 274 | default: 275 | return mapErr() 276 | } 277 | case typeString: 278 | switch s := v.(type) { 279 | case string: 280 | bb, l := toBytesFromString(a, s) 281 | 282 | p := a.Alloc(unsafe.Sizeof(fwpByteBlob{})) 283 | *(*fwpByteBlob)(p) = fwpByteBlob{ 284 | Size: uint32(l), 285 | Data: bb, 286 | } 287 | typ = dataTypeByteBlob 288 | val = uintptr(p) 289 | case Range: 290 | r0, err := toRange0(a, s, ftype) 291 | if err != nil { 292 | return 0, 0, err 293 | } 294 | typ = dataTypeRange 295 | val = uintptr(unsafe.Pointer(r0)) 296 | default: 297 | return mapErr() 298 | } 299 | case typeSID: 300 | typ = dataTypeSID 301 | s, ok := v.(*windows.SID) 302 | if !ok { 303 | return mapErr() 304 | } 305 | sidLen := windows.GetLengthSid(s) 306 | p := a.Alloc(uintptr(sidLen)) 307 | if err := windows.CopySid(sidLen, (*windows.SID)(p), s); err != nil { 308 | return 0, 0, err 309 | } 310 | val = uintptr(p) 311 | case typeArray16: 312 | switch bs := v.(type) { 313 | case [16]byte: 314 | typ = dataTypeByteArray16 315 | val = uintptr(unsafe.Pointer(toBytes(a, bs[:]))) 316 | case Range: 317 | r0, err := toRange0(a, bs, ftype) 318 | if err != nil { 319 | return 0, 0, err 320 | } 321 | typ = dataTypeRange 322 | val = uintptr(unsafe.Pointer(r0)) 323 | default: 324 | return mapErr() 325 | } 326 | case typeMAC: 327 | typ = dataTypeArray6 328 | mac, ok := v.(net.HardwareAddr) 329 | if !ok { 330 | return mapErr() 331 | } 332 | if len(mac) != 6 { 333 | return mapErr() // TODO: better error 334 | } 335 | val = uintptr(unsafe.Pointer(toBytes(a, mac[:]))) 336 | case typeIP: 337 | switch m := v.(type) { 338 | case netip.Addr: 339 | if m.Is4() { 340 | typ = dataTypeUint32 341 | *(*uint32)(unsafe.Pointer(&val)) = u32FromIPv4(m) 342 | } else { 343 | typ = dataTypeByteArray16 344 | b16 := m.As16() 345 | val = uintptr(unsafe.Pointer(toBytes(a, b16[:]))) 346 | } 347 | case netip.Prefix: 348 | if m.Addr().Is4() { 349 | typ = dataTypeV4AddrMask 350 | val = uintptr(unsafe.Pointer(toFwpV4AddrAndMask(a, m))) 351 | } else { 352 | typ = dataTypeV6AddrMask 353 | val = uintptr(unsafe.Pointer(toFwpV6AddrAndMask(a, m))) 354 | } 355 | case netipx.IPRange: 356 | if !m.IsValid() { 357 | return 0, 0, fmt.Errorf("invalid IPRange %v", m) 358 | } 359 | r, err := toRange0(a, Range{m.From(), m.To()}, ftype) 360 | if err != nil { 361 | return 0, 0, err 362 | } 363 | typ = dataTypeRange 364 | val = uintptr(unsafe.Pointer(r)) 365 | default: 366 | return mapErr() 367 | } 368 | case typeSecurityDescriptor: 369 | sd, ok := v.(*windows.SECURITY_DESCRIPTOR) 370 | if !ok { 371 | return mapErr() 372 | } 373 | csd, err := toSecurityDescriptor(a, sd) 374 | if err != nil { 375 | return 0, 0, err 376 | } 377 | 378 | // This should be a FWP_BYTE_BLOB pointing to a 379 | // SECURITY_DESCRIPTOR struct according to the Win32 380 | // Documentation. 381 | // https://docs.microsoft.com/en-us/windows/win32/api/fwptypes/ns-fwptypes-fwp_condition_value0 382 | p := a.Alloc(unsafe.Sizeof(fwpByteBlob{})) 383 | *(*fwpByteBlob)(p) = fwpByteBlob{ 384 | Size: uint32(sd.Length()), 385 | Data: (*uint8)(unsafe.Pointer(csd)), 386 | } 387 | typ = dataTypeSecurityDescriptor 388 | val = uintptr(p) 389 | case typeRange: 390 | r, ok := v.(Range) 391 | if !ok { 392 | return mapErr() 393 | } 394 | r0, err := toRange0(a, r, ftype) 395 | if err != nil { 396 | return 0, 0, err 397 | } 398 | typ = dataTypeRange 399 | val = uintptr(unsafe.Pointer(r0)) 400 | default: 401 | return mapErr() 402 | } 403 | 404 | // TODO: dataTypeTokenInformation 405 | // TODO: dataTypeTokenAccessInformation 406 | 407 | return typ, val, nil 408 | } 409 | 410 | // toRange0 converts r into an arena-allocated fwpRange0. 411 | func toRange0(a *arena, r Range, ftype reflect.Type) (ret *fwpRange0, err error) { 412 | if _, ok := r.From.(Range); ok { 413 | return nil, errors.New("can't have a Range of Ranges") 414 | } 415 | if _, ok := r.To.(Range); ok { 416 | return nil, errors.New("can't have a Range of Ranges") 417 | } 418 | 419 | ftyp, fval, err := toValue0(a, r.From, ftype) 420 | if err != nil { 421 | return nil, err 422 | } 423 | ttyp, tval, err := toValue0(a, r.To, ftype) 424 | if err != nil { 425 | return nil, err 426 | } 427 | if ftyp != ttyp { 428 | return nil, fmt.Errorf("range type mismatch: %T vs. %T", r.From, r.To) 429 | } 430 | ret = (*fwpRange0)(a.Alloc(unsafe.Sizeof(fwpRange0{}))) 431 | 432 | *ret = fwpRange0{ 433 | From: fwpValue0{ 434 | Type: ftyp, 435 | Value: fval, 436 | }, 437 | To: fwpValue0{ 438 | Type: ttyp, 439 | Value: tval, 440 | }, 441 | } 442 | return ret, nil 443 | } 444 | 445 | // toUint16 converts s into an arena-allocated, null-terminated UTF-16 446 | // array pointer. 447 | func toUint16(a *arena, s string) *uint16 { 448 | if len(s) == 0 { 449 | return nil 450 | } 451 | 452 | n := windows.StringToUTF16(s) 453 | ret := a.Alloc(2 * uintptr(len(n))) 454 | 455 | var sl []uint16 456 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&sl)) 457 | sh.Cap = len(s) 458 | sh.Len = len(s) 459 | sh.Data = uintptr(ret) 460 | 461 | copy(sl, n) 462 | return (*uint16)(ret) 463 | } 464 | 465 | // toBytes converts bs into an arena-allocated byte array pointer. 466 | func toBytes(a *arena, bs []byte) *byte { 467 | if len(bs) == 0 { 468 | return nil 469 | } 470 | 471 | ret := a.Alloc(uintptr(len(bs))) 472 | 473 | var sl []byte 474 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&sl)) 475 | sh.Cap = len(bs) 476 | sh.Len = len(bs) 477 | sh.Data = uintptr(ret) 478 | 479 | copy(sl, bs) 480 | return (*byte)(ret) 481 | } 482 | 483 | // toBytes converts s into an arena-allocated byte array pointer, 484 | // containing a utf-16 encoded, null-terminated string. 485 | func toBytesFromString(a *arena, s string) (*byte, int) { 486 | bs := windows.StringToUTF16(s) 487 | 488 | l := 2 * len(bs) 489 | ret := a.Alloc(uintptr(l)) 490 | 491 | var retSlice []uint16 492 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&retSlice)) 493 | sh.Cap = len(bs) 494 | sh.Len = len(bs) 495 | sh.Data = uintptr(ret) 496 | copy(retSlice, bs) 497 | 498 | return (*byte)(ret), l 499 | } 500 | 501 | // toGUID returns an arena-allocated copy of guid. 502 | func toGUID(a *arena, guid windows.GUID) *windows.GUID { 503 | if guid == (windows.GUID{}) { 504 | return nil 505 | } 506 | ret := (*windows.GUID)(a.Alloc(unsafe.Sizeof(guid))) 507 | *ret = guid 508 | return ret 509 | } 510 | 511 | // toFwpV4AddrAndMask converts pfx into an arena-allocated 512 | // fwpV4AddrAndMask. 513 | func toFwpV4AddrAndMask(a *arena, pfx netip.Prefix) *fwpV4AddrAndMask { 514 | ret := (*fwpV4AddrAndMask)(a.Alloc(unsafe.Sizeof(fwpV4AddrAndMask{}))) 515 | ret.Addr = u32FromIPv4(pfx.Masked().Addr()) 516 | ret.Mask = (^uint32(0)) << (32 - pfx.Bits()) 517 | return ret 518 | } 519 | 520 | // toFwpV6AddrAndMask converts pfx into an arena-allocated 521 | // fwpV6AddrAndMask. 522 | func toFwpV6AddrAndMask(a *arena, pfx netip.Prefix) *fwpV6AddrAndMask { 523 | ret := (*fwpV6AddrAndMask)(a.Alloc(unsafe.Sizeof(fwpV6AddrAndMask{}))) 524 | ret.Addr = pfx.Addr().As16() 525 | ret.PrefixLength = uint8(pfx.Bits()) 526 | return ret 527 | } 528 | 529 | // toSecurityDescriptor returns an arena-allocated copy of s. 530 | func toSecurityDescriptor(a *arena, s *windows.SECURITY_DESCRIPTOR) (*windows.SECURITY_DESCRIPTOR, error) { 531 | s, err := s.ToSelfRelative() 532 | if err != nil { 533 | return nil, err 534 | } 535 | 536 | sl := s.Length() 537 | var from []byte 538 | sf := (*reflect.SliceHeader)(unsafe.Pointer(&from)) 539 | sf.Cap = int(sl) 540 | sf.Len = int(sl) 541 | sf.Data = uintptr(unsafe.Pointer(s)) 542 | 543 | p := a.Alloc(uintptr(s.Length())) 544 | var to []byte 545 | st := (*reflect.SliceHeader)(unsafe.Pointer(&to)) 546 | st.Cap = int(sl) 547 | st.Len = int(sl) 548 | st.Data = uintptr(p) 549 | 550 | copy(to, from) 551 | 552 | return (*windows.SECURITY_DESCRIPTOR)(p), nil 553 | } 554 | 555 | // u32FromIPv4 returns ip as a big-endian uint32. 556 | func u32FromIPv4(ip netip.Addr) uint32 { 557 | b4 := ip.As4() 558 | return binary.BigEndian.Uint32(b4[:]) 559 | } 560 | -------------------------------------------------------------------------------- /firewall.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package wf 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "net/netip" 11 | "reflect" 12 | "time" 13 | "unsafe" 14 | 15 | "golang.org/x/sys/windows" 16 | ) 17 | 18 | type fieldTypes map[FieldID]reflect.Type 19 | type layerTypes map[LayerID]fieldTypes 20 | 21 | // Session is a connection to the WFP API. 22 | type Session struct { 23 | handle windows.Handle 24 | // layerTypes is a map of layer ID -> field ID -> Go type for that field. 25 | layerTypes layerTypes 26 | } 27 | 28 | // Options configures a Session. 29 | type Options struct { 30 | // Name is a short name for the session, shown in Windows 31 | // administrative tools. 32 | Name string 33 | // Description is a short description for the session, shown in 34 | // Windows administrative tools. 35 | Description string 36 | // Dynamic, if true, indicates that all objects created during the 37 | // session should be removed when the session is closed or the 38 | // current process terminates. Dynamic sessions are meant for 39 | // adding firewall configuration that should not outlast your 40 | // program's execution. 41 | Dynamic bool 42 | // TransactionStartTimeout is how long the session is willing to 43 | // wait to acquire the global transaction lock. If zero, WFP's 44 | // default timeout (15 seconds) is used. 45 | TransactionStartTimeout time.Duration 46 | } 47 | 48 | // New connects to the WFP API. 49 | func New(opts *Options) (*Session, error) { 50 | if opts == nil { 51 | opts = &Options{} 52 | } 53 | 54 | var a arena 55 | defer a.Dispose() 56 | 57 | s0 := toSession0(&a, opts) 58 | 59 | var handle windows.Handle 60 | err := fwpmEngineOpen0(nil, authnServiceWinNT, nil, s0, &handle) 61 | if err != nil { 62 | return nil, err 63 | } 64 | 65 | ret := &Session{ 66 | handle: handle, 67 | layerTypes: layerTypes{}, 68 | } 69 | 70 | // Populate the layer type cache. 71 | layers, err := ret.Layers() 72 | if err != nil { 73 | ret.Close() 74 | return nil, err 75 | } 76 | for _, layer := range layers { 77 | fields := fieldTypes{} 78 | for _, field := range layer.Fields { 79 | fields[field.ID] = field.Type 80 | } 81 | ret.layerTypes[layer.ID] = fields 82 | } 83 | 84 | return ret, nil 85 | } 86 | 87 | // Close implements io.Closer. 88 | func (s *Session) Close() error { 89 | if s.handle == 0 { 90 | return nil 91 | } 92 | err := fwpmEngineClose0(s.handle) 93 | s.handle = 0 94 | return err 95 | } 96 | 97 | // LayerID identifies a WFP layer. 98 | type LayerID windows.GUID 99 | 100 | func (id LayerID) String() string { 101 | if s := guidNames[windows.GUID(id)]; s != "" { 102 | return s 103 | } 104 | return windows.GUID(id).String() 105 | } 106 | 107 | // IsZero reports whether id is nil or the zero GUID. 108 | func (id *LayerID) IsZero() bool { 109 | return id == nil || *id == LayerID{} 110 | } 111 | 112 | // ConditionFlag represents special conditions that can be tested. 113 | type ConditionFlag uint32 // do not change type, used in C calls 114 | 115 | const ( 116 | ConditionFlagIsLoopback ConditionFlag = 0x00000001 117 | ConditionFlagIsIPSecSecured ConditionFlag = 0x00000002 118 | ConditionFlagIsReauthorize ConditionFlag = 0x00000004 119 | ConditionFlagIsWildcardBind ConditionFlag = 0x00000008 120 | ConditionFlagIsRawEndpoint ConditionFlag = 0x00000010 121 | ConditionFlagIsFragmant ConditionFlag = 0x00000020 122 | ConditionFlagIsFragmantGroup ConditionFlag = 0x00000040 123 | ConditionFlagIsIPSecNATTReclassify ConditionFlag = 0x00000080 124 | ConditionFlagIsRequiresALEClassify ConditionFlag = 0x00000100 125 | ConditionFlagIsImplicitBind ConditionFlag = 0x00000200 126 | ConditionFlagIsReassembled ConditionFlag = 0x00000400 127 | ConditionFlagIsNameAppSpecified ConditionFlag = 0x00004000 128 | ConditionFlagIsPromiscuous ConditionFlag = 0x00008000 129 | ConditionFlagIsAuthFW ConditionFlag = 0x00010000 130 | ConditionFlagIsReclassify ConditionFlag = 0x00020000 131 | ConditionFlagIsOutboundPassThru ConditionFlag = 0x00040000 132 | ConditionFlagIsInboundPassThru ConditionFlag = 0x00080000 133 | ConditionFlagIsConnectionRedirected ConditionFlag = 0x00100000 134 | ) 135 | 136 | // IPProto represents the protocol being used. 137 | type IPProto uint8 // do not change type, used in C calls 138 | 139 | // From: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket 140 | const ( 141 | IPProtoICMP IPProto = 1 142 | IPProtoICMPV6 IPProto = 58 143 | IPProtoTCP IPProto = 6 144 | IPProtoUDP IPProto = 17 145 | ) 146 | 147 | // AppID returns the application ID associated with the provided file. 148 | func AppID(file string) (string, error) { 149 | var a arena 150 | defer a.Dispose() 151 | fileBytes, _ := toBytesFromString(&a, file) 152 | var appID *fwpByteBlob 153 | if err := fwpmGetAppIdFromFileName0(fileBytes, &appID); err != nil { 154 | return "", err 155 | } 156 | defer fwpmFreeMemory0((*struct{})(unsafe.Pointer(&appID))) 157 | return fromByteBlobToString(appID) 158 | } 159 | 160 | // Layer is a point in the packet processing path where filter rules 161 | // can be applied. 162 | type Layer struct { 163 | // ID is the unique identifier for this layer. 164 | ID LayerID 165 | // KernelID is the internal kernel ID for this layer. 166 | KernelID uint16 167 | // Name is a short descriptive name. 168 | Name string 169 | // Description is a longer description of the layer's function. 170 | Description string 171 | // DefaultSublayer is the ID for the default sublayer into which 172 | // filter rules are added. 173 | DefaultSublayer SublayerID 174 | // Fields describes the fields that are available in this layer to 175 | // be matched against. 176 | Fields []*Field 177 | } 178 | 179 | // FieldID identifies a WFP layer field. 180 | type FieldID windows.GUID 181 | 182 | func (id FieldID) String() string { 183 | if s := guidNames[windows.GUID(id)]; s != "" { 184 | return s 185 | } 186 | return windows.GUID(id).String() 187 | } 188 | 189 | // IsZero reports whether id is nil or the zero GUID. 190 | func (id *FieldID) IsZero() bool { 191 | return id == nil || *id == FieldID{} 192 | } 193 | 194 | // Field is a piece of information that a layer makes available to 195 | // filter rules for matching. 196 | type Field struct { 197 | // ID is the unique identifier for the field. 198 | ID FieldID 199 | // Type is the type of the field. 200 | Type reflect.Type 201 | } 202 | 203 | // TokenAccessInformation represents all the information in a token 204 | // that is necessary to perform an access check. 205 | // This type is only present in Layer fields, and cannot be used 206 | // directly as a value in firewall rules. 207 | type TokenAccessInformation struct{} 208 | 209 | type Range struct { 210 | From, To interface{} 211 | } 212 | 213 | // TokenInformation defines a set of security identifiers. 214 | // This type is only present in Layer fields, and cannot be used 215 | // directly as a value in firewall rules. 216 | type TokenInformation struct{} 217 | 218 | // Layers returns information on available WFP layers. 219 | func (s *Session) Layers() ([]*Layer, error) { 220 | var enum windows.Handle 221 | if err := fwpmLayerCreateEnumHandle0(s.handle, nil, &enum); err != nil { 222 | return nil, err 223 | } 224 | defer fwpmLayerDestroyEnumHandle0(s.handle, enum) 225 | 226 | var ret []*Layer 227 | 228 | for { 229 | layers, err := s.getLayerPage(enum) 230 | if err != nil { 231 | return nil, err 232 | } 233 | if len(layers) == 0 { 234 | return ret, nil 235 | } 236 | ret = append(ret, layers...) 237 | } 238 | } 239 | 240 | func (s *Session) getLayerPage(enum windows.Handle) ([]*Layer, error) { 241 | const pageSize = 100 242 | var ( 243 | array **fwpmLayer0 244 | num uint32 245 | ) 246 | if err := fwpmLayerEnum0(s.handle, enum, pageSize, &array, &num); err != nil { 247 | return nil, err 248 | } 249 | if num == 0 { 250 | return nil, nil 251 | } 252 | defer fwpmFreeMemory0((*struct{})(unsafe.Pointer(&array))) 253 | 254 | return fromLayer0(array, num) 255 | } 256 | 257 | // SublayerID identifies a WFP sublayer. 258 | type SublayerID windows.GUID 259 | 260 | func (id SublayerID) String() string { 261 | if s := guidNames[windows.GUID(id)]; s != "" { 262 | return s 263 | } 264 | return windows.GUID(id).String() 265 | } 266 | 267 | // IsZero reports whether id is nil or the zero GUID. 268 | func (id *SublayerID) IsZero() bool { 269 | return id == nil || *id == SublayerID{} 270 | } 271 | 272 | // A Sublayer is a container for filtering rules. 273 | type Sublayer struct { 274 | // ID is the unique identifier for this sublayer. 275 | ID SublayerID 276 | // Name is a short descriptive name. 277 | Name string 278 | // Description is a longer description of the Sublayer. 279 | Description string 280 | // Persistent indicates whether the sublayer is preserved across 281 | // restarts of the filtering engine. 282 | Persistent bool 283 | // Provider optionally identifies the Provider that manages this 284 | // sublayer. 285 | Provider ProviderID 286 | // ProviderData is optional opaque data that can be held on behalf 287 | // of the Provider. 288 | ProviderData []byte 289 | // Weight specifies the priority of this sublayer relative to 290 | // other sublayers. Higher-weighted sublayers are invoked first. 291 | Weight uint16 292 | } 293 | 294 | // Sublayers returns available Sublayers. If providers are given, 295 | // returns only sublayers registered to those providers. 296 | func (s *Session) Sublayers(providers ...ProviderID) ([]*Sublayer, error) { 297 | if len(providers) == 0 { 298 | // Do one lookup with a zero provider, which returns all 299 | // sublayers. 300 | providers = []ProviderID{ProviderID{}} 301 | } 302 | 303 | var ret []*Sublayer 304 | for _, provider := range providers { 305 | sls, err := s.getOneProvider(provider) 306 | if err != nil { 307 | return nil, err 308 | } 309 | ret = append(ret, sls...) 310 | } 311 | 312 | return ret, nil 313 | } 314 | 315 | func (s *Session) getOneProvider(provider ProviderID) ([]*Sublayer, error) { 316 | var a arena 317 | defer a.Dispose() 318 | 319 | tpl := toSublayerEnumTemplate0(&a, provider) 320 | 321 | var enum windows.Handle 322 | if err := fwpmSubLayerCreateEnumHandle0(s.handle, tpl, &enum); err != nil { 323 | return nil, err 324 | } 325 | defer fwpmSubLayerDestroyEnumHandle0(s.handle, enum) 326 | 327 | var ret []*Sublayer 328 | 329 | for { 330 | sublayers, err := s.getSublayerPage(enum) 331 | if err != nil { 332 | return nil, err 333 | } 334 | if len(sublayers) == 0 { 335 | return ret, nil 336 | } 337 | ret = append(ret, sublayers...) 338 | } 339 | } 340 | 341 | func (s *Session) getSublayerPage(enum windows.Handle) ([]*Sublayer, error) { 342 | const pageSize = 100 343 | var ( 344 | array **fwpmSublayer0 345 | num uint32 346 | ) 347 | if err := fwpmSubLayerEnum0(s.handle, enum, pageSize, &array, &num); err != nil { 348 | return nil, err 349 | } 350 | if num == 0 { 351 | return nil, nil 352 | } 353 | defer fwpmFreeMemory0((*struct{})(unsafe.Pointer(&array))) 354 | 355 | return fromSublayer0(array, num), nil 356 | } 357 | 358 | // AddSublayer creates a new Sublayer. 359 | func (s *Session) AddSublayer(sl *Sublayer) error { 360 | // the WFP API accepts zero GUIDs and interprets it as "give me a 361 | // random GUID". However, we can't get that GUID back out, so it 362 | // would be pointless to make such a request. Stop it here. 363 | if sl.ID.IsZero() { 364 | return errors.New("Sublayer.ID cannot be zero") 365 | } 366 | 367 | var a arena 368 | defer a.Dispose() 369 | 370 | sl0 := toSublayer0(&a, sl) 371 | return fwpmSubLayerAdd0(s.handle, sl0, nil) // TODO: security descriptor 372 | } 373 | 374 | // DeleteSublayer deletes the Sublayer whose GUID is id. 375 | func (s *Session) DeleteSublayer(id SublayerID) error { 376 | if id.IsZero() { 377 | return errors.New("GUID cannot be zero") 378 | } 379 | 380 | return fwpmSubLayerDeleteByKey0(s.handle, &id) 381 | } 382 | 383 | // ProviderID identifies a WFP provider. 384 | type ProviderID windows.GUID 385 | 386 | func (id ProviderID) String() string { 387 | if s := guidNames[windows.GUID(id)]; s != "" { 388 | return s 389 | } 390 | return windows.GUID(id).String() 391 | } 392 | 393 | // IsZero reports whether id is nil or the zero GUID. 394 | func (id *ProviderID) IsZero() bool { 395 | return id == nil || *id == ProviderID{} 396 | } 397 | 398 | // A Provider is an entity that owns sublayers and filtering rules. 399 | type Provider struct { 400 | // ID is the unique identifier for this provider. 401 | ID ProviderID 402 | // Name is a short descriptive name. 403 | Name string 404 | // Description is a longer description of the provider. 405 | Description string 406 | // Persistent indicates whether the provider is preserved across 407 | // restarts of the filtering engine. 408 | Persistent bool 409 | // Data is optional opaque data that can be held on behalf of the 410 | // Provider. 411 | Data []byte 412 | // ServiceName is an optional Windows service name. If present, 413 | // the rules owned by this Provider are only activated when the 414 | // service is active. 415 | ServiceName string 416 | 417 | // Disabled indicates whether the rules owned by this Provider are 418 | // disabled due to its associated service being 419 | // disabled. Read-only, ignored on Provider creation. 420 | Disabled bool 421 | } 422 | 423 | func (s *Session) Providers() ([]*Provider, error) { 424 | var enum windows.Handle 425 | if err := fwpmProviderCreateEnumHandle0(s.handle, nil, &enum); err != nil { 426 | return nil, err 427 | } 428 | defer fwpmProviderDestroyEnumHandle0(s.handle, enum) 429 | 430 | var ret []*Provider 431 | 432 | for { 433 | providers, err := s.getProviderPage(enum) 434 | if err != nil { 435 | return nil, err 436 | } 437 | if len(providers) == 0 { 438 | return ret, nil 439 | } 440 | ret = append(ret, providers...) 441 | } 442 | } 443 | 444 | func (s *Session) getProviderPage(enum windows.Handle) ([]*Provider, error) { 445 | const pageSize = 100 446 | var ( 447 | array **fwpmProvider0 448 | num uint32 449 | ) 450 | if err := fwpmProviderEnum0(s.handle, enum, pageSize, &array, &num); err != nil { 451 | return nil, err 452 | } 453 | if num == 0 { 454 | return nil, nil 455 | } 456 | defer fwpmFreeMemory0((*struct{})(unsafe.Pointer(&array))) 457 | 458 | return fromProvider0(array, num), nil 459 | } 460 | 461 | // AddProvider creates a new provider. 462 | func (s *Session) AddProvider(p *Provider) error { 463 | if p.ID.IsZero() { 464 | return errors.New("Provider.ID cannot be zero") 465 | } 466 | 467 | var a arena 468 | defer a.Dispose() 469 | 470 | p0 := toProvider0(&a, p) 471 | 472 | return fwpmProviderAdd0(s.handle, p0, nil) 473 | } 474 | 475 | // DeleteProvider deletes the Provider whose GUID is id. A provider 476 | // can only be deleted once all the resources it owns have been 477 | // deleted. 478 | func (s *Session) DeleteProvider(id ProviderID) error { 479 | if id.IsZero() { 480 | return errors.New("GUID cannot be zero") 481 | } 482 | 483 | return fwpmProviderDeleteByKey0(s.handle, &id) 484 | } 485 | 486 | // MatchType is the operator to use when testing a field in a Match. 487 | type MatchType uint32 // do not change type, used in C calls 488 | 489 | const ( 490 | MatchTypeEqual MatchType = iota 491 | MatchTypeGreater 492 | MatchTypeLess 493 | MatchTypeGreaterOrEqual 494 | MatchTypeLessOrEqual 495 | MatchTypeRange // true if the field value is within the Range. 496 | MatchTypeFlagsAllSet 497 | MatchTypeFlagsAnySet 498 | MatchTypeFlagsNoneSet 499 | MatchTypeEqualCaseInsensitive // only valid on strings, no string fields exist 500 | MatchTypeNotEqual 501 | MatchTypePrefix // TODO: not well documented. Is this prefix.Contains(ip) ? 502 | MatchTypeNotPrefix // TODO: see above. 503 | ) 504 | 505 | var mtStr = map[MatchType]string{ 506 | MatchTypeEqual: "==", 507 | MatchTypeGreater: ">", 508 | MatchTypeLess: "<", 509 | MatchTypeGreaterOrEqual: ">=", 510 | MatchTypeLessOrEqual: "<=", 511 | MatchTypeRange: "in", 512 | MatchTypeFlagsAllSet: "F[all]", 513 | MatchTypeFlagsAnySet: "F[any]", 514 | MatchTypeFlagsNoneSet: "F[none]", 515 | MatchTypeEqualCaseInsensitive: "i==", 516 | MatchTypeNotEqual: "!=", 517 | MatchTypePrefix: "pfx", 518 | MatchTypeNotPrefix: "!pfx", 519 | } 520 | 521 | func (m MatchType) String() string { 522 | return mtStr[m] 523 | } 524 | 525 | // Match is a matching test that gets run against a layer's field. 526 | type Match struct { 527 | Field FieldID 528 | Op MatchType 529 | Value interface{} 530 | } 531 | 532 | func (m Match) String() string { 533 | return fmt.Sprintf("%s %s %v (%T)", m.Field, m.Op, m.Value, m.Value) 534 | } 535 | 536 | // Action is an action the filtering engine can execute. 537 | type Action uint32 538 | 539 | const ( 540 | // ActionBlock blocks a packet or session. 541 | ActionBlock Action = 0x1001 542 | // ActionPermit permits a packet or session. 543 | ActionPermit Action = 0x1002 544 | // ActionCalloutTerminating invokes a callout that must return a 545 | // permit or block verdict. 546 | ActionCalloutTerminating Action = 0x5003 547 | // ActionCalloutInspection invokes a callout that is expected to 548 | // not return a verdict (i.e. a read-only callout). 549 | ActionCalloutInspection Action = 0x6004 550 | // ActionCalloutUnknown invokes a callout that may return a permit 551 | // or block verdict. 552 | ActionCalloutUnknown Action = 0x4005 553 | ) 554 | 555 | // RuleID identifies a WFP filtering rule. 556 | type RuleID windows.GUID 557 | 558 | func (id RuleID) String() string { 559 | if s := guidNames[windows.GUID(id)]; s != "" { 560 | return s 561 | } 562 | return windows.GUID(id).String() 563 | } 564 | 565 | // IsZero reports whether id is nil or the zero GUID. 566 | func (id *RuleID) IsZero() bool { 567 | return id == nil || *id == RuleID{} 568 | } 569 | 570 | // CalloutID identifies a WFP callout function. 571 | type CalloutID windows.GUID 572 | 573 | func (id CalloutID) String() string { 574 | if s := guidNames[windows.GUID(id)]; s != "" { 575 | return s 576 | } 577 | return windows.GUID(id).String() 578 | } 579 | 580 | // IsZero reports whether id is nil or the zero GUID. 581 | func (id *CalloutID) IsZero() bool { 582 | return id == nil || *id == CalloutID{} 583 | } 584 | 585 | // A Rule is an action to take on packets that match a set of 586 | // conditions. 587 | type Rule struct { 588 | // ID is the unique identifier for this rule. 589 | ID RuleID 590 | // KernelID is the kernel ID for this rule. 591 | KernelID uint64 592 | // Name is a short descriptive name. 593 | Name string 594 | // Description is a longer description of the rule. 595 | Description string 596 | // Layer is the ID of the layer in which the rule runs. 597 | Layer LayerID 598 | // Sublayer is the ID of the sublayer in which the rule runs. 599 | Sublayer SublayerID 600 | // Weight is the priority of the rule relative to other rules in 601 | // its sublayer. 602 | Weight uint64 603 | // Conditions are the tests which must pass for this rule to apply 604 | // to a packet. 605 | Conditions []*Match 606 | // Action is the action to take on matching packets. 607 | Action Action 608 | // Callout is the ID of the callout to invoke. Only valid if 609 | // Action is ActionCalloutTerminating, ActionCalloutInspection, or 610 | // ActionCalloutUnknown. 611 | Callout CalloutID 612 | // PermitIfMissing, if set, indicates that a callout action to a 613 | // callout ID that isn't registered should be translated into an 614 | // ActionPermit, rather than an ActionBlock. Only relevant if 615 | // Action is ActionCalloutTerminating or ActionCalloutUnknown. 616 | PermitIfMissing bool 617 | // HardAction, if set, indicates that the action type is hard and cannot 618 | // be overridden except by a Veto. 619 | HardAction bool 620 | 621 | // Persistent indicates whether the rule is preserved across 622 | // restarts of the filtering engine. 623 | Persistent bool 624 | // BootTime indicates that this rule applies only during early 625 | // boot, before the filtering engine fully starts and hands off to 626 | // the normal runtime rules. 627 | BootTime bool 628 | 629 | // Provider optionally identifies the Provider that manages this 630 | // rule. 631 | Provider ProviderID 632 | // ProviderData is optional opaque data that can be held on behalf 633 | // of the Provider. 634 | ProviderData []byte 635 | 636 | // Disabled indicates whether the rule is currently disabled due 637 | // to its provider being associated with an inactive Windows 638 | // service. See Provider.ServiceName for details. 639 | Disabled bool 640 | } 641 | 642 | // TODO: figure out what currently unexposed flags do: Indexed 643 | // TODO: figure out what ProviderContextKey is about. MSDN doesn't explain what contexts are. 644 | 645 | func (s *Session) Rules() ([]*Rule, error) { // TODO: support filter settings 646 | var enum windows.Handle 647 | if err := fwpmFilterCreateEnumHandle0(s.handle, nil, &enum); err != nil { 648 | return nil, err 649 | } 650 | defer fwpmFilterDestroyEnumHandle0(s.handle, enum) 651 | 652 | var ret []*Rule 653 | 654 | for { 655 | rules, err := s.getRulePage(enum) 656 | if err != nil { 657 | return nil, err 658 | } 659 | if len(rules) == 0 { 660 | return ret, nil 661 | } 662 | ret = append(ret, rules...) 663 | } 664 | } 665 | 666 | func (s *Session) getRulePage(enum windows.Handle) ([]*Rule, error) { 667 | const pageSize = 100 668 | var ( 669 | array **fwpmFilter0 670 | num uint32 671 | ) 672 | if err := fwpmFilterEnum0(s.handle, enum, pageSize, &array, &num); err != nil { 673 | return nil, err 674 | } 675 | if num == 0 { 676 | return nil, nil 677 | } 678 | defer fwpmFreeMemory0((*struct{})(unsafe.Pointer(&array))) 679 | 680 | return fromFilter0(array, num, s.layerTypes) 681 | } 682 | 683 | func (s *Session) AddRule(r *Rule) error { 684 | if r.ID.IsZero() { 685 | return errors.New("Provider.ID cannot be zero") 686 | } 687 | 688 | var a arena 689 | defer a.Dispose() 690 | 691 | f, err := toFilter0(&a, r, s.layerTypes) 692 | if err != nil { 693 | return err 694 | } 695 | if err := fwpmFilterAdd0(s.handle, f, nil, &f.FilterID); err != nil { 696 | return err 697 | } 698 | 699 | return nil 700 | } 701 | 702 | func (s *Session) DeleteRule(id RuleID) error { 703 | if id.IsZero() { 704 | return errors.New("GUID cannot be zero") 705 | } 706 | 707 | return fwpmFilterDeleteByKey0(s.handle, &id) 708 | } 709 | 710 | type DropEvent struct { 711 | Timestamp time.Time 712 | IPProtocol uint8 713 | LocalAddr netip.AddrPort 714 | RemoteAddr netip.AddrPort 715 | AppID string 716 | 717 | LayerID uint16 718 | FilterID uint64 719 | } 720 | 721 | func (s *Session) DropEvents() ([]*DropEvent, error) { 722 | var enum windows.Handle 723 | if err := fwpmNetEventCreateEnumHandle0(s.handle, nil, &enum); err != nil { 724 | return nil, err 725 | } 726 | defer fwpmNetEventDestroyEnumHandle0(s.handle, enum) 727 | 728 | var ret []*DropEvent 729 | 730 | for { 731 | events, err := s.getEventPage(enum) 732 | if err != nil { 733 | return nil, err 734 | } 735 | if len(events) == 0 { 736 | return ret, nil 737 | } 738 | ret = append(ret, events...) 739 | } 740 | } 741 | 742 | func (s *Session) getEventPage(enum windows.Handle) ([]*DropEvent, error) { 743 | const pageSize = 100 744 | var ( 745 | array **fwpmNetEvent1 746 | num uint32 747 | ) 748 | if err := fwpmNetEventEnum1(s.handle, enum, pageSize, &array, &num); err != nil { 749 | return nil, err 750 | } 751 | if num == 0 { 752 | return nil, nil 753 | } 754 | defer fwpmFreeMemory0((*struct{})(unsafe.Pointer(&array))) 755 | 756 | return fromNetEvent1(array, num) 757 | } 758 | -------------------------------------------------------------------------------- /firewall_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package wf 6 | 7 | import ( 8 | "os" 9 | "sort" 10 | "testing" 11 | "time" 12 | 13 | "github.com/google/go-cmp/cmp" 14 | "golang.org/x/sys/windows" 15 | ) 16 | 17 | func skipIfUnprivileged(t *testing.T) { 18 | if !windows.GetCurrentProcessToken().IsElevated() { 19 | if os.Getenv("CI") != "" { 20 | t.Fatal("test requires admin privileges") 21 | } 22 | t.Skipf("skipping test that requires admin privileges") 23 | } 24 | } 25 | 26 | func TestSession(t *testing.T) { 27 | skipIfUnprivileged(t) 28 | 29 | tests := []struct { 30 | name string 31 | opts *Options 32 | }{ 33 | { 34 | name: "nil", 35 | opts: nil, 36 | }, 37 | { 38 | name: "name_only", 39 | opts: &Options{ 40 | Name: "test", 41 | }, 42 | }, 43 | { 44 | name: "name_and_desc", 45 | opts: &Options{ 46 | Name: "test2", 47 | Description: "unit test session", 48 | }, 49 | }, 50 | { 51 | name: "dynamic", 52 | opts: &Options{ 53 | Name: "test2", 54 | Dynamic: true, 55 | }, 56 | }, 57 | { 58 | name: "tx_timeout", 59 | opts: &Options{ 60 | Name: "test2", 61 | TransactionStartTimeout: 5 * time.Minute, 62 | }, 63 | }, 64 | } 65 | 66 | for _, test := range tests { 67 | t.Run(test.name, func(t *testing.T) { 68 | sess, err := New(test.opts) 69 | if err != nil { 70 | t.Fatalf("failed to open session: %v", err) 71 | } 72 | if err := sess.Close(); err != nil { 73 | t.Errorf("closing session: %v", err) 74 | } 75 | }) 76 | } 77 | } 78 | 79 | func TestLayers(t *testing.T) { 80 | skipIfUnprivileged(t) 81 | 82 | s, err := New(nil) 83 | if err != nil { 84 | t.Fatal(err) 85 | } 86 | defer s.Close() 87 | 88 | layers, err := s.Layers() 89 | if err != nil { 90 | t.Fatalf("getting layers: %v", err) 91 | } 92 | 93 | // Try to find a couple of the well-known layers that Windows 94 | // should definitely have. 95 | wantLayers := map[LayerID]*Layer{ 96 | LayerALEAuthRecvAcceptV4: { 97 | ID: LayerALEAuthRecvAcceptV4, 98 | KernelID: 44, 99 | Name: "ALE Receive/Accept v4 Layer", 100 | DefaultSublayer: guidSublayerUniversal, 101 | Fields: []*Field{ 102 | {FieldALEAppID, typeString}, 103 | {FieldALENAPContext, typeUint32}, 104 | {FieldALEPackageID, typeSID}, 105 | {FieldALERemoteMachineID, typeSecurityDescriptor}, 106 | {FieldALERemoteUserID, typeSecurityDescriptor}, 107 | {FieldALESecurityAttributeFqbnValue, typeBytes}, 108 | {FieldALESioFirewallSystemPort, typeUint32}, 109 | {FieldALEUserID, typeSecurityDescriptor}, 110 | {FieldArrivalInterfaceIndex, typeUint32}, 111 | {FieldArrivalInterfaceType, typeUint32}, 112 | {FieldArrivalTunnelType, typeUint32}, 113 | {FieldBitmapIPLocalAddress, typeBitmapIndex}, 114 | {FieldBitmapIPLocalPort, typeBitmapIndex}, 115 | {FieldBitmapIPRemoteAddress, typeBitmapIndex}, 116 | {FieldBitmapIPRemotePort, typeBitmapIndex}, 117 | {FieldCompartmentID, typeUint32}, 118 | {FieldCurrentProfileID, typeUint32}, 119 | {FieldFlags, typeUint32}, 120 | {FieldInterfaceIndex, typeUint32}, 121 | {FieldInterfaceQuarantineEpoch, typeUint64}, 122 | {FieldInterfaceType, typeUint32}, 123 | {FieldIPArrivalInterface, typeUint64}, 124 | {FieldIPLocalAddress, typeIP}, 125 | {FieldIPLocalAddressType, typeUint8}, 126 | {FieldIPLocalInterface, typeUint64}, 127 | {FieldIPLocalPort, typeUint16}, 128 | {FieldIPNexthopInterface, typeUint64}, 129 | {FieldIPProtocol, typeUint8}, 130 | {FieldIPRemoteAddress, typeIP}, 131 | {FieldIPRemotePort, typeUint16}, 132 | {FieldNexthopInterfaceIndex, typeUint32}, 133 | {FieldNexthopInterfaceType, typeUint32}, 134 | {FieldNexthopSubInterfaceIndex, typeUint32}, 135 | {FieldNexthopTunnelType, typeUint32}, 136 | {FieldOriginalICMPType, typeUint16}, 137 | {FieldOriginalProfileID, typeUint32}, 138 | {FieldReauthorizeReason, typeUint32}, 139 | {FieldSubInterfaceIndex, typeUint32}, 140 | {FieldTunnelType, typeUint32}, 141 | }, 142 | }, 143 | LayerStreamV4Discard: { 144 | ID: LayerStreamV4Discard, 145 | KernelID: 21, 146 | Name: "Stream v4 Discard Layer", 147 | DefaultSublayer: guidSublayerUniversal, 148 | Fields: []*Field{ 149 | {FieldCompartmentID, typeUint32}, 150 | {FieldDirection, typeUint32}, 151 | {FieldFlags, typeUint32}, 152 | {FieldIPLocalAddress, typeIP}, 153 | {FieldIPLocalAddressType, typeUint8}, 154 | {FieldIPLocalPort, typeUint16}, 155 | {FieldIPRemoteAddress, typeIP}, 156 | {FieldIPRemotePort, typeUint16}, 157 | }, 158 | }, 159 | } 160 | 161 | for guid, want := range wantLayers { 162 | found := false 163 | for _, got := range layers { 164 | if got.ID != guid { 165 | continue 166 | } 167 | found = true 168 | sort.Slice(got.Fields, func(i, j int) bool { 169 | return got.Fields[i].ID.String() < got.Fields[j].ID.String() 170 | }) 171 | fieldCmp := func(a, b *Field) bool { 172 | return a.ID == b.ID && a.Type == b.Type 173 | } 174 | if diff := cmp.Diff(got, want, cmp.Comparer(fieldCmp)); diff != "" { 175 | t.Errorf("unexpected layer def (-got+want):\n%s", diff) 176 | } 177 | break 178 | } 179 | if !found { 180 | t.Errorf("layer %s (%s) not found", guid, windows.GUID(guid)) 181 | } 182 | } 183 | } 184 | 185 | func TestSublayers(t *testing.T) { 186 | skipIfUnprivileged(t) 187 | 188 | s, err := New(&Options{ 189 | Dynamic: true, 190 | }) 191 | if err != nil { 192 | t.Fatal(err) 193 | } 194 | defer s.Close() 195 | 196 | guid, err := windows.GenerateGUID() 197 | if err != nil { 198 | t.Fatal(err) 199 | } 200 | 201 | sl := &Sublayer{ 202 | ID: SublayerID(guid), 203 | Name: "test sublayer", 204 | Description: "a test sublayer", 205 | ProviderData: []byte("byte blob"), 206 | Weight: 0x4242, 207 | } 208 | if err := s.AddSublayer(sl); err != nil { 209 | t.Fatalf("add sublayer failed: %v", err) 210 | } 211 | 212 | sublayers, err := s.Sublayers(ProviderID{}) 213 | if err != nil { 214 | t.Fatalf("get sublayers failed: %v", err) 215 | } 216 | 217 | found := false 218 | for _, got := range sublayers { 219 | if got.ID != sl.ID { 220 | continue 221 | } 222 | found = true 223 | if diff := cmp.Diff(got, sl); diff != "" { 224 | t.Fatalf("sublayer is wrong (-got+want):\n%s", diff) 225 | } 226 | break 227 | } 228 | if !found { 229 | t.Fatal("sublayer added but not found") 230 | } 231 | 232 | if err := s.DeleteSublayer(sl.ID); err != nil { 233 | t.Fatalf("delete sublayer failed: %v", err) 234 | } 235 | 236 | sublayers, err = s.Sublayers(ProviderID{}) 237 | if err != nil { 238 | t.Fatalf("get sublayers failed: %v", err) 239 | } 240 | for _, got := range sublayers { 241 | if got.ID == sl.ID { 242 | t.Fatalf("deleted sublayer but it's still there: %#v", got) 243 | } 244 | } 245 | } 246 | 247 | func TestProviders(t *testing.T) { 248 | skipIfUnprivileged(t) 249 | 250 | s, err := New(&Options{ 251 | Dynamic: true, 252 | }) 253 | if err != nil { 254 | t.Fatal(err) 255 | } 256 | defer s.Close() 257 | 258 | guid, err := windows.GenerateGUID() 259 | if err != nil { 260 | t.Fatal(err) 261 | } 262 | 263 | p := &Provider{ 264 | ID: ProviderID(guid), 265 | Name: "test provider", 266 | Description: "a test provider", 267 | Data: []byte("byte blob"), 268 | } 269 | if err := s.AddProvider(p); err != nil { 270 | t.Fatalf("add provider failed: %v", err) 271 | } 272 | 273 | providers, err := s.Providers() 274 | if err != nil { 275 | t.Fatalf("get providers failed: %v", err) 276 | } 277 | 278 | found := false 279 | for _, got := range providers { 280 | if got.ID != p.ID { 281 | continue 282 | } 283 | found = true 284 | if diff := cmp.Diff(got, p); diff != "" { 285 | t.Fatalf("provider is wrong (-got+want):\n%s", diff) 286 | } 287 | break 288 | } 289 | if !found { 290 | t.Fatal("provider added but not found") 291 | } 292 | 293 | if err := s.DeleteProvider(p.ID); err != nil { 294 | t.Fatalf("delete provider failed: %v", err) 295 | } 296 | 297 | providers, err = s.Providers() 298 | if err != nil { 299 | t.Fatalf("get providers failed: %v", err) 300 | } 301 | for _, got := range providers { 302 | if got.ID == p.ID { 303 | t.Fatalf("deleted provider but it's still there: %#v", got) 304 | } 305 | } 306 | } 307 | -------------------------------------------------------------------------------- /generate.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package wf 6 | 7 | //go:generate go run generators/gen_guids.go includes/fwpmu.h zguids.go 8 | //go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall.go 9 | 10 | //go:generate stringer -output=zfieldtype_strings.go -type=fwpmFieldType -trimprefix=fwpmFieldtype 11 | //go:generate stringer -output=zsublayerflags_strings.go -type=fwpmSublayerFlags -trimprefix=fwpmSublayerFlags 12 | //go:generate stringer -output=zfilterenumtype_strings.go -type=filterEnumType -trimprefix=filterEnumType 13 | //go:generate stringer -output=zfilterenumflags_strings.go -type=filterEnumFlags -trimprefix=filterEnumFlags 14 | //go:generate stringer -output=zaction_strings.go -type=Action -trimprefix=Action 15 | //go:generate stringer -output=zfilterflags_strings.go -type=fwpmFilterFlags -trimprefix=fwpmFilterFlags 16 | //go:generate stringer -output=zproviderflags_strings.go -type=fwpmProviderFlags -trimprefix=fwpmProviderFlags 17 | //go:generate stringer -output=zdatatype_strings.go -type=dataType -trimprefix=dataType 18 | //go:generate stringer -output=zconditionflag_strings.go -type=ConditionFlag -trimprefix=ConditionFlag 19 | //go:generate stringer -output=zipproto_strings.go -type=IPProto -trimprefix=IPProto 20 | -------------------------------------------------------------------------------- /generators/gen_guids.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "bufio" 9 | "bytes" 10 | "fmt" 11 | "go/format" 12 | "io" 13 | "io/ioutil" 14 | "os" 15 | "sort" 16 | "strings" 17 | ) 18 | 19 | func fatalf(msg string, args ...interface{}) { 20 | fmt.Printf(msg+"\n", args...) 21 | os.Exit(1) 22 | } 23 | 24 | func main() { 25 | fwpmuPath, outPath := os.Args[1], os.Args[2] 26 | 27 | f, err := os.Open(fwpmuPath) 28 | if err != nil { 29 | fatalf("reading .h: %v", err) 30 | } 31 | defer f.Close() 32 | 33 | r := bufio.NewReader(f) 34 | 35 | var out bytes.Buffer 36 | out.WriteString(`package wf 37 | 38 | import "golang.org/x/sys/windows" 39 | 40 | `) 41 | 42 | defs := map[string][]string{} 43 | var generated []guidName 44 | 45 | for { 46 | l, err := r.ReadString('\n') 47 | if err == io.EOF { 48 | break 49 | } else if err != nil { 50 | fatalf("reading from .h: %v", err) 51 | } 52 | l = strings.TrimSpace(l) 53 | 54 | if !strings.HasPrefix(l, "DEFINE_GUID(") { 55 | continue 56 | } 57 | 58 | name, g1, g2, g3, g4, err := readGUIDDef(r, l) 59 | if err != nil { 60 | fatalf("reading GUID def: %v", err) 61 | } 62 | 63 | defs[name.Type()] = append(defs[name.Type()], fmt.Sprintf("%s = %s{%s, %s, %s, [8]byte{%s}}", name.VarName(), name.GoType(), g1, g2, g3, g4)) 64 | generated = append(generated, name) 65 | } 66 | 67 | var types []string 68 | for typ := range defs { 69 | types = append(types, typ) 70 | } 71 | sort.Strings(types) 72 | for _, typ := range types { 73 | fmt.Fprintf(&out, "// Well-known %s IDs.\n", strings.ToLower(typ)) 74 | fmt.Fprintf(&out, "var (\n") 75 | vars := defs[typ] 76 | sort.Strings(vars) 77 | for _, v := range vars { 78 | fmt.Fprintf(&out, "%s\n", v) 79 | } 80 | fmt.Fprintf(&out, ")\n\n") 81 | } 82 | 83 | sort.Slice(generated, func(i, j int) bool { return generated[i] < generated[j] }) 84 | 85 | out.WriteString("var guidNames = map[windows.GUID]string{\n") 86 | for _, name := range generated { 87 | v := name.VarName() 88 | if name.GoType() != "windows.GUID" { 89 | v = fmt.Sprintf("windows.GUID(%s)", v) 90 | } 91 | fmt.Fprintf(&out, "%s: %q,\n", v, name.String()) 92 | } 93 | out.WriteString("}\n") 94 | 95 | bs, err := format.Source(out.Bytes()) 96 | if err != nil { 97 | fatalf("formatting source code: %v", err) 98 | } 99 | 100 | if err := ioutil.WriteFile(outPath, bs, 0644); err != nil { 101 | fatalf("writing generated file: %v", err) 102 | } 103 | } 104 | 105 | type guidName string 106 | 107 | // Type returns the datatype of the GUID. 108 | // e.g. FWPM_LAYER_BLAH_BLAH -> "layer" 109 | func (g guidName) Type() string { 110 | ret := strings.ToLower(strings.Split(string(g), "_")[1]) 111 | switch ret { 112 | case "condition": 113 | return "field" 114 | default: 115 | return ret 116 | } 117 | } 118 | 119 | func (g guidName) Exported() bool { 120 | switch g.Type() { 121 | case "layer", "field": 122 | return true 123 | default: 124 | return false 125 | } 126 | } 127 | 128 | // GoType returns the Go type to use when declaring the GUID. 129 | // e.g. FWPM_LAYER_BLAH -> LayerID 130 | func (g guidName) GoType() string { 131 | if g.Exported() || g.Type() == "sublayer" { 132 | return strings.Title(g.Type()) + "ID" 133 | } 134 | return "windows.GUID" 135 | } 136 | 137 | // String returns the pretty string for the GUID. 138 | // e.g. "FWPM_LAYER_BLAH" -> "BLAH" 139 | // e.g. "FWPM_SUBLAYER_LIPS" -> "SUBLAYER_LIPS" 140 | func (g guidName) String() string { 141 | if g.Exported() { 142 | return strings.SplitN(string(g), "_", 3)[2] 143 | } 144 | return strings.SplitN(string(g), "_", 2)[1] 145 | } 146 | 147 | var keepUpper = map[string]bool{ 148 | "ALE": true, 149 | "DCOM": true, 150 | "EP": true, 151 | "ICMP": true, 152 | "ID": true, 153 | "IKE": true, 154 | "IP": true, 155 | "KM": true, 156 | "LIPS": true, 157 | "MAC": true, 158 | "NAP": true, 159 | "OUI": true, 160 | "QM": true, 161 | "RPC": true, 162 | "SNAP": true, 163 | "TCP": true, 164 | "UDP": true, 165 | "UM": true, 166 | "UUID": true, 167 | "VLAN": true, 168 | "WFP": true, 169 | } 170 | 171 | var replacements = map[string]string{ 172 | "AUTHIP": "AuthIP", 173 | "EPMAP": "EPMap", 174 | "IKEEXT": "IKEExt", 175 | "IKEV2": "IKEv2", 176 | "IPFORWARD": "IPForward", 177 | "IPPACKET": "IPPacket", 178 | "IPSEC": "IPSec", 179 | "VSWITCH": "VSwitch", 180 | } 181 | 182 | func (g guidName) VarName() string { 183 | fs := strings.Split(string(g), "_") 184 | if g.Exported() { 185 | fs[0] = "" 186 | } else { 187 | fs[0] = "guid" 188 | } 189 | fs[1] = g.Type() 190 | 191 | for i, f := range fs[1:] { 192 | if keepUpper[f] { 193 | continue 194 | } 195 | if rep, ok := replacements[f]; ok { 196 | fs[i+1] = rep 197 | } else { 198 | fs[i+1] = strings.Title(strings.ToLower(f)) 199 | } 200 | } 201 | 202 | return strings.Join(fs, "") 203 | } 204 | 205 | func readGUIDDef(r *bufio.Reader, l string) (name guidName, g1, g2, g3, g4 string, err error) { 206 | clean := func(s string) string { 207 | s = strings.TrimSpace(s) 208 | return strings.TrimSuffix(s, ",") 209 | } 210 | 211 | var n string 212 | if strings.HasPrefix(l, "DEFINE_GUID(FWPM_") { 213 | n = strings.Split(l, "(")[1] 214 | } else { 215 | n, err = r.ReadString('\n') 216 | if err != nil { 217 | return 218 | } 219 | } 220 | name = guidName(clean(n)) 221 | 222 | g1, err = r.ReadString('\n') 223 | if err != nil { 224 | return 225 | } 226 | g1 = clean(g1) 227 | 228 | g2, err = r.ReadString('\n') 229 | if err != nil { 230 | return 231 | } 232 | g2 = clean(g2) 233 | 234 | g3, err = r.ReadString('\n') 235 | if err != nil { 236 | return 237 | } 238 | g3 = clean(g3) 239 | 240 | g4, err = r.ReadString('\n') 241 | if err != nil { 242 | return 243 | } 244 | g4 = clean(g4) 245 | 246 | return 247 | } 248 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tailscale/wf 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/google/go-cmp v0.5.5 7 | github.com/peterbourgon/ff/v3 v3.0.0 8 | go4.org/netipx v0.0.0-20220725152314-7e7bdc8411bf 9 | golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 10 | honnef.co/go/tools v0.3.2 11 | ) 12 | 13 | require ( 14 | github.com/BurntSushi/toml v0.4.1 // indirect 15 | golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e // indirect 16 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect 17 | golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f // indirect 18 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 2 | github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= 3 | github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 6 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 7 | github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= 8 | github.com/peterbourgon/ff/v3 v3.0.0 h1:eQzEmNahuOjQXfuegsKQTSTDbf4dNvr/eNLrmJhiH7M= 9 | github.com/peterbourgon/ff/v3 v3.0.0/go.mod h1:UILIFjRH5a/ar8TjXYLTkIvSvekZqPm5Eb/qbGk6CT0= 10 | go4.org/intern v0.0.0-20211027215823-ae77deb06f29 h1:UXLjNohABv4S58tHmeuIZDO6e3mHpW2Dx33gaNt03LE= 11 | go4.org/netipx v0.0.0-20220725152314-7e7bdc8411bf h1:IdwJUzqoIo5lkr2EOyKoe5qipUaEjbOKKY5+fzPBZ3A= 12 | go4.org/netipx v0.0.0-20220725152314-7e7bdc8411bf/go.mod h1:+QXzaoURFd0rGDIjDNpyIkv+F9R7EmeKorvlKRnhqgA= 13 | go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 h1:FyBZqvoA/jbNzuAWLQE2kG820zMAkcilx6BMjGbL/E4= 14 | golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM= 15 | golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= 16 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= 17 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 18 | golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0= 19 | golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 20 | golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f h1:OKYpQQVE3DKSc3r3zHVzq46vq5YH7x8xpR3/k9ixmUg= 21 | golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= 22 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 23 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 24 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 25 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 26 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 27 | honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34= 28 | honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= 29 | -------------------------------------------------------------------------------- /malloc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package wf 6 | 7 | import ( 8 | "fmt" 9 | "unsafe" 10 | 11 | "golang.org/x/sys/windows" 12 | ) 13 | 14 | // arena is a bump allocation arena that returns memory from the non-Go heap. 15 | // It exists because calling into the WFP API requires allocating 16 | // structs on the C heap and knitting them into nested structs, and 17 | // tracking individual allocations and their matching frees dirties 18 | // the APIs. Instead, top-level API functions create an arena, and all 19 | // subordinate allocations come out of that managed-lifetime pool. 20 | type arena struct { 21 | slabs []uintptr 22 | next uintptr 23 | remaining uintptr 24 | } 25 | 26 | const slabSize = 4096 27 | 28 | // grow adds a new slab to the allocator and handles future calls to 29 | // alloc/calloc out of it. 30 | func (a *arena) grow() { 31 | slab, err := windows.LocalAlloc(windows.LPTR, slabSize) 32 | if err != nil { 33 | panic(fmt.Sprintf("memory allocation failed: %v", err)) 34 | } 35 | a.slabs = append(a.slabs, slab) 36 | a.next = slab 37 | a.remaining = slabSize 38 | } 39 | 40 | // Alloc returns an unsafe.Pointer to a zeroed range of length bytes. 41 | func (a *arena) Alloc(length uintptr) unsafe.Pointer { 42 | if length > slabSize { 43 | panic(fmt.Sprintf("can't allocate something that big (%d bytes)", length)) 44 | } 45 | if length == 0 { 46 | panic("can't allocate zero bytes") 47 | } 48 | if length > a.remaining { 49 | a.grow() 50 | } 51 | 52 | // Cast from *uintptr rather than plain uintptr to avoid the go 53 | // vet unsafe.Pointer safety check. This pattern is safe because 54 | // a.next never points into the Go heap. 55 | ret := *(**struct{})(unsafe.Pointer(&a.next)) 56 | a.next += length 57 | a.remaining -= length 58 | return unsafe.Pointer(ret) 59 | } 60 | 61 | // Dispose frees all the memory returned by prior Alloc calls. 62 | // The arena can continue to be used after a call to Dispose. 63 | func (a *arena) Dispose() { 64 | for _, slab := range a.slabs { 65 | if _, err := windows.LocalFree(windows.Handle(slab)); err != nil { 66 | panic(fmt.Sprintf("free failed: %v", err)) 67 | } 68 | } 69 | a.slabs = a.slabs[:0] 70 | a.next = 0 71 | a.remaining = 0 72 | } 73 | -------------------------------------------------------------------------------- /parse.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package wf 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "math/bits" 11 | "net" 12 | "net/netip" 13 | "reflect" 14 | "time" 15 | "unsafe" 16 | 17 | "go4.org/netipx" 18 | "golang.org/x/sys/windows" 19 | ) 20 | 21 | // This file contains parsing code for structures returned by the WFP 22 | // API. These are the structs defined in types.go, allocated out of 23 | // the C heap by WFP. The parsers in this file convert those raw 24 | // structs (which require unsafe pointers to traverse) into safe Go 25 | // types. 26 | 27 | var ( 28 | typeUint8 = reflect.TypeOf(uint8(0)) 29 | typeUint16 = reflect.TypeOf(uint16(0)) 30 | typeUint32 = reflect.TypeOf(uint32(0)) 31 | typeUint64 = reflect.TypeOf(uint64(0)) 32 | typeArray16 = reflect.TypeOf([16]byte{}) 33 | typeBytes = reflect.TypeOf([]byte(nil)) 34 | typeSID = reflect.TypeOf(&windows.SID{}) 35 | typeSecurityDescriptor = reflect.TypeOf(windows.SECURITY_DESCRIPTOR{}) 36 | typeTokenInformation = reflect.TypeOf(TokenInformation{}) 37 | typeMAC = reflect.TypeOf(net.HardwareAddr{}) 38 | typeBitmapIndex = reflect.TypeOf(uint8(0)) 39 | typeIP = reflect.TypeOf(netip.Addr{}) 40 | typePrefix = reflect.TypeOf(netip.Prefix{}) 41 | typeRange = reflect.TypeOf(Range{}) 42 | typeString = reflect.TypeOf("") 43 | ) 44 | 45 | // fieldTypeMap maps a layer field's dataType to a Go value of that 46 | // type. 47 | // NOTE: According to documentation, all fields which report TokenAccessInformation 48 | // are actually a SECURITY_DESCRIPTOR type. For some reason, WFP responds 49 | // with a TOKEN_ACCESS_INFORMATION type when enumerating fields. This forces the 50 | // security descriptor type here to align with documentation. 51 | // https://docs.microsoft.com/en-us/windows/win32/fwp/filtering-condition-identifiers- 52 | var fieldTypeMap = map[dataType]reflect.Type{ 53 | dataTypeUint8: typeUint8, 54 | dataTypeUint16: typeUint16, 55 | dataTypeUint32: typeUint32, 56 | dataTypeUint64: typeUint64, 57 | dataTypeByteArray16: typeArray16, 58 | dataTypeByteBlob: typeBytes, 59 | dataTypeSID: typeSID, 60 | dataTypeSecurityDescriptor: typeSecurityDescriptor, 61 | dataTypeTokenInformation: typeTokenInformation, 62 | dataTypeTokenAccessInformation: typeSecurityDescriptor, 63 | dataTypeArray6: typeMAC, 64 | dataTypeBitmapIndex: typeBitmapIndex, 65 | dataTypeV4AddrMask: typePrefix, 66 | dataTypeV6AddrMask: typePrefix, 67 | dataTypeRange: typeRange, 68 | } 69 | 70 | // fieldType returns the reflect.Type for a layer field, or an error 71 | // if the field has an unknown type. 72 | func fieldType(f *fwpmField0) (reflect.Type, error) { 73 | // IP addresses are represented as either a uint32 or a 16-byte 74 | // array, with a modifier flag indicating that it's an IP 75 | // address. Use plain IPs when exposing in Go. 76 | if f.Type == fwpmFieldTypeIPAddress { 77 | if f.DataType != dataTypeUint32 && f.DataType != dataTypeByteArray16 { 78 | return nil, fmt.Errorf("field has IP address type, but underlying datatype is %s (want Uint32 or ByteArray16)", f.DataType) 79 | } 80 | return typeIP, nil 81 | } 82 | // Flags are a uint32 with a modifier. This just checks that there 83 | // are no surprise flag fields of other types. 84 | if f.Type == fwpmFieldTypeFlags { 85 | if f.DataType != dataTypeUint32 { 86 | return nil, fmt.Errorf("field has flag type, but underlying datatype is %s (want Uint32)", f.DataType) 87 | } 88 | return typeUint32, nil 89 | } 90 | 91 | // FWPM_CONDITION_ALE_APP_ID is provided by WFP as a byte blob 92 | // (aka []byte), but those bytes are actually a null-terminated, 93 | // UTF-16 encoded string. Since WFP doesn't use its own "unicode 94 | // string" datatype for anything, we use Go strings as a special 95 | // case for thtat one field. 96 | if f.DataType == dataTypeByteBlob && *f.FieldKey == FieldALEAppID { 97 | return typeString, nil 98 | } 99 | 100 | // For everything else, there's a simple mapping. 101 | if t, ok := fieldTypeMap[f.DataType]; ok { 102 | return t, nil 103 | } 104 | 105 | return nil, fmt.Errorf("unknown data type %s", f.DataType) 106 | } 107 | 108 | // toLayers converts a C array of *fwpmLayer0 to a safe-to-use *Layer slice. 109 | func fromLayer0(array **fwpmLayer0, num uint32) ([]*Layer, error) { 110 | var ret []*Layer 111 | 112 | var layers []*fwpmLayer0 113 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&layers)) 114 | sh.Cap = int(num) 115 | sh.Len = int(num) 116 | sh.Data = uintptr(unsafe.Pointer(array)) 117 | 118 | for _, layer := range layers { 119 | l := &Layer{ 120 | ID: layer.LayerKey, 121 | Name: windows.UTF16PtrToString(layer.DisplayData.Name), 122 | Description: windows.UTF16PtrToString(layer.DisplayData.Description), 123 | DefaultSublayer: layer.DefaultSublayerKey, 124 | KernelID: layer.LayerID, 125 | } 126 | 127 | var fields []fwpmField0 128 | sh = (*reflect.SliceHeader)(unsafe.Pointer(&fields)) 129 | sh.Cap = int(layer.NumFields) 130 | sh.Len = int(layer.NumFields) 131 | sh.Data = uintptr(unsafe.Pointer(layer.Fields)) 132 | 133 | for i := range fields { 134 | field := &fields[i] 135 | typ, err := fieldType(field) 136 | if err != nil { 137 | return nil, fmt.Errorf("finding type of field %s: %w", *field.FieldKey, err) 138 | } 139 | l.Fields = append(l.Fields, &Field{ 140 | ID: *field.FieldKey, 141 | Type: typ, 142 | }) 143 | } 144 | 145 | ret = append(ret, l) 146 | } 147 | 148 | return ret, nil 149 | } 150 | 151 | // toSublayers converts a C array of *fwpmSublayer0 to a safe-to-use *Sublayer slice. 152 | func fromSublayer0(array **fwpmSublayer0, num uint32) []*Sublayer { 153 | var ret []*Sublayer 154 | 155 | var sublayers []*fwpmSublayer0 156 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&sublayers)) 157 | sh.Cap = int(num) 158 | sh.Len = int(num) 159 | sh.Data = uintptr(unsafe.Pointer(array)) 160 | 161 | for _, sublayer := range sublayers { 162 | s := &Sublayer{ 163 | ID: sublayer.SublayerKey, 164 | Name: windows.UTF16PtrToString(sublayer.DisplayData.Name), 165 | Description: windows.UTF16PtrToString(sublayer.DisplayData.Description), 166 | Persistent: (sublayer.Flags & fwpmSublayerFlagsPersistent) != 0, 167 | ProviderData: fromByteBlob(&sublayer.ProviderData), 168 | Weight: sublayer.Weight, 169 | } 170 | if sublayer.ProviderKey != nil { 171 | // Make a copy of the GUID, to ensure we're not aliasing C 172 | // memory. 173 | s.Provider = ProviderID(*sublayer.ProviderKey) 174 | } 175 | ret = append(ret, s) 176 | } 177 | 178 | return ret 179 | } 180 | 181 | // toProviders converts a C array of fwpmProvider0 to a safe-to-use Provider 182 | // slice. 183 | func fromProvider0(array **fwpmProvider0, num uint32) []*Provider { 184 | var ret []*Provider 185 | 186 | var providers []*fwpmProvider0 187 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&providers)) 188 | sh.Cap = int(num) 189 | sh.Len = int(num) 190 | sh.Data = uintptr(unsafe.Pointer(array)) 191 | 192 | for _, provider := range providers { 193 | p := &Provider{ 194 | ID: provider.ProviderKey, 195 | Name: windows.UTF16PtrToString(provider.DisplayData.Name), 196 | Description: windows.UTF16PtrToString(provider.DisplayData.Description), 197 | Persistent: (provider.Flags & fwpmProviderFlagsPersistent) != 0, 198 | Disabled: (provider.Flags & fwpmProviderFlagsDisabled) != 0, 199 | Data: fromByteBlob(&provider.ProviderData), 200 | ServiceName: windows.UTF16PtrToString(provider.ServiceName), 201 | } 202 | ret = append(ret, p) 203 | } 204 | 205 | return ret 206 | } 207 | 208 | // fromNetEvent1 converts a C array of fwpmNetEvent1 to a safe-to-use 209 | // DropEvent slice. 210 | func fromNetEvent1(array **fwpmNetEvent1, num uint32) ([]*DropEvent, error) { 211 | var ret []*DropEvent 212 | 213 | var events []*fwpmNetEvent1 214 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&events)) 215 | sh.Cap = int(num) 216 | sh.Len = int(num) 217 | sh.Data = uintptr(unsafe.Pointer(array)) 218 | 219 | for _, event := range events { 220 | if event.Type != fwpmNetEventClassifyDrop { 221 | continue 222 | } 223 | 224 | e := &DropEvent{ 225 | Timestamp: time.Unix(0, event.Header.Timestamp.Nanoseconds()), 226 | IPProtocol: event.Header.IPProtocol, 227 | LocalAddr: netip.AddrPortFrom(netip.Addr{}, event.Header.LocalPort), 228 | RemoteAddr: netip.AddrPortFrom(netip.Addr{}, event.Header.RemotePort), 229 | LayerID: event.Drop.LayerID, 230 | FilterID: event.Drop.FilterID, 231 | } 232 | switch event.Header.IPVersion { 233 | case fwpIPVersion4: 234 | localIP := ipv4From32(*(*uint32)(unsafe.Pointer(&event.Header.LocalAddr[0]))) 235 | e.LocalAddr = netip.AddrPortFrom(localIP, e.LocalAddr.Port()) 236 | remoteIP := ipv4From32(*(*uint32)(unsafe.Pointer(&event.Header.RemoteAddr[0]))) 237 | e.RemoteAddr = netip.AddrPortFrom(remoteIP, e.RemoteAddr.Port()) 238 | case fwpIPVersion6: 239 | localIP := netip.AddrFrom16(event.Header.LocalAddr).Unmap() 240 | e.LocalAddr = netip.AddrPortFrom(localIP, e.LocalAddr.Port()) 241 | remoteIP := netip.AddrFrom16(event.Header.RemoteAddr).Unmap() 242 | e.RemoteAddr = netip.AddrPortFrom(remoteIP, e.RemoteAddr.Port()) 243 | } 244 | appID, err := fromByteBlobToString(&event.Header.AppID) 245 | if err != nil { 246 | return nil, err 247 | } 248 | e.AppID = appID 249 | ret = append(ret, e) 250 | } 251 | 252 | return ret, nil 253 | } 254 | 255 | func fromFilter0(array **fwpmFilter0, num uint32, layerTypes layerTypes) ([]*Rule, error) { 256 | var rules []*fwpmFilter0 257 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&rules)) 258 | sh.Cap = int(num) 259 | sh.Len = int(num) 260 | sh.Data = uintptr(unsafe.Pointer(array)) 261 | 262 | var ret []*Rule 263 | 264 | for _, rule := range rules { 265 | r := &Rule{ 266 | ID: rule.FilterKey, 267 | KernelID: rule.FilterID, 268 | Name: windows.UTF16PtrToString(rule.DisplayData.Name), 269 | Description: windows.UTF16PtrToString(rule.DisplayData.Description), 270 | Layer: rule.LayerKey, 271 | Sublayer: rule.SublayerKey, 272 | Action: rule.Action.Type, 273 | Persistent: (rule.Flags & fwpmFilterFlagsPersistent) != 0, 274 | BootTime: (rule.Flags & fwpmFilterFlagsBootTime) != 0, 275 | ProviderData: fromByteBlob(&rule.ProviderData), 276 | Disabled: (rule.Flags & fwpmFilterFlagsDisabled) != 0, 277 | } 278 | if rule.ProviderKey != nil { 279 | r.Provider = ProviderID(*rule.ProviderKey) 280 | } 281 | if rule.EffectiveWeight.Type == dataTypeUint64 { 282 | r.Weight = **(**uint64)(unsafe.Pointer(&rule.EffectiveWeight.Value)) 283 | } 284 | if r.Action == ActionCalloutTerminating || r.Action == ActionCalloutInspection || r.Action == ActionCalloutUnknown { 285 | r.Callout = rule.Action.GUID 286 | } 287 | if r.Action == ActionCalloutTerminating || r.Action == ActionCalloutUnknown { 288 | r.PermitIfMissing = (rule.Flags & fwpmFilterFlagsPermitIfCalloutUnregistered) != 0 289 | } 290 | r.HardAction = (rule.Flags & fwpmFilterFlagsClearActionRight) != 0 291 | 292 | ft := layerTypes[r.Layer] 293 | if ft == nil { 294 | return nil, fmt.Errorf("unknown layer %s", r.Layer) 295 | } 296 | 297 | ms, err := fromCondition0(rule.FilterConditions, rule.NumFilterConditions, ft) 298 | if err != nil { 299 | return nil, err 300 | } 301 | 302 | r.Conditions = ms 303 | 304 | ret = append(ret, r) 305 | } 306 | 307 | return ret, nil 308 | } 309 | 310 | func fromCondition0(condArray *fwpmFilterCondition0, num uint32, fieldTypes fieldTypes) ([]*Match, error) { 311 | var conditions []fwpmFilterCondition0 312 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&conditions)) 313 | sh.Cap = int(num) 314 | sh.Len = int(num) 315 | sh.Data = uintptr(unsafe.Pointer(condArray)) 316 | 317 | var ret []*Match 318 | 319 | for i := range conditions { 320 | cond := &conditions[i] 321 | fieldType, ok := fieldTypes[cond.FieldKey] 322 | if !ok { 323 | return nil, fmt.Errorf("unknown field %s", cond.FieldKey) 324 | } 325 | 326 | v, err := fromValue0((*fwpValue0)(unsafe.Pointer(&cond.Value)), fieldType) 327 | if err != nil { 328 | return nil, fmt.Errorf("getting value for match [%s %s]: %w", cond.FieldKey, cond.MatchType, err) 329 | } 330 | m := &Match{ 331 | Field: cond.FieldKey, 332 | Op: cond.MatchType, 333 | Value: v, 334 | } 335 | 336 | ret = append(ret, m) 337 | } 338 | 339 | return ret, nil 340 | } 341 | 342 | // fromValue converts a fwpValue0 to the corresponding Go value. 343 | func fromValue0(v *fwpValue0, ftype reflect.Type) (interface{}, error) { 344 | switch v.Type { 345 | case dataTypeUint8: 346 | return *(*uint8)(unsafe.Pointer(&v.Value)), nil 347 | case dataTypeUint16: 348 | return *(*uint16)(unsafe.Pointer(&v.Value)), nil 349 | case dataTypeUint32: 350 | u := *(*uint32)(unsafe.Pointer(&v.Value)) 351 | if ftype == typeIP { 352 | return ipv4From32(u), nil 353 | } 354 | return u, nil 355 | case dataTypeUint64: 356 | return **(**uint64)(unsafe.Pointer(&v.Value)), nil 357 | case dataTypeByteArray16: 358 | var ret [16]byte 359 | copy(ret[:], fromBytes(v.Value, 16)) 360 | if ftype == typeIP { 361 | return netip.AddrFrom16(ret).Unmap(), nil 362 | } 363 | return ret, nil 364 | case dataTypeByteBlob: 365 | if ftype == typeString { 366 | return fromByteBlobToString(*(**fwpByteBlob)(unsafe.Pointer(&v.Value))) 367 | } else { 368 | return fromByteBlob(*(**fwpByteBlob)(unsafe.Pointer(&v.Value))), nil 369 | } 370 | case dataTypeSID: 371 | return parseSID(&v.Value) 372 | case dataTypeSecurityDescriptor: 373 | return parseSecurityDescriptor(&v.Value) 374 | case dataTypeArray6: 375 | ret := make(net.HardwareAddr, 6) 376 | copy(ret[:], fromBytes(v.Value, 6)) 377 | return ret, nil 378 | case dataTypeV4AddrMask: 379 | return parseV4AddrAndMask(&v.Value), nil 380 | case dataTypeV6AddrMask: 381 | return parseV6AddrAndMask(&v.Value), nil 382 | case dataTypeRange: 383 | return parseRange0(&v.Value, ftype) 384 | } 385 | // Deliberately omitted: TokenInformation, TokenAccessInformation 386 | // and BitmapIndex seem to only be used as field types, but match 387 | // against other types only. 388 | 389 | return nil, fmt.Errorf("don't know how to map API type %s into Go", v.Type) 390 | } 391 | 392 | func parseV4AddrAndMask(v *uintptr) netip.Prefix { 393 | v4 := *(**fwpV4AddrAndMask)(unsafe.Pointer(v)) 394 | ip := netip.AddrFrom4([4]byte{uint8(v4.Addr >> 24), uint8(v4.Addr >> 16), uint8(v4.Addr >> 8), uint8(v4.Addr)}) 395 | bits := 32 - bits.TrailingZeros32(v4.Mask) 396 | return netip.PrefixFrom(ip, bits) 397 | } 398 | 399 | func parseV6AddrAndMask(v *uintptr) netip.Prefix { 400 | v6 := *(**fwpV6AddrAndMask)(unsafe.Pointer(v)) 401 | return netip.PrefixFrom(netip.AddrFrom16(v6.Addr).Unmap(), int(v6.PrefixLength)) 402 | } 403 | 404 | func parseSID(v *uintptr) (*windows.SID, error) { 405 | // TODO: export IsValidSid in x/sys/windows so we can vaguely 406 | // verify this pointer. 407 | sid := *(**windows.SID)(unsafe.Pointer(v)) 408 | // Copy the SID into Go memory. 409 | dsid, err := sid.Copy() 410 | if err != nil { 411 | return nil, err 412 | } 413 | return dsid, nil 414 | } 415 | 416 | func parseSecurityDescriptor(v *uintptr) (*windows.SECURITY_DESCRIPTOR, error) { 417 | // The security descriptor is embedded in the API response as 418 | // a byte slice. 419 | bb := fromByteBlob(*(**fwpByteBlob)(unsafe.Pointer(v))) 420 | relSD := (*windows.SECURITY_DESCRIPTOR)(unsafe.Pointer(&bb[0])) 421 | return relSD, nil 422 | } 423 | 424 | func parseRange0(v *uintptr, ftype reflect.Type) (interface{}, error) { 425 | r := *(**fwpRange0)(unsafe.Pointer(v)) 426 | from, err := fromValue0(&r.From, ftype) 427 | if err != nil { 428 | return nil, err 429 | } 430 | to, err := fromValue0(&r.To, ftype) 431 | if err != nil { 432 | return nil, err 433 | } 434 | if reflect.TypeOf(from) != reflect.TypeOf(to) { 435 | return nil, fmt.Errorf("range.From and range.To types don't match: %s / %s", reflect.TypeOf(from), reflect.TypeOf(to)) 436 | } 437 | if reflect.TypeOf(from) == typeIP { 438 | return netipx.IPRangeFrom(from.(netip.Addr), to.(netip.Addr)), nil 439 | } 440 | return Range{from, to}, nil 441 | } 442 | 443 | func ipv4From32(v uint32) netip.Addr { 444 | return netip.AddrFrom4([4]byte{uint8(v >> 24), uint8(v >> 16), uint8(v >> 8), uint8(v)}) 445 | } 446 | 447 | func fromBytes(bb uintptr, length int) []byte { 448 | var bs []byte 449 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&bs)) 450 | sh.Cap = length 451 | sh.Len = length 452 | sh.Data = bb 453 | return append([]byte(nil), bs...) 454 | } 455 | 456 | // fromByteBlob extracts the bytes from bb and returns them as a 457 | // []byte that doesn't alias C memory. 458 | func fromByteBlob(bb *fwpByteBlob) []byte { 459 | if bb == nil || bb.Size == 0 { 460 | return nil 461 | } 462 | 463 | var blob []byte 464 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&blob)) 465 | sh.Cap = int(bb.Size) 466 | sh.Len = sh.Cap 467 | sh.Data = uintptr(unsafe.Pointer(bb.Data)) 468 | 469 | return append([]byte(nil), blob...) 470 | } 471 | 472 | func fromByteBlobToString(bb *fwpByteBlob) (string, error) { 473 | if bb == nil || bb.Size == 0 { 474 | return "", nil 475 | } 476 | if bb.Size%2 != 0 { 477 | return "", errors.New("byte blob should be string, but has odd number of bytes") 478 | } 479 | 480 | var blob []uint16 481 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&blob)) 482 | sh.Cap = int(bb.Size) / 2 483 | sh.Len = sh.Cap 484 | sh.Data = uintptr(unsafe.Pointer(bb.Data)) 485 | 486 | return windows.UTF16ToString(blob), nil 487 | } 488 | -------------------------------------------------------------------------------- /syscall.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package wf 6 | 7 | //sys fwpmEngineOpen0(mustBeNil *uint16, authnService authnService, authIdentity *uintptr, session *fwpmSession0, engineHandle *windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmEngineOpen0 8 | //sys fwpmEngineClose0(engineHandle windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmEngineClose0 9 | 10 | //sys fwpmLayerCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *fwpmLayerEnumTemplate0, handle *windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmLayerCreateEnumHandle0 11 | //sys fwpmLayerDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmLayerDestroyEnumHandle0 12 | //sys fwpmLayerEnum0(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmLayer0, numEntriesReturned *uint32) (ret error) [failretval!=0] = fwpuclnt.FwpmLayerEnum0 13 | 14 | //sys fwpmSubLayerCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *fwpmSublayerEnumTemplate0, handle *windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmSubLayerCreateEnumHandle0 15 | //sys fwpmSubLayerDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmSubLayerDestroyEnumHandle0 16 | //sys fwpmSubLayerEnum0(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmSublayer0, numEntriesReturned *uint32) (ret error) [failretval!=0] = fwpuclnt.FwpmSubLayerEnum0 17 | //sys fwpmSubLayerAdd0(engineHandle windows.Handle, sublayer *fwpmSublayer0, nilForNow *uintptr) (ret error) [failretval!=0] = fwpuclnt.FwpmSubLayerAdd0 18 | //sys fwpmSubLayerDeleteByKey0(engineHandle windows.Handle, guid *SublayerID) (ret error) [failretval!=0] = fwpuclnt.FwpmSubLayerDeleteByKey0 19 | 20 | //sys fwpmProviderCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *struct{}, handle *windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmProviderCreateEnumHandle0 21 | //sys fwpmProviderDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmProviderDestroyEnumHandle0 22 | //sys fwpmProviderEnum0(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmProvider0, numEntriesReturned *uint32) (ret error) [failretval!=0] = fwpuclnt.FwpmProviderEnum0 23 | //sys fwpmProviderAdd0(engineHandle windows.Handle, provider *fwpmProvider0, nilForNow *uintptr) (ret error) [failretval!=0] = fwpuclnt.FwpmProviderAdd0 24 | //sys fwpmProviderDeleteByKey0(engineHandle windows.Handle, guid *ProviderID) (ret error) [failretval!=0] = fwpuclnt.FwpmProviderDeleteByKey0 25 | 26 | //sys fwpmFilterCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *fwpmFilterEnumTemplate0, handle *windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmFilterCreateEnumHandle0 27 | //sys fwpmFilterDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmFilterDestroyEnumHandle0 28 | //sys fwpmFilterEnum0(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmFilter0, numEntriesReturned *uint32) (ret error) [failretval!=0] = fwpuclnt.FwpmFilterEnum0 29 | //sys fwpmFilterAdd0(engineHandle windows.Handle, rule *fwpmFilter0, sd *windows.SECURITY_DESCRIPTOR, id *uint64) (ret error) [failretval!=0] = fwpuclnt.FwpmFilterAdd0 30 | //sys fwpmFilterDeleteByKey0(engineHandle windows.Handle, guid *RuleID) (ret error) [failretval!=0] = fwpuclnt.FwpmFilterDeleteByKey0 31 | 32 | //sys fwpmNetEventCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *struct{}, handle *windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmNetEventCreateEnumHandle0 33 | //sys fwpmNetEventDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmNetEventDestroyEnumHandle0 34 | //sys fwpmNetEventEnum1(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmNetEvent1, numEntriesReturned *uint32) (ret error) [failretval!=0] = fwpuclnt.FwpmNetEventEnum1 35 | 36 | //sys fwpmTransactionBegin0(engineHandle windows.Handle, flags uint32) (ret error) [failretval!=0] = fwpuclnt.FwpmTransactionBegin0 37 | //sys fwpmTransactionCommit0(engineHandle windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmTransactionCommit0 38 | //sys fwpmTransactionAbort0(engineHandle windows.Handle) (ret error) [failretval!=0] = fwpuclnt.FwpmTransactionAbort0 39 | 40 | //sys fwpmFreeMemory0(p *struct{}) = fwpuclnt.FwpmFreeMemory0 41 | //sys fwpmGetAppIdFromFileName0(path *byte, appId **fwpByteBlob) (ret error) [failretval!=0] = fwpuclnt.FwpmGetAppIdFromFileName0 42 | -------------------------------------------------------------------------------- /tooldeps.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build tool_deps_for_go_mod_tidy 6 | // +build tool_deps_for_go_mod_tidy 7 | 8 | package wf 9 | 10 | import ( 11 | _ "honnef.co/go/tools/cmd/staticcheck" 12 | ) 13 | -------------------------------------------------------------------------------- /types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 The Inet.Af AUTHORS. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package wf 6 | 7 | import ( 8 | "golang.org/x/sys/windows" 9 | ) 10 | 11 | //go:notinheap 12 | type fwpmDisplayData0 struct { 13 | Name *uint16 14 | Description *uint16 15 | } 16 | 17 | type fwpmSession0Flags uint32 18 | 19 | const fwpmSession0FlagDynamic = 1 20 | 21 | //go:notinheap 22 | type fwpmSession0 struct { 23 | SessionKey windows.GUID 24 | DisplayData fwpmDisplayData0 25 | Flags fwpmSession0Flags 26 | TxnWaitTimeoutMillis uint32 27 | ProcessID uint32 28 | SID *windows.SID 29 | Username *uint16 30 | KernelMode uint8 31 | } 32 | 33 | type authnService uint32 34 | 35 | const ( 36 | authnServiceWinNT authnService = 0xa 37 | authnServiceDefault authnService = 0xffffffff 38 | ) 39 | 40 | //go:notinheap 41 | type fwpmLayerEnumTemplate0 struct { 42 | reserved uint64 43 | } 44 | 45 | //go:notinheap 46 | type fwpmLayer0 struct { 47 | LayerKey LayerID 48 | DisplayData fwpmDisplayData0 49 | Flags uint32 50 | NumFields uint32 51 | Fields *fwpmField0 52 | DefaultSublayerKey SublayerID 53 | LayerID uint16 54 | } 55 | 56 | type fwpmFieldType uint32 57 | 58 | const ( 59 | fwpmFieldTypeRawData fwpmFieldType = iota // no special semantics 60 | fwpmFieldTypeIPAddress // data is an IP address 61 | fwpmFieldTypeFlags // data is a flag bitfield 62 | ) 63 | 64 | type dataType uint32 65 | 66 | const ( 67 | dataTypeEmpty dataType = 0 68 | dataTypeUint8 dataType = 1 69 | dataTypeUint16 dataType = 2 70 | dataTypeUint32 dataType = 3 71 | dataTypeUint64 dataType = 4 72 | dataTypeByteArray16 dataType = 11 73 | dataTypeByteBlob dataType = 12 74 | dataTypeSID dataType = 13 75 | dataTypeSecurityDescriptor dataType = 14 76 | dataTypeTokenInformation dataType = 15 77 | dataTypeTokenAccessInformation dataType = 16 78 | dataTypeArray6 dataType = 18 79 | dataTypeBitmapIndex dataType = 19 80 | dataTypeV4AddrMask dataType = 256 81 | dataTypeV6AddrMask dataType = 257 82 | dataTypeRange dataType = 258 83 | ) 84 | 85 | // Types not implemented, because WFP doesn't seem to use them. 86 | // dataTypeInt8 dataType = 5 87 | // dataTypeInt16 dataType = 6 88 | // dataTypeInt32 dataType = 7 89 | // dataTypeInt64 dataType = 8 90 | // dataTypeFloat dataType = 9 91 | // dataTypeDouble dataType = 10 92 | // dataTypeUnicodeString dataType = 17 93 | // dataTypeBitmapArray64 dataType = 20 94 | 95 | //go:notinheap 96 | type fwpmField0 struct { 97 | FieldKey *FieldID 98 | Type fwpmFieldType 99 | DataType dataType 100 | } 101 | 102 | //go:notinheap 103 | type fwpmSublayerEnumTemplate0 struct { 104 | ProviderKey *windows.GUID 105 | } 106 | 107 | //go:notinheap 108 | type fwpByteBlob struct { 109 | Size uint32 110 | Data *uint8 111 | } 112 | 113 | type fwpmSublayerFlags uint32 114 | 115 | const fwpmSublayerFlagsPersistent fwpmSublayerFlags = 1 116 | 117 | //go:notinheap 118 | type fwpmSublayer0 struct { 119 | SublayerKey SublayerID 120 | DisplayData fwpmDisplayData0 121 | Flags fwpmSublayerFlags 122 | ProviderKey *windows.GUID 123 | ProviderData fwpByteBlob 124 | Weight uint16 125 | } 126 | 127 | type fwpmProviderFlags uint32 128 | 129 | const ( 130 | fwpmProviderFlagsPersistent fwpmProviderFlags = 0x01 131 | fwpmProviderFlagsDisabled fwpmProviderFlags = 0x10 132 | ) 133 | 134 | //go:notinheap 135 | type fwpmProvider0 struct { 136 | ProviderKey ProviderID 137 | DisplayData fwpmDisplayData0 138 | Flags fwpmProviderFlags 139 | ProviderData fwpByteBlob 140 | ServiceName *uint16 141 | } 142 | 143 | //go:notinheap 144 | type fwpValue0 struct { 145 | Type dataType 146 | Value uintptr // unioned value 147 | } 148 | 149 | type fwpmFilterFlags uint32 150 | 151 | const ( 152 | fwpmFilterFlagsPersistent fwpmFilterFlags = 1 << iota 153 | fwpmFilterFlagsBootTime 154 | fwpmFilterFlagsHasProviderContext 155 | fwpmFilterFlagsClearActionRight 156 | fwpmFilterFlagsPermitIfCalloutUnregistered 157 | fwpmFilterFlagsDisabled 158 | fwpmFilterFlagsIndexed 159 | ) 160 | 161 | //go:notinheap 162 | type fwpmAction0 struct { 163 | Type Action 164 | GUID CalloutID 165 | } 166 | 167 | // fwpmFilter0 is the Go representation of FWPM_FILTER0, 168 | // which stores the state associated with a filter. 169 | // See https://docs.microsoft.com/en-us/windows/win32/api/fwpmtypes/ns-fwpmtypes-fwpm_filter0 170 | //go:notinheap 171 | type fwpmFilter0 struct { 172 | FilterKey RuleID 173 | DisplayData fwpmDisplayData0 174 | Flags fwpmFilterFlags 175 | ProviderKey *windows.GUID 176 | ProviderData fwpByteBlob 177 | LayerKey LayerID 178 | SublayerKey SublayerID 179 | Weight fwpValue0 180 | NumFilterConditions uint32 181 | FilterConditions *fwpmFilterCondition0 182 | Action fwpmAction0 183 | 184 | // Only one of RawContext/ProviderContextKey must be set. 185 | RawContext uint64 186 | ProviderContextKey windows.GUID 187 | 188 | Reserved *windows.GUID 189 | FilterID uint64 190 | EffectiveWeight fwpValue0 191 | } 192 | 193 | //go:notinheap 194 | type fwpConditionValue0 struct { 195 | Type dataType 196 | Value uintptr 197 | } 198 | 199 | //go:notinheap 200 | type fwpmFilterCondition0 struct { 201 | FieldKey FieldID 202 | MatchType MatchType 203 | Value fwpConditionValue0 204 | } 205 | 206 | //go:notinheap 207 | type fwpV4AddrAndMask struct { 208 | Addr, Mask uint32 209 | } 210 | 211 | //go:notinheap 212 | type fwpV6AddrAndMask struct { 213 | Addr [16]byte 214 | PrefixLength uint8 215 | } 216 | 217 | //go:notinheap 218 | type fwpmProviderContextEnumTemplate0 struct { 219 | ProviderKey *ProviderID 220 | ProviderContextType uint32 221 | } 222 | 223 | //go:notinheap 224 | type fwpmFilterEnumTemplate0 struct { 225 | ProviderKey *ProviderID 226 | LayerKey windows.GUID 227 | EnumType filterEnumType 228 | Flags filterEnumFlags 229 | ProviderContextTemplate *fwpmProviderContextEnumTemplate0 // TODO: wtf? 230 | NumConditions uint32 231 | Conditions *fwpmFilterCondition0 232 | ActionMask uint32 233 | CalloutKey *windows.GUID 234 | } 235 | 236 | //go:notinheap 237 | type fwpRange0 struct { 238 | From, To fwpValue0 239 | } 240 | 241 | type filterEnumType uint32 242 | 243 | const ( 244 | filterEnumTypeFullyContained filterEnumType = iota 245 | filterEnumTypeOverlapping 246 | ) 247 | 248 | type filterEnumFlags uint32 249 | 250 | const ( 251 | filterEnumFlagsBestTerminatingMatch filterEnumFlags = iota + 1 252 | filterEnumFlagsSorted 253 | filterEnumFlagsBootTimeOnly 254 | filterEnumFlagsIncludeBootTime 255 | filterEnumFlagsIncludeDisabled 256 | ) 257 | 258 | type fwpIPVersion uint32 259 | 260 | const ( 261 | fwpIPVersion4 fwpIPVersion = 0 262 | fwpIPVersion6 fwpIPVersion = 1 263 | ) 264 | 265 | //go:notinheap 266 | type fwpmNetEventHeader1 struct { 267 | Timestamp windows.Filetime 268 | Flags uint32 // enum 269 | IPVersion fwpIPVersion // enum 270 | IPProtocol uint8 271 | _ [3]byte 272 | LocalAddr [16]byte 273 | RemoteAddr [16]byte 274 | LocalPort uint16 275 | RemotePort uint16 276 | ScopeID uint32 277 | AppID fwpByteBlob 278 | UserID *windows.SID 279 | 280 | // Random reserved fields for an aborted attempt at including 281 | // Ethernet frame information. Not used, but we have to pad out 282 | // the struct appropriately. 283 | _ struct { 284 | reserved1 uint32 285 | unused2 struct { 286 | reserved2 [6]byte 287 | reserved3 [6]byte 288 | reserved4 uint32 289 | reserved5 uint32 290 | reserved6 uint16 291 | reserved7 uint32 292 | reserved8 uint32 293 | reserved9 uint16 294 | reserved10 uint64 295 | } 296 | } 297 | } 298 | 299 | //go:notinheap 300 | type fwpmNetEventClassifyDrop1 struct { 301 | FilterID uint64 302 | LayerID uint16 303 | ReauthReason uint32 304 | OriginalProfile uint32 305 | CurrentProfile uint32 306 | Direction uint32 307 | Loopback uint32 308 | } 309 | 310 | type fwpmNetEventType uint32 311 | 312 | const fwpmNetEventClassifyDrop = 3 313 | 314 | //go:notinheap 315 | type fwpmNetEvent1 struct { 316 | Header fwpmNetEventHeader1 317 | Type fwpmNetEventType 318 | Drop *fwpmNetEventClassifyDrop1 319 | } 320 | -------------------------------------------------------------------------------- /zaction_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zaction_strings.go -type=Action -trimprefix=Action"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[ActionBlock-4097] 12 | _ = x[ActionPermit-4098] 13 | _ = x[ActionCalloutTerminating-20483] 14 | _ = x[ActionCalloutInspection-24580] 15 | _ = x[ActionCalloutUnknown-16389] 16 | } 17 | 18 | const ( 19 | _Action_name_0 = "BlockPermit" 20 | _Action_name_1 = "CalloutUnknown" 21 | _Action_name_2 = "CalloutTerminating" 22 | _Action_name_3 = "CalloutInspection" 23 | ) 24 | 25 | var ( 26 | _Action_index_0 = [...]uint8{0, 5, 11} 27 | ) 28 | 29 | func (i Action) String() string { 30 | switch { 31 | case 4097 <= i && i <= 4098: 32 | i -= 4097 33 | return _Action_name_0[_Action_index_0[i]:_Action_index_0[i+1]] 34 | case i == 16389: 35 | return _Action_name_1 36 | case i == 20483: 37 | return _Action_name_2 38 | case i == 24580: 39 | return _Action_name_3 40 | default: 41 | return "Action(" + strconv.FormatInt(int64(i), 10) + ")" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /zconditionflag_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zconditionflag_strings.go -type=ConditionFlag -trimprefix=ConditionFlag"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[ConditionFlagIsLoopback-1] 12 | _ = x[ConditionFlagIsIPSecSecured-2] 13 | _ = x[ConditionFlagIsReauthorize-4] 14 | _ = x[ConditionFlagIsWildcardBind-8] 15 | _ = x[ConditionFlagIsRawEndpoint-16] 16 | _ = x[ConditionFlagIsFragmant-32] 17 | _ = x[ConditionFlagIsFragmantGroup-64] 18 | _ = x[ConditionFlagIsIPSecNATTReclassify-128] 19 | _ = x[ConditionFlagIsRequiresALEClassify-256] 20 | _ = x[ConditionFlagIsImplicitBind-512] 21 | _ = x[ConditionFlagIsReassembled-1024] 22 | _ = x[ConditionFlagIsNameAppSpecified-16384] 23 | _ = x[ConditionFlagIsPromiscuous-32768] 24 | _ = x[ConditionFlagIsAuthFW-65536] 25 | _ = x[ConditionFlagIsReclassify-131072] 26 | _ = x[ConditionFlagIsOutboundPassThru-262144] 27 | _ = x[ConditionFlagIsInboundPassThru-524288] 28 | _ = x[ConditionFlagIsConnectionRedirected-1048576] 29 | } 30 | 31 | const _ConditionFlag_name = "IsLoopbackIsIPSecSecuredIsReauthorizeIsWildcardBindIsRawEndpointIsFragmantIsFragmantGroupIsIPSecNATTReclassifyIsRequiresALEClassifyIsImplicitBindIsReassembledIsNameAppSpecifiedIsPromiscuousIsAuthFWIsReclassifyIsOutboundPassThruIsInboundPassThruIsConnectionRedirected" 32 | 33 | var _ConditionFlag_map = map[ConditionFlag]string{ 34 | 1: _ConditionFlag_name[0:10], 35 | 2: _ConditionFlag_name[10:24], 36 | 4: _ConditionFlag_name[24:37], 37 | 8: _ConditionFlag_name[37:51], 38 | 16: _ConditionFlag_name[51:64], 39 | 32: _ConditionFlag_name[64:74], 40 | 64: _ConditionFlag_name[74:89], 41 | 128: _ConditionFlag_name[89:110], 42 | 256: _ConditionFlag_name[110:131], 43 | 512: _ConditionFlag_name[131:145], 44 | 1024: _ConditionFlag_name[145:158], 45 | 16384: _ConditionFlag_name[158:176], 46 | 32768: _ConditionFlag_name[176:189], 47 | 65536: _ConditionFlag_name[189:197], 48 | 131072: _ConditionFlag_name[197:209], 49 | 262144: _ConditionFlag_name[209:227], 50 | 524288: _ConditionFlag_name[227:244], 51 | 1048576: _ConditionFlag_name[244:266], 52 | } 53 | 54 | func (i ConditionFlag) String() string { 55 | if str, ok := _ConditionFlag_map[i]; ok { 56 | return str 57 | } 58 | return "ConditionFlag(" + strconv.FormatInt(int64(i), 10) + ")" 59 | } 60 | -------------------------------------------------------------------------------- /zdatatype_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zdatatype_strings.go -type=dataType -trimprefix=dataType"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[dataTypeEmpty-0] 12 | _ = x[dataTypeUint8-1] 13 | _ = x[dataTypeUint16-2] 14 | _ = x[dataTypeUint32-3] 15 | _ = x[dataTypeUint64-4] 16 | _ = x[dataTypeByteArray16-11] 17 | _ = x[dataTypeByteBlob-12] 18 | _ = x[dataTypeSID-13] 19 | _ = x[dataTypeSecurityDescriptor-14] 20 | _ = x[dataTypeTokenInformation-15] 21 | _ = x[dataTypeTokenAccessInformation-16] 22 | _ = x[dataTypeArray6-18] 23 | _ = x[dataTypeBitmapIndex-19] 24 | _ = x[dataTypeV4AddrMask-256] 25 | _ = x[dataTypeV6AddrMask-257] 26 | _ = x[dataTypeRange-258] 27 | } 28 | 29 | const ( 30 | _dataType_name_0 = "EmptyUint8Uint16Uint32Uint64" 31 | _dataType_name_1 = "ByteArray16ByteBlobSIDSecurityDescriptorTokenInformationTokenAccessInformation" 32 | _dataType_name_2 = "Array6BitmapIndex" 33 | _dataType_name_3 = "V4AddrMaskV6AddrMaskRange" 34 | ) 35 | 36 | var ( 37 | _dataType_index_0 = [...]uint8{0, 5, 10, 16, 22, 28} 38 | _dataType_index_1 = [...]uint8{0, 11, 19, 22, 40, 56, 78} 39 | _dataType_index_2 = [...]uint8{0, 6, 17} 40 | _dataType_index_3 = [...]uint8{0, 10, 20, 25} 41 | ) 42 | 43 | func (i dataType) String() string { 44 | switch { 45 | case i <= 4: 46 | return _dataType_name_0[_dataType_index_0[i]:_dataType_index_0[i+1]] 47 | case 11 <= i && i <= 16: 48 | i -= 11 49 | return _dataType_name_1[_dataType_index_1[i]:_dataType_index_1[i+1]] 50 | case 18 <= i && i <= 19: 51 | i -= 18 52 | return _dataType_name_2[_dataType_index_2[i]:_dataType_index_2[i+1]] 53 | case 256 <= i && i <= 258: 54 | i -= 256 55 | return _dataType_name_3[_dataType_index_3[i]:_dataType_index_3[i+1]] 56 | default: 57 | return "dataType(" + strconv.FormatInt(int64(i), 10) + ")" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /zfieldtype_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zfieldtype_strings.go -type=fwpmFieldType -trimprefix=fwpmFieldtype"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[fwpmFieldTypeRawData-0] 12 | _ = x[fwpmFieldTypeIPAddress-1] 13 | _ = x[fwpmFieldTypeFlags-2] 14 | } 15 | 16 | const _fwpmFieldType_name = "fwpmFieldTypeRawDatafwpmFieldTypeIPAddressfwpmFieldTypeFlags" 17 | 18 | var _fwpmFieldType_index = [...]uint8{0, 20, 42, 60} 19 | 20 | func (i fwpmFieldType) String() string { 21 | if i >= fwpmFieldType(len(_fwpmFieldType_index)-1) { 22 | return "fwpmFieldType(" + strconv.FormatInt(int64(i), 10) + ")" 23 | } 24 | return _fwpmFieldType_name[_fwpmFieldType_index[i]:_fwpmFieldType_index[i+1]] 25 | } 26 | -------------------------------------------------------------------------------- /zfilterenumflags_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zfilterenumflags_strings.go -type=filterEnumFlags -trimprefix=filterEnumFlags"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[filterEnumFlagsBestTerminatingMatch-1] 12 | _ = x[filterEnumFlagsSorted-2] 13 | _ = x[filterEnumFlagsBootTimeOnly-3] 14 | _ = x[filterEnumFlagsIncludeBootTime-4] 15 | _ = x[filterEnumFlagsIncludeDisabled-5] 16 | } 17 | 18 | const _filterEnumFlags_name = "BestTerminatingMatchSortedBootTimeOnlyIncludeBootTimeIncludeDisabled" 19 | 20 | var _filterEnumFlags_index = [...]uint8{0, 20, 26, 38, 53, 68} 21 | 22 | func (i filterEnumFlags) String() string { 23 | i -= 1 24 | if i >= filterEnumFlags(len(_filterEnumFlags_index)-1) { 25 | return "filterEnumFlags(" + strconv.FormatInt(int64(i+1), 10) + ")" 26 | } 27 | return _filterEnumFlags_name[_filterEnumFlags_index[i]:_filterEnumFlags_index[i+1]] 28 | } 29 | -------------------------------------------------------------------------------- /zfilterenumtype_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zfilterenumtype_strings.go -type=filterEnumType -trimprefix=filterEnumType"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[filterEnumTypeFullyContained-0] 12 | _ = x[filterEnumTypeOverlapping-1] 13 | } 14 | 15 | const _filterEnumType_name = "FullyContainedOverlapping" 16 | 17 | var _filterEnumType_index = [...]uint8{0, 14, 25} 18 | 19 | func (i filterEnumType) String() string { 20 | if i >= filterEnumType(len(_filterEnumType_index)-1) { 21 | return "filterEnumType(" + strconv.FormatInt(int64(i), 10) + ")" 22 | } 23 | return _filterEnumType_name[_filterEnumType_index[i]:_filterEnumType_index[i+1]] 24 | } 25 | -------------------------------------------------------------------------------- /zfilterflags_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zfilterflags_strings.go -type=fwpmFilterFlags -trimprefix=fwpmFilterFlags"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[fwpmFilterFlagsPersistent-1] 12 | _ = x[fwpmFilterFlagsBootTime-2] 13 | _ = x[fwpmFilterFlagsHasProviderContext-4] 14 | _ = x[fwpmFilterFlagsClearActionRight-8] 15 | _ = x[fwpmFilterFlagsPermitIfCalloutUnregistered-16] 16 | _ = x[fwpmFilterFlagsDisabled-32] 17 | _ = x[fwpmFilterFlagsIndexed-64] 18 | } 19 | 20 | const ( 21 | _fwpmFilterFlags_name_0 = "PersistentBootTime" 22 | _fwpmFilterFlags_name_1 = "HasProviderContext" 23 | _fwpmFilterFlags_name_2 = "ClearActionRight" 24 | _fwpmFilterFlags_name_3 = "PermitIfCalloutUnregistered" 25 | _fwpmFilterFlags_name_4 = "Disabled" 26 | _fwpmFilterFlags_name_5 = "Indexed" 27 | ) 28 | 29 | var ( 30 | _fwpmFilterFlags_index_0 = [...]uint8{0, 10, 18} 31 | ) 32 | 33 | func (i fwpmFilterFlags) String() string { 34 | switch { 35 | case 1 <= i && i <= 2: 36 | i -= 1 37 | return _fwpmFilterFlags_name_0[_fwpmFilterFlags_index_0[i]:_fwpmFilterFlags_index_0[i+1]] 38 | case i == 4: 39 | return _fwpmFilterFlags_name_1 40 | case i == 8: 41 | return _fwpmFilterFlags_name_2 42 | case i == 16: 43 | return _fwpmFilterFlags_name_3 44 | case i == 32: 45 | return _fwpmFilterFlags_name_4 46 | case i == 64: 47 | return _fwpmFilterFlags_name_5 48 | default: 49 | return "fwpmFilterFlags(" + strconv.FormatInt(int64(i), 10) + ")" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /zguids.go: -------------------------------------------------------------------------------- 1 | package wf 2 | 3 | import "golang.org/x/sys/windows" 4 | 5 | // Well-known callout IDs. 6 | var ( 7 | guidCalloutEdgeTraversalALEListenV4 = windows.GUID{0x33486ab5, 0x6d5e, 0x4e65, [8]byte{0xa0, 0x0b, 0xa7, 0xaf, 0xed, 0x0b, 0xa9, 0xa1}} 8 | guidCalloutEdgeTraversalALEResourceAssignmentV4 = windows.GUID{0x079b1010, 0xf1c5, 0x4fcd, [8]byte{0xae, 0x05, 0xda, 0x41, 0x10, 0x7a, 0xbd, 0x0b}} 9 | guidCalloutHttpTemplateSslHandshake = windows.GUID{0xb3423249, 0x8d09, 0x4858, [8]byte{0x92, 0x10, 0x95, 0xc7, 0xfd, 0xa8, 0xe3, 0x0f}} 10 | guidCalloutIPSecALEConnectV4 = windows.GUID{0x6ac141fc, 0xf75d, 0x4203, [8]byte{0xb9, 0xc8, 0x48, 0xe6, 0x14, 0x9c, 0x27, 0x12}} 11 | guidCalloutIPSecALEConnectV6 = windows.GUID{0x4c0dda05, 0xe31f, 0x4666, [8]byte{0x90, 0xb0, 0xb3, 0xdf, 0xad, 0x34, 0x12, 0x9a}} 12 | guidCalloutIPSecDospForwardV4 = windows.GUID{0x2fcb56ec, 0xcd37, 0x4b4f, [8]byte{0xb1, 0x08, 0x62, 0xc2, 0xb1, 0x85, 0x0a, 0x0c}} 13 | guidCalloutIPSecDospForwardV6 = windows.GUID{0x6d08a342, 0xdb9e, 0x4fbe, [8]byte{0x9e, 0xd2, 0x57, 0x37, 0x4c, 0xe8, 0x9f, 0x79}} 14 | guidCalloutIPSecForwardInboundTunnelV4 = windows.GUID{0x28829633, 0xc4f0, 0x4e66, [8]byte{0x87, 0x3f, 0x84, 0x4d, 0xb2, 0xa8, 0x99, 0xc7}} 15 | guidCalloutIPSecForwardInboundTunnelV6 = windows.GUID{0xaf50bec2, 0xc686, 0x429a, [8]byte{0x88, 0x4d, 0xb7, 0x44, 0x43, 0xe7, 0xb0, 0xb4}} 16 | guidCalloutIPSecForwardOutboundTunnelV4 = windows.GUID{0xfb532136, 0x15cb, 0x440b, [8]byte{0x93, 0x7c, 0x17, 0x17, 0xca, 0x32, 0x0c, 0x40}} 17 | guidCalloutIPSecForwardOutboundTunnelV6 = windows.GUID{0xdae640cc, 0xe021, 0x4bee, [8]byte{0x9e, 0xb6, 0xa4, 0x8b, 0x27, 0x5c, 0x8c, 0x1d}} 18 | guidCalloutIPSecInboundInitiateSecureV4 = windows.GUID{0x7dff309b, 0xba7d, 0x4aba, [8]byte{0x91, 0xaa, 0xae, 0x5c, 0x66, 0x40, 0xc9, 0x44}} 19 | guidCalloutIPSecInboundInitiateSecureV6 = windows.GUID{0xa9a0d6d9, 0xc58c, 0x474e, [8]byte{0x8a, 0xeb, 0x3c, 0xfe, 0x99, 0xd6, 0xd5, 0x3d}} 20 | guidCalloutIPSecInboundTransportV4 = windows.GUID{0x5132900d, 0x5e84, 0x4b5f, [8]byte{0x80, 0xe4, 0x01, 0x74, 0x1e, 0x81, 0xff, 0x10}} 21 | guidCalloutIPSecInboundTransportV6 = windows.GUID{0x49d3ac92, 0x2a6c, 0x4dcf, [8]byte{0x95, 0x5f, 0x1c, 0x3b, 0xe0, 0x09, 0xdd, 0x99}} 22 | guidCalloutIPSecInboundTunnelALEAcceptV4 = windows.GUID{0x3df6e7de, 0xfd20, 0x48f2, [8]byte{0x9f, 0x26, 0xf8, 0x54, 0x44, 0x4c, 0xba, 0x79}} 23 | guidCalloutIPSecInboundTunnelALEAcceptV6 = windows.GUID{0xa1e392d3, 0x72ac, 0x47bb, [8]byte{0x87, 0xa7, 0x01, 0x22, 0xc6, 0x94, 0x34, 0xab}} 24 | guidCalloutIPSecInboundTunnelV4 = windows.GUID{0x191a8a46, 0x0bf8, 0x46cf, [8]byte{0xb0, 0x45, 0x4b, 0x45, 0xdf, 0xa6, 0xa3, 0x24}} 25 | guidCalloutIPSecInboundTunnelV6 = windows.GUID{0x80c342e3, 0x1e53, 0x4d6f, [8]byte{0x9b, 0x44, 0x03, 0xdf, 0x5a, 0xee, 0xe1, 0x54}} 26 | guidCalloutIPSecOutboundTransportV4 = windows.GUID{0x4b46bf0a, 0x4523, 0x4e57, [8]byte{0xaa, 0x38, 0xa8, 0x79, 0x87, 0xc9, 0x10, 0xd9}} 27 | guidCalloutIPSecOutboundTransportV6 = windows.GUID{0x38d87722, 0xad83, 0x4f11, [8]byte{0xa9, 0x1f, 0xdf, 0x0f, 0xb0, 0x77, 0x22, 0x5b}} 28 | guidCalloutIPSecOutboundTunnelV4 = windows.GUID{0x70a4196c, 0x835b, 0x4fb0, [8]byte{0x98, 0xe8, 0x07, 0x5f, 0x4d, 0x97, 0x7d, 0x46}} 29 | guidCalloutIPSecOutboundTunnelV6 = windows.GUID{0xf1835363, 0xa6a5, 0x4e62, [8]byte{0xb1, 0x80, 0x23, 0xdb, 0x78, 0x9d, 0x8d, 0xa6}} 30 | guidCalloutPolicySilentModeAuthConnectLayerV4 = windows.GUID{0x5fbfc31d, 0xa51c, 0x44dc, [8]byte{0xac, 0xb6, 0x6, 0x24, 0xa0, 0x30, 0xa7, 0x00}} 31 | guidCalloutPolicySilentModeAuthConnectLayerV6 = windows.GUID{0x5fbfc31d, 0xa51c, 0x44dc, [8]byte{0xac, 0xb6, 0x6, 0x24, 0xa0, 0x30, 0xa7, 0x01}} 32 | guidCalloutPolicySilentModeAuthRecvAcceptLayerV4 = windows.GUID{0x5fbfc31d, 0xa51c, 0x44dc, [8]byte{0xac, 0xb6, 0x6, 0x24, 0xa0, 0x30, 0xa7, 0x02}} 33 | guidCalloutPolicySilentModeAuthRecvAcceptLayerV6 = windows.GUID{0x5fbfc31d, 0xa51c, 0x44dc, [8]byte{0xac, 0xb6, 0x6, 0x24, 0xa0, 0x30, 0xa7, 0x03}} 34 | guidCalloutReservedAuthConnectLayerV4 = windows.GUID{0x288b524d, 0x566, 0x4e19, [8]byte{0xb6, 0x12, 0x8f, 0x44, 0x1a, 0x2e, 0x59, 0x49}} 35 | guidCalloutReservedAuthConnectLayerV6 = windows.GUID{0xb84b92, 0x2b5e, 0x4b71, [8]byte{0xab, 0xe, 0xaa, 0xca, 0x43, 0xe3, 0x87, 0xe6}} 36 | guidCalloutSetOptionsAuthConnectLayerV4 = windows.GUID{0xbc582280, 0x1677, 0x41e9, [8]byte{0x94, 0xab, 0xc2, 0xfc, 0xb1, 0x5c, 0x2e, 0xeb}} 37 | guidCalloutSetOptionsAuthConnectLayerV6 = windows.GUID{0x98e5373c, 0xb884, 0x490f, [8]byte{0xb6, 0x5f, 0x2f, 0x6a, 0x4a, 0x57, 0x51, 0x95}} 38 | guidCalloutSetOptionsAuthRecvAcceptLayerV4 = windows.GUID{0x2d55f008, 0x0c01, 0x4f92, [8]byte{0xb2, 0x6e, 0xa0, 0x8a, 0x94, 0x56, 0x9b, 0x8d}} 39 | guidCalloutSetOptionsAuthRecvAcceptLayerV6 = windows.GUID{0x63018537, 0xf281, 0x4dc4, [8]byte{0x83, 0xd3, 0x8d, 0xec, 0x18, 0xb7, 0xad, 0xe2}} 40 | guidCalloutTCPChimneyAcceptLayerV4 = windows.GUID{0xe183ecb2, 0x3a7f, 0x4b54, [8]byte{0x8a, 0xd9, 0x76, 0x05, 0x0e, 0xd8, 0x80, 0xca}} 41 | guidCalloutTCPChimneyAcceptLayerV6 = windows.GUID{0x0378cf41, 0xbf98, 0x4603, [8]byte{0x81, 0xf2, 0x7f, 0x12, 0x58, 0x60, 0x79, 0xf6}} 42 | guidCalloutTCPChimneyConnectLayerV4 = windows.GUID{0xf3e10ab3, 0x2c25, 0x4279, [8]byte{0xac, 0x36, 0xc3, 0x0f, 0xc1, 0x81, 0xbe, 0xc4}} 43 | guidCalloutTCPChimneyConnectLayerV6 = windows.GUID{0x39e22085, 0xa341, 0x42fc, [8]byte{0xa2, 0x79, 0xae, 0xc9, 0x4e, 0x68, 0x9c, 0x56}} 44 | guidCalloutTCPTemplatesAcceptLayerV4 = windows.GUID{0x2f23f5d0, 0x40c4, 0x4c41, [8]byte{0xa2, 0x54, 0x46, 0xd8, 0xdb, 0xa8, 0x95, 0x7c}} 45 | guidCalloutTCPTemplatesAcceptLayerV6 = windows.GUID{0xb25152f0, 0x991c, 0x4f53, [8]byte{0xbb, 0xe7, 0xd2, 0x4b, 0x45, 0xfe, 0x63, 0x2c}} 46 | guidCalloutTCPTemplatesConnectLayerV4 = windows.GUID{0x215a0b39, 0x4b7e, 0x4eda, [8]byte{0x8c, 0xe4, 0x17, 0x96, 0x79, 0xdf, 0x62, 0x24}} 47 | guidCalloutTCPTemplatesConnectLayerV6 = windows.GUID{0x838b37a1, 0x5c12, 0x4d34, [8]byte{0x8b, 0x38, 0x07, 0x87, 0x28, 0xb2, 0xd2, 0x5c}} 48 | guidCalloutTeredoALEListenV6 = windows.GUID{0x81a434e7, 0xf60c, 0x4378, [8]byte{0xba, 0xb8, 0xc6, 0x25, 0xa3, 0x0f, 0x01, 0x97}} 49 | guidCalloutTeredoALEResourceAssignmentV6 = windows.GUID{0x31b95392, 0x066e, 0x42a2, [8]byte{0xb7, 0xdb, 0x92, 0xf8, 0xac, 0xdd, 0x56, 0xf9}} 50 | guidCalloutWFPTransportLayerV4SilentDrop = windows.GUID{0xeda08606, 0x2494, 0x4d78, [8]byte{0x89, 0xbc, 0x67, 0x83, 0x7c, 0x03, 0xb9, 0x69}} 51 | guidCalloutWFPTransportLayerV6SilentDrop = windows.GUID{0x8693cc74, 0xa075, 0x4156, [8]byte{0xb4, 0x76, 0x92, 0x86, 0xee, 0xce, 0x81, 0x4e}} 52 | ) 53 | 54 | // Well-known field IDs. 55 | var ( 56 | FieldALEAppID = FieldID{0xd78e1e87, 0x8644, 0x4ea5, [8]byte{0x94, 0x37, 0xd8, 0x09, 0xec, 0xef, 0xc9, 0x71}} 57 | FieldALEEffectiveName = FieldID{0xb1277b9a, 0xb781, 0x40fc, [8]byte{0x96, 0x71, 0xe5, 0xf1, 0xb9, 0x89, 0xf3, 0x4e}} 58 | FieldALENAPContext = FieldID{0x46275a9d, 0xc03f, 0x4d77, [8]byte{0xb7, 0x84, 0x1c, 0x57, 0xf4, 0xd0, 0x27, 0x53}} 59 | FieldALEOriginalAppID = FieldID{0x0e6cd086, 0xe1fb, 0x4212, [8]byte{0x84, 0x2f, 0x8a, 0x9f, 0x99, 0x3f, 0xb3, 0xf6}} 60 | FieldALEPackageID = FieldID{0x71bc78fa, 0xf17c, 0x4997, [8]byte{0xa6, 0x2, 0x6a, 0xbb, 0x26, 0x1f, 0x35, 0x1c}} 61 | FieldALEPromiscuousMode = FieldID{0x1c974776, 0x7182, 0x46e9, [8]byte{0xaf, 0xd3, 0xb0, 0x29, 0x10, 0xe3, 0x03, 0x34}} 62 | FieldALEReauthReason = FieldID{0xb482d227, 0x1979, 0x4a98, [8]byte{0x80, 0x44, 0x18, 0xbb, 0xe6, 0x23, 0x75, 0x42}} 63 | FieldALERemoteMachineID = FieldID{0x1aa47f51, 0x7f93, 0x4508, [8]byte{0xa2, 0x71, 0x81, 0xab, 0xb0, 0x0c, 0x9c, 0xab}} 64 | FieldALERemoteUserID = FieldID{0xf63073b7, 0x0189, 0x4ab0, [8]byte{0x95, 0xa4, 0x61, 0x23, 0xcb, 0xfa, 0xb8, 0x62}} 65 | FieldALESecurityAttributeFqbnValue = FieldID{0x37a57699, 0x5883, 0x4963, [8]byte{0x92, 0xb8, 0x3e, 0x70, 0x46, 0x88, 0xb0, 0xad}} 66 | FieldALESioFirewallSystemPort = FieldID{0xb9f4e088, 0xcb98, 0x4efb, [8]byte{0xa2, 0xc7, 0xad, 0x07, 0x33, 0x26, 0x43, 0xdb}} 67 | FieldALEUserID = FieldID{0xaf043a0a, 0xb34d, 0x4f86, [8]byte{0x97, 0x9c, 0xc9, 0x03, 0x71, 0xaf, 0x6e, 0x66}} 68 | FieldArrivalInterfaceIndex = FieldID{0xcc088db3, 0x1792, 0x4a71, [8]byte{0xb0, 0xf9, 0x03, 0x7d, 0x21, 0xcd, 0x82, 0x8b}} 69 | FieldArrivalInterfaceProfileID = FieldID{0xcdfe6aab, 0xc083, 0x4142, [8]byte{0x86, 0x79, 0xc0, 0x8f, 0x95, 0x32, 0x9c, 0x61}} 70 | FieldArrivalInterfaceType = FieldID{0x89f990de, 0xe798, 0x4e6d, [8]byte{0xab, 0x76, 0x7c, 0x95, 0x58, 0x29, 0x2e, 0x6f}} 71 | FieldArrivalTunnelType = FieldID{0x511166dc, 0x7a8c, 0x4aa7, [8]byte{0xb5, 0x33, 0x95, 0xab, 0x59, 0xfb, 0x03, 0x40}} 72 | FieldAuthenticationType = FieldID{0xeb458cd5, 0xda7b, 0x4ef9, [8]byte{0x8d, 0x43, 0x7b, 0x0a, 0x84, 0x03, 0x32, 0xf2}} 73 | FieldBitmapIPLocalAddress = FieldID{0x16ebc3df, 0x957a, 0x452e, [8]byte{0xa1, 0xfc, 0x3d, 0x2f, 0xf6, 0xa7, 0x30, 0xba}} 74 | FieldBitmapIPLocalPort = FieldID{0x9f90a920, 0xc3b5, 0x4569, [8]byte{0xba, 0x31, 0x8b, 0xd3, 0x91, 0xd, 0xc6, 0x56}} 75 | FieldBitmapIPRemoteAddress = FieldID{0x33f00e25, 0x8eec, 0x4531, [8]byte{0xa0, 0x5, 0x41, 0xb9, 0x11, 0xf6, 0x24, 0x52}} 76 | FieldBitmapIPRemotePort = FieldID{0x2663d549, 0xaaf2, 0x46a2, [8]byte{0x86, 0x66, 0x1e, 0x76, 0x67, 0xf8, 0x69, 0x85}} 77 | FieldBitmapIndexKey = FieldID{0xf36514c, 0x3226, 0x4a81, [8]byte{0xa2, 0x14, 0x2d, 0x51, 0x8b, 0x4, 0xd0, 0x8a}} 78 | FieldClientCertKeyLength = FieldID{0xa3ec00c7, 0x05f4, 0x4df7, [8]byte{0x91, 0xf2, 0x5f, 0x60, 0xd9, 0x1f, 0xf4, 0x43}} 79 | FieldClientCertOid = FieldID{0xc491ad5e, 0xf882, 0x4283, [8]byte{0xb9, 0x16, 0x43, 0x6b, 0x10, 0x3f, 0xf4, 0xad}} 80 | FieldClientToken = FieldID{0xc228fc1e, 0x403a, 0x4478, [8]byte{0xbe, 0x05, 0xc9, 0xba, 0xa4, 0xc0, 0x5a, 0xce}} 81 | FieldCompartmentID = FieldID{0x35a791ab, 0x4ac, 0x4ff2, [8]byte{0xa6, 0xbb, 0xda, 0x6c, 0xfa, 0xc7, 0x18, 0x6}} 82 | FieldCurrentProfileID = FieldID{0xab3033c9, 0xc0e3, 0x4759, [8]byte{0x93, 0x7d, 0x57, 0x58, 0xc6, 0x5d, 0x4a, 0xe3}} 83 | FieldDCOMAppID = FieldID{0xff2e7b4d, 0x3112, 0x4770, [8]byte{0xb6, 0x36, 0x4d, 0x24, 0xae, 0x3a, 0x6a, 0xf2}} 84 | FieldDestinationInterfaceIndex = FieldID{0x35cf6522, 0x4139, 0x45ee, [8]byte{0xa0, 0xd5, 0x67, 0xb8, 0x09, 0x49, 0xd8, 0x79}} 85 | FieldDestinationSubInterfaceIndex = FieldID{0x2b7d4399, 0xd4c7, 0x4738, [8]byte{0xa2, 0xf5, 0xe9, 0x94, 0xb4, 0x3d, 0xa3, 0x88}} 86 | FieldDirection = FieldID{0x8784c146, 0xca97, 0x44d6, [8]byte{0x9f, 0xd1, 0x19, 0xfb, 0x18, 0x40, 0xcb, 0xf7}} 87 | FieldEmbeddedLocalAddressType = FieldID{0x4672a468, 0x8a0a, 0x4202, [8]byte{0xab, 0xb4, 0x84, 0x9e, 0x92, 0xe6, 0x68, 0x09}} 88 | FieldEmbeddedLocalPort = FieldID{0xbfca394d, 0xacdb, 0x484e, [8]byte{0xb8, 0xe6, 0x2a, 0xff, 0x79, 0x75, 0x73, 0x45}} 89 | FieldEmbeddedProtocol = FieldID{0x07784107, 0xa29e, 0x4c7b, [8]byte{0x9e, 0xc7, 0x29, 0xc4, 0x4a, 0xfa, 0xfd, 0xbc}} 90 | FieldEmbeddedRemoteAddress = FieldID{0x77ee4b39, 0x3273, 0x4671, [8]byte{0xb6, 0x3b, 0xab, 0x6f, 0xeb, 0x66, 0xee, 0xb6}} 91 | FieldEmbeddedRemotePort = FieldID{0xcae4d6a1, 0x2968, 0x40ed, [8]byte{0xa4, 0xce, 0x54, 0x71, 0x60, 0xdd, 0xa8, 0x8d}} 92 | FieldEtherType = FieldID{0xfd08948d, 0xa219, 0x4d52, [8]byte{0xbb, 0x98, 0x1a, 0x55, 0x40, 0xee, 0x7b, 0x4e}} 93 | FieldFlags = FieldID{0x632ce23b, 0x5167, 0x435c, [8]byte{0x86, 0xd7, 0xe9, 0x03, 0x68, 0x4a, 0xa8, 0x0c}} 94 | FieldIPArrivalInterface = FieldID{0x618a9b6d, 0x386b, 0x4136, [8]byte{0xad, 0x6e, 0xb5, 0x15, 0x87, 0xcf, 0xb1, 0xcd}} 95 | FieldIPDestinationAddress = FieldID{0x2d79133b, 0xb390, 0x45c6, [8]byte{0x86, 0x99, 0xac, 0xac, 0xea, 0xaf, 0xed, 0x33}} 96 | FieldIPDestinationAddressType = FieldID{0x1ec1b7c9, 0x4eea, 0x4f5e, [8]byte{0xb9, 0xef, 0x76, 0xbe, 0xaa, 0xaf, 0x17, 0xee}} 97 | FieldIPDestinationPort = FieldID{0xce6def45, 0x60fb, 0x4a7b, [8]byte{0xa3, 0x04, 0xaf, 0x30, 0xa1, 0x17, 0x00, 0x0e}} 98 | FieldIPForwardInterface = FieldID{0x1076b8a5, 0x6323, 0x4c5e, [8]byte{0x98, 0x10, 0xe8, 0xd3, 0xfc, 0x9e, 0x61, 0x36}} 99 | FieldIPLocalAddress = FieldID{0xd9ee00de, 0xc1ef, 0x4617, [8]byte{0xbf, 0xe3, 0xff, 0xd8, 0xf5, 0xa0, 0x89, 0x57}} 100 | FieldIPLocalAddressType = FieldID{0x6ec7f6c4, 0x376b, 0x45d7, [8]byte{0x9e, 0x9c, 0xd3, 0x37, 0xce, 0xdc, 0xd2, 0x37}} 101 | FieldIPLocalAddressV4 = FieldID{0x03a629cb, 0x6e52, 0x49f8, [8]byte{0x9c, 0x41, 0x57, 0x09, 0x63, 0x3c, 0x09, 0xcf}} 102 | FieldIPLocalAddressV6 = FieldID{0x2381be84, 0x7524, 0x45b3, [8]byte{0xa0, 0x5b, 0x1e, 0x63, 0x7d, 0x9c, 0x7a, 0x6a}} 103 | FieldIPLocalInterface = FieldID{0x4cd62a49, 0x59c3, 0x4969, [8]byte{0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4}} 104 | FieldIPLocalPort = FieldID{0x0c1ba1af, 0x5765, 0x453f, [8]byte{0xaf, 0x22, 0xa8, 0xf7, 0x91, 0xac, 0x77, 0x5b}} 105 | FieldIPNexthopAddress = FieldID{0xeabe448a, 0xa711, 0x4d64, [8]byte{0x85, 0xb7, 0x3f, 0x76, 0xb6, 0x52, 0x99, 0xc7}} 106 | FieldIPNexthopInterface = FieldID{0x93ae8f5b, 0x7f6f, 0x4719, [8]byte{0x98, 0xc8, 0x14, 0xe9, 0x74, 0x29, 0xef, 0x04}} 107 | FieldIPPhysicalArrivalInterface = FieldID{0xda50d5c8, 0xfa0d, 0x4c89, [8]byte{0xb0, 0x32, 0x6e, 0x62, 0x13, 0x6d, 0x1e, 0x96}} 108 | FieldIPPhysicalNexthopInterface = FieldID{0xf09bd5ce, 0x5150, 0x48be, [8]byte{0xb0, 0x98, 0xc2, 0x51, 0x52, 0xfb, 0x1f, 0x92}} 109 | FieldIPProtocol = FieldID{0x3971ef2b, 0x623e, 0x4f9a, [8]byte{0x8c, 0xb1, 0x6e, 0x79, 0xb8, 0x06, 0xb9, 0xa7}} 110 | FieldIPRemoteAddress = FieldID{0xb235ae9a, 0x1d64, 0x49b8, [8]byte{0xa4, 0x4c, 0x5f, 0xf3, 0xd9, 0x09, 0x50, 0x45}} 111 | FieldIPRemoteAddressV4 = FieldID{0x1febb610, 0x3bcc, 0x45e1, [8]byte{0xbc, 0x36, 0x2e, 0x06, 0x7e, 0x2c, 0xb1, 0x86}} 112 | FieldIPRemoteAddressV6 = FieldID{0x246e1d8c, 0x8bee, 0x4018, [8]byte{0x9b, 0x98, 0x31, 0xd4, 0x58, 0x2f, 0x33, 0x61}} 113 | FieldIPRemotePort = FieldID{0xc35a604d, 0xd22b, 0x4e1a, [8]byte{0x91, 0xb4, 0x68, 0xf6, 0x74, 0xee, 0x67, 0x4b}} 114 | FieldIPSecPolicyKey = FieldID{0xad37dee3, 0x722f, 0x45cc, [8]byte{0xa4, 0xe3, 0x06, 0x80, 0x48, 0x12, 0x44, 0x52}} 115 | FieldIPSecSecurityRealmID = FieldID{0x37a57700, 0x5884, 0x4964, [8]byte{0x92, 0xb8, 0x3e, 0x70, 0x46, 0x88, 0xb0, 0xad}} 116 | FieldIPSourceAddress = FieldID{0xae96897e, 0x2e94, 0x4bc9, [8]byte{0xb3, 0x13, 0xb2, 0x7e, 0xe8, 0x0e, 0x57, 0x4d}} 117 | FieldIPSourcePort = FieldID{0xa6afef91, 0x3df4, 0x4730, [8]byte{0xa2, 0x14, 0xf5, 0x42, 0x6a, 0xeb, 0xf8, 0x21}} 118 | FieldImageName = FieldID{0xd024de4d, 0xdeaa, 0x4317, [8]byte{0x9c, 0x85, 0xe4, 0x0e, 0xf6, 0xe1, 0x40, 0xc3}} 119 | FieldInterfaceIndex = FieldID{0x667fd755, 0xd695, 0x434a, [8]byte{0x8a, 0xf5, 0xd3, 0x83, 0x5a, 0x12, 0x59, 0xbc}} 120 | FieldInterfaceMACAddress = FieldID{0xf6e63dce, 0x1f4b, 0x4c6b, [8]byte{0xb6, 0xef, 0x11, 0x65, 0xe7, 0x1f, 0x8e, 0xe7}} 121 | FieldInterfaceQuarantineEpoch = FieldID{0xcce68d5e, 0x053b, 0x43a8, [8]byte{0x9a, 0x6f, 0x33, 0x38, 0x4c, 0x28, 0xe4, 0xf6}} 122 | FieldInterfaceType = FieldID{0xdaf8cd14, 0xe09e, 0x4c93, [8]byte{0xa5, 0xae, 0xc5, 0xc1, 0x3b, 0x73, 0xff, 0xca}} 123 | FieldKMAuthNAPContext = FieldID{0x35d0ea0e, 0x15ca, 0x492b, [8]byte{0x90, 0x0e, 0x97, 0xfd, 0x46, 0x35, 0x2c, 0xce}} 124 | FieldKMMode = FieldID{0xfeef4582, 0xef8f, 0x4f7b, [8]byte{0x85, 0x8b, 0x90, 0x77, 0xd1, 0x22, 0xde, 0x47}} 125 | FieldKMType = FieldID{0xff0f5f49, 0x0ceb, 0x481b, [8]byte{0x86, 0x38, 0x14, 0x79, 0x79, 0x1f, 0x3f, 0x2c}} 126 | FieldL2Flags = FieldID{0x7bc43cbf, 0x37ba, 0x45f1, [8]byte{0xb7, 0x4a, 0x82, 0xff, 0x51, 0x8e, 0xeb, 0x10}} 127 | FieldLocalInterfaceProfileID = FieldID{0x4ebf7562, 0x9f18, 0x4d06, [8]byte{0x99, 0x41, 0xa7, 0xa6, 0x25, 0x74, 0x4d, 0x71}} 128 | FieldMACDestinationAddress = FieldID{0x04ea2a93, 0x858c, 0x4027, [8]byte{0xb6, 0x13, 0xb4, 0x31, 0x80, 0xc7, 0x85, 0x9e}} 129 | FieldMACDestinationAddressType = FieldID{0xae052932, 0xef42, 0x4e99, [8]byte{0xb1, 0x29, 0xf3, 0xb3, 0x13, 0x9e, 0x34, 0xf7}} 130 | FieldMACLocalAddress = FieldID{0xd999e981, 0x7948, 0x4c83, [8]byte{0xb7, 0x42, 0xc8, 0x4e, 0x3b, 0x67, 0x8f, 0x8f}} 131 | FieldMACLocalAddressType = FieldID{0xcc31355c, 0x3073, 0x4ffb, [8]byte{0xa1, 0x4f, 0x79, 0x41, 0x5c, 0xb1, 0xea, 0xd1}} 132 | FieldMACRemoteAddress = FieldID{0x408f2ed4, 0x3a70, 0x4b4d, [8]byte{0x92, 0xa6, 0x41, 0x5a, 0xc2, 0x0e, 0x2f, 0x12}} 133 | FieldMACRemoteAddressType = FieldID{0x027fedb4, 0xf1c1, 0x4030, [8]byte{0xb5, 0x64, 0xee, 0x77, 0x7f, 0xd8, 0x67, 0xea}} 134 | FieldMACSourceAddress = FieldID{0x7b795451, 0xf1f6, 0x4d05, [8]byte{0xb7, 0xcb, 0x21, 0x77, 0x9d, 0x80, 0x23, 0x36}} 135 | FieldMACSourceAddressType = FieldID{0x5c1b72e4, 0x299e, 0x4437, [8]byte{0xa2, 0x98, 0xbc, 0x3f, 0x01, 0x4b, 0x3d, 0xc2}} 136 | FieldNdisMediaType = FieldID{0xcb31cef1, 0x791d, 0x473b, [8]byte{0x89, 0xd1, 0x61, 0xc5, 0x98, 0x43, 0x04, 0xa0}} 137 | FieldNdisPhysicalMediaType = FieldID{0x34c79823, 0xc229, 0x44f2, [8]byte{0xb8, 0x3c, 0x74, 0x02, 0x08, 0x82, 0xae, 0x77}} 138 | FieldNdisPort = FieldID{0xdb7bb42b, 0x2dac, 0x4cd4, [8]byte{0xa5, 0x9a, 0xe0, 0xbd, 0xce, 0x1e, 0x68, 0x34}} 139 | FieldNetEventType = FieldID{0x206e9996, 0x490e, 0x40cf, [8]byte{0xb8, 0x31, 0xb3, 0x86, 0x41, 0xeb, 0x6f, 0xcb}} 140 | FieldNexthopInterfaceIndex = FieldID{0x138e6888, 0x7ab8, 0x4d65, [8]byte{0x9e, 0xe8, 0x05, 0x91, 0xbc, 0xf6, 0xa4, 0x94}} 141 | FieldNexthopInterfaceProfileID = FieldID{0xd7ff9a56, 0xcdaa, 0x472b, [8]byte{0x84, 0xdb, 0xd2, 0x39, 0x63, 0xc1, 0xd1, 0xbf}} 142 | FieldNexthopInterfaceType = FieldID{0x97537c6c, 0xd9a3, 0x4767, [8]byte{0xa3, 0x81, 0xe9, 0x42, 0x67, 0x5c, 0xd9, 0x20}} 143 | FieldNexthopSubInterfaceIndex = FieldID{0xef8a6122, 0x0577, 0x45a7, [8]byte{0x9a, 0xaf, 0x82, 0x5f, 0xbe, 0xb4, 0xfb, 0x95}} 144 | FieldNexthopTunnelType = FieldID{0x72b1a111, 0x987b, 0x4720, [8]byte{0x99, 0xdd, 0xc7, 0xc5, 0x76, 0xfa, 0x2d, 0x4c}} 145 | FieldOriginalICMPType = FieldID{0x076dfdbe, 0xc56c, 0x4f72, [8]byte{0xae, 0x8a, 0x2c, 0xfe, 0x7e, 0x5c, 0x82, 0x86}} 146 | FieldOriginalProfileID = FieldID{0x46ea1551, 0x2255, 0x492b, [8]byte{0x80, 0x19, 0xaa, 0xbe, 0xee, 0x34, 0x9f, 0x40}} 147 | FieldPeerName = FieldID{0x9b539082, 0xeb90, 0x4186, [8]byte{0xa6, 0xcc, 0xde, 0x5b, 0x63, 0x23, 0x50, 0x16}} 148 | FieldPipe = FieldID{0x1bd0741d, 0xe3df, 0x4e24, [8]byte{0x86, 0x34, 0x76, 0x20, 0x46, 0xee, 0xf6, 0xeb}} 149 | FieldProcessWithRPCIfUUID = FieldID{0xe31180a8, 0xbbbd, 0x4d14, [8]byte{0xa6, 0x5e, 0x71, 0x57, 0xb0, 0x62, 0x33, 0xbb}} 150 | FieldQMMode = FieldID{0xf64fc6d1, 0xf9cb, 0x43d2, [8]byte{0x8a, 0x5f, 0xe1, 0x3b, 0xc8, 0x94, 0xf2, 0x65}} 151 | FieldRPCAuthLevel = FieldID{0xe5a0aed5, 0x59ac, 0x46ea, [8]byte{0xbe, 0x05, 0xa5, 0xf0, 0x5e, 0xcf, 0x44, 0x6e}} 152 | FieldRPCAuthType = FieldID{0xdaba74ab, 0x0d67, 0x43e7, [8]byte{0x98, 0x6e, 0x75, 0xb8, 0x4f, 0x82, 0xf5, 0x94}} 153 | FieldRPCEPFlags = FieldID{0x218b814a, 0x0a39, 0x49b8, [8]byte{0x8e, 0x71, 0xc2, 0x0c, 0x39, 0xc7, 0xdd, 0x2e}} 154 | FieldRPCEPValue = FieldID{0xdccea0b9, 0x0886, 0x4360, [8]byte{0x9c, 0x6a, 0xab, 0x04, 0x3a, 0x24, 0xfb, 0xa9}} 155 | FieldRPCIfFlag = FieldID{0x238a8a32, 0x3199, 0x467d, [8]byte{0x87, 0x1c, 0x27, 0x26, 0x21, 0xab, 0x38, 0x96}} 156 | FieldRPCIfUUID = FieldID{0x7c9c7d9f, 0x0075, 0x4d35, [8]byte{0xa0, 0xd1, 0x83, 0x11, 0xc4, 0xcf, 0x6a, 0xf1}} 157 | FieldRPCIfVersion = FieldID{0xeabfd9b7, 0x1262, 0x4a2e, [8]byte{0xad, 0xaa, 0x5f, 0x96, 0xf6, 0xfe, 0x32, 0x6d}} 158 | FieldRPCProtocol = FieldID{0x2717bc74, 0x3a35, 0x4ce7, [8]byte{0xb7, 0xef, 0xc8, 0x38, 0xfa, 0xbd, 0xec, 0x45}} 159 | FieldRPCProxyAuthType = FieldID{0x40953fe2, 0x8565, 0x4759, [8]byte{0x84, 0x88, 0x17, 0x71, 0xb4, 0xb4, 0xb5, 0xdb}} 160 | FieldRPCServerName = FieldID{0xb605a225, 0xc3b3, 0x48c7, [8]byte{0x98, 0x33, 0x7a, 0xef, 0xa9, 0x52, 0x75, 0x46}} 161 | FieldRPCServerPort = FieldID{0x8090f645, 0x9ad5, 0x4e3b, [8]byte{0x9f, 0x9f, 0x80, 0x23, 0xca, 0x09, 0x79, 0x09}} 162 | FieldReauthorizeReason = FieldID{0x11205e8c, 0x11ae, 0x457a, [8]byte{0x8a, 0x44, 0x47, 0x70, 0x26, 0xdd, 0x76, 0x4a}} 163 | FieldRemoteID = FieldID{0xf68166fd, 0x0682, 0x4c89, [8]byte{0xb8, 0xf5, 0x86, 0x43, 0x6c, 0x7e, 0xf9, 0xb7}} 164 | FieldRemoteUserToken = FieldID{0x9bf0ee66, 0x06c9, 0x41b9, [8]byte{0x84, 0xda, 0x28, 0x8c, 0xb4, 0x3a, 0xf5, 0x1f}} 165 | FieldReserved0 = FieldID{0x678f4deb, 0x45af, 0x4882, [8]byte{0x93, 0xfe, 0x19, 0xd4, 0x72, 0x9d, 0x98, 0x34}} 166 | FieldReserved1 = FieldID{0xd818f827, 0x5c69, 0x48eb, [8]byte{0xbf, 0x80, 0xd8, 0x6b, 0x17, 0x75, 0x5f, 0x97}} 167 | FieldReserved10 = FieldID{0xb979e282, 0xd621, 0x4c8c, [8]byte{0xb1, 0x84, 0xb1, 0x05, 0xa6, 0x1c, 0x36, 0xce}} 168 | FieldReserved11 = FieldID{0x2d62ee4d, 0x023d, 0x411f, [8]byte{0x95, 0x82, 0x43, 0xac, 0xbb, 0x79, 0x59, 0x75}} 169 | FieldReserved12 = FieldID{0xa3677c32, 0x7e35, 0x4ddc, [8]byte{0x93, 0xda, 0xe8, 0xc3, 0x3f, 0xc9, 0x23, 0xc7}} 170 | FieldReserved13 = FieldID{0x335a3e90, 0x84aa, 0x42f5, [8]byte{0x9e, 0x6f, 0x59, 0x30, 0x95, 0x36, 0xa4, 0x4c}} 171 | FieldReserved14 = FieldID{0x30e44da2, 0x2f1a, 0x4116, [8]byte{0xa5, 0x59, 0xf9, 0x07, 0xde, 0x83, 0x60, 0x4a}} 172 | FieldReserved15 = FieldID{0xbab8340f, 0xafe0, 0x43d1, [8]byte{0x80, 0xd8, 0x5c, 0xa4, 0x56, 0x96, 0x2d, 0xe3}} 173 | FieldReserved2 = FieldID{0x53d4123d, 0xe15b, 0x4e84, [8]byte{0xb7, 0xa8, 0xdc, 0xe1, 0x6f, 0x7b, 0x62, 0xd9}} 174 | FieldReserved3 = FieldID{0x7f6e8ca3, 0x6606, 0x4932, [8]byte{0x97, 0xc7, 0xe1, 0xf2, 0x07, 0x10, 0xaf, 0x3b}} 175 | FieldReserved4 = FieldID{0x5f58e642, 0xb937, 0x495e, [8]byte{0xa9, 0x4b, 0xf6, 0xb0, 0x51, 0xa4, 0x92, 0x50}} 176 | FieldReserved5 = FieldID{0x9ba8f6cd, 0xf77c, 0x43e6, [8]byte{0x88, 0x47, 0x11, 0x93, 0x9d, 0xc5, 0xdb, 0x5a}} 177 | FieldReserved6 = FieldID{0xf13d84bd, 0x59d5, 0x44c4, [8]byte{0x88, 0x17, 0x5e, 0xcd, 0xae, 0x18, 0x05, 0xbd}} 178 | FieldReserved7 = FieldID{0x65a0f930, 0x45dd, 0x4983, [8]byte{0xaa, 0x33, 0xef, 0xc7, 0xb6, 0x11, 0xaf, 0x08}} 179 | FieldReserved8 = FieldID{0x4f424974, 0x0c12, 0x4816, [8]byte{0x9b, 0x47, 0x9a, 0x54, 0x7d, 0xb3, 0x9a, 0x32}} 180 | FieldReserved9 = FieldID{0xce78e10f, 0x13ff, 0x4c70, [8]byte{0x86, 0x43, 0x36, 0xad, 0x18, 0x79, 0xaf, 0xa3}} 181 | FieldSecEncryptAlgorithm = FieldID{0x0d306ef0, 0xe974, 0x4f74, [8]byte{0xb5, 0xc7, 0x59, 0x1b, 0x0d, 0xa7, 0xd5, 0x62}} 182 | FieldSecKeySize = FieldID{0x4772183b, 0xccf8, 0x4aeb, [8]byte{0xbc, 0xe1, 0xc6, 0xc6, 0x16, 0x1c, 0x8f, 0xe4}} 183 | FieldSourceInterfaceIndex = FieldID{0x2311334d, 0xc92d, 0x45bf, [8]byte{0x94, 0x96, 0xed, 0xf4, 0x47, 0x82, 0x0e, 0x2d}} 184 | FieldSourceSubInterfaceIndex = FieldID{0x055edd9d, 0xacd2, 0x4361, [8]byte{0x8d, 0xab, 0xf9, 0x52, 0x5d, 0x97, 0x66, 0x2f}} 185 | FieldSubInterfaceIndex = FieldID{0x0cd42473, 0xd621, 0x4be3, [8]byte{0xae, 0x8c, 0x72, 0xa3, 0x48, 0xd2, 0x83, 0xe1}} 186 | FieldTunnelType = FieldID{0x77a40437, 0x8779, 0x4868, [8]byte{0xa2, 0x61, 0xf5, 0xa9, 0x02, 0xf1, 0xc0, 0xcd}} 187 | FieldVLANID = FieldID{0x938eab21, 0x3618, 0x4e64, [8]byte{0x9c, 0xa5, 0x21, 0x41, 0xeb, 0xda, 0x1c, 0xa2}} 188 | FieldVSwitchDestinationInterfaceID = FieldID{0x8ed48be4, 0xc926, 0x49f6, [8]byte{0xa4, 0xf6, 0xef, 0x30, 0x30, 0xe3, 0xfc, 0x16}} 189 | FieldVSwitchDestinationInterfaceType = FieldID{0xfa9b3f06, 0x2f1a, 0x4c57, [8]byte{0x9e, 0x68, 0xa7, 0x09, 0x8b, 0x28, 0xdb, 0xfe}} 190 | FieldVSwitchDestinationVmID = FieldID{0x6106aace, 0x4de1, 0x4c84, [8]byte{0x96, 0x71, 0x36, 0x37, 0xf8, 0xbc, 0xf7, 0x31}} 191 | FieldVSwitchID = FieldID{0xc4a414ba, 0x437b, 0x4de6, [8]byte{0x99, 0x46, 0xd9, 0x9c, 0x1b, 0x95, 0xb3, 0x12}} 192 | FieldVSwitchNetworkType = FieldID{0x11d48b4b, 0xe77a, 0x40b4, [8]byte{0x91, 0x55, 0x39, 0x2c, 0x90, 0x6c, 0x26, 0x08}} 193 | FieldVSwitchSourceInterfaceID = FieldID{0x7f4ef24b, 0xb2c1, 0x4938, [8]byte{0xba, 0x33, 0xa1, 0xec, 0xbe, 0xd5, 0x12, 0xba}} 194 | FieldVSwitchSourceInterfaceType = FieldID{0xe6b040a2, 0xedaf, 0x4c36, [8]byte{0x90, 0x8b, 0xf2, 0xf5, 0x8a, 0xe4, 0x38, 0x07}} 195 | FieldVSwitchSourceVmID = FieldID{0x9c2a9ec2, 0x9fc6, 0x42bc, [8]byte{0xbd, 0xd8, 0x40, 0x6d, 0x4d, 0xa0, 0xbe, 0x64}} 196 | FieldVSwitchTenantNetworkID = FieldID{0xdc04843c, 0x79e6, 0x4e44, [8]byte{0xa0, 0x25, 0x65, 0xb9, 0xbb, 0x0f, 0x9f, 0x94}} 197 | ) 198 | 199 | // Well-known keying IDs. 200 | var ( 201 | guidKeyingModuleAuthIP = windows.GUID{0x11e3dae0, 0xdd26, 0x4590, [8]byte{0x85, 0x7d, 0xab, 0x4b, 0x28, 0xd1, 0xa0, 0x95}} 202 | guidKeyingModuleIKE = windows.GUID{0xa9bbf787, 0x82a8, 0x45bb, [8]byte{0xa4, 0x00, 0x5d, 0x7e, 0x59, 0x52, 0xc7, 0xa9}} 203 | guidKeyingModuleIKEv2 = windows.GUID{0x041792cc, 0x8f07, 0x419d, [8]byte{0xa3, 0x94, 0x71, 0x69, 0x68, 0xcb, 0x16, 0x47}} 204 | ) 205 | 206 | // Well-known layer IDs. 207 | var ( 208 | LayerALEAuthConnectV4 = LayerID{0xc38d57d1, 0x05a7, 0x4c33, [8]byte{0x90, 0x4f, 0x7f, 0xbc, 0xee, 0xe6, 0x0e, 0x82}} 209 | LayerALEAuthConnectV4Discard = LayerID{0xd632a801, 0xf5ba, 0x4ad6, [8]byte{0x96, 0xe3, 0x60, 0x70, 0x17, 0xd9, 0x83, 0x6a}} 210 | LayerALEAuthConnectV6 = LayerID{0x4a72393b, 0x319f, 0x44bc, [8]byte{0x84, 0xc3, 0xba, 0x54, 0xdc, 0xb3, 0xb6, 0xb4}} 211 | LayerALEAuthConnectV6Discard = LayerID{0xc97bc3b8, 0xc9a3, 0x4e33, [8]byte{0x86, 0x95, 0x8e, 0x17, 0xaa, 0xd4, 0xde, 0x09}} 212 | LayerALEAuthListenV4 = LayerID{0x88bb5dad, 0x76d7, 0x4227, [8]byte{0x9c, 0x71, 0xdf, 0x0a, 0x3e, 0xd7, 0xbe, 0x7e}} 213 | LayerALEAuthListenV4Discard = LayerID{0x371dfada, 0x9f26, 0x45fd, [8]byte{0xb4, 0xeb, 0xc2, 0x9e, 0xb2, 0x12, 0x89, 0x3f}} 214 | LayerALEAuthListenV6 = LayerID{0x7ac9de24, 0x17dd, 0x4814, [8]byte{0xb4, 0xbd, 0xa9, 0xfb, 0xc9, 0x5a, 0x32, 0x1b}} 215 | LayerALEAuthListenV6Discard = LayerID{0x60703b07, 0x63c8, 0x48e9, [8]byte{0xad, 0xa3, 0x12, 0xb1, 0xaf, 0x40, 0xa6, 0x17}} 216 | LayerALEAuthRecvAcceptV4 = LayerID{0xe1cd9fe7, 0xf4b5, 0x4273, [8]byte{0x96, 0xc0, 0x59, 0x2e, 0x48, 0x7b, 0x86, 0x50}} 217 | LayerALEAuthRecvAcceptV4Discard = LayerID{0x9eeaa99b, 0xbd22, 0x4227, [8]byte{0x91, 0x9f, 0x00, 0x73, 0xc6, 0x33, 0x57, 0xb1}} 218 | LayerALEAuthRecvAcceptV6 = LayerID{0xa3b42c97, 0x9f04, 0x4672, [8]byte{0xb8, 0x7e, 0xce, 0xe9, 0xc4, 0x83, 0x25, 0x7f}} 219 | LayerALEAuthRecvAcceptV6Discard = LayerID{0x89455b97, 0xdbe1, 0x453f, [8]byte{0xa2, 0x24, 0x13, 0xda, 0x89, 0x5a, 0xf3, 0x96}} 220 | LayerALEBindRedirectV4 = LayerID{0x66978cad, 0xc704, 0x42ac, [8]byte{0x86, 0xac, 0x7c, 0x1a, 0x23, 0x1b, 0xd2, 0x53}} 221 | LayerALEBindRedirectV6 = LayerID{0xbef02c9c, 0x606b, 0x4536, [8]byte{0x8c, 0x26, 0x1c, 0x2f, 0xc7, 0xb6, 0x31, 0xd4}} 222 | LayerALEConnectRedirectV4 = LayerID{0xc6e63c8c, 0xb784, 0x4562, [8]byte{0xaa, 0x7d, 0x0a, 0x67, 0xcf, 0xca, 0xf9, 0xa3}} 223 | LayerALEConnectRedirectV6 = LayerID{0x587e54a7, 0x8046, 0x42ba, [8]byte{0xa0, 0xaa, 0xb7, 0x16, 0x25, 0x0f, 0xc7, 0xfd}} 224 | LayerALEEndpointClosureV4 = LayerID{0xb4766427, 0xe2a2, 0x467a, [8]byte{0xbd, 0x7e, 0xdb, 0xcd, 0x1b, 0xd8, 0x5a, 0x09}} 225 | LayerALEEndpointClosureV6 = LayerID{0xbb536ccd, 0x4755, 0x4ba9, [8]byte{0x9f, 0xf7, 0xf9, 0xed, 0xf8, 0x69, 0x9c, 0x7b}} 226 | LayerALEFlowEstablishedV4 = LayerID{0xaf80470a, 0x5596, 0x4c13, [8]byte{0x99, 0x92, 0x53, 0x9e, 0x6f, 0xe5, 0x79, 0x67}} 227 | LayerALEFlowEstablishedV4Discard = LayerID{0x146ae4a9, 0xa1d2, 0x4d43, [8]byte{0xa3, 0x1a, 0x4c, 0x42, 0x68, 0x2b, 0x8e, 0x4f}} 228 | LayerALEFlowEstablishedV6 = LayerID{0x7021d2b3, 0xdfa4, 0x406e, [8]byte{0xaf, 0xeb, 0x6a, 0xfa, 0xf7, 0xe7, 0x0e, 0xfd}} 229 | LayerALEFlowEstablishedV6Discard = LayerID{0x46928636, 0xbbca, 0x4b76, [8]byte{0x94, 0x1d, 0x0f, 0xa7, 0xf5, 0xd7, 0xd3, 0x72}} 230 | LayerALEResourceAssignmentV4 = LayerID{0x1247d66d, 0x0b60, 0x4a15, [8]byte{0x8d, 0x44, 0x71, 0x55, 0xd0, 0xf5, 0x3a, 0x0c}} 231 | LayerALEResourceAssignmentV4Discard = LayerID{0x0b5812a2, 0xc3ff, 0x4eca, [8]byte{0xb8, 0x8d, 0xc7, 0x9e, 0x20, 0xac, 0x63, 0x22}} 232 | LayerALEResourceAssignmentV6 = LayerID{0x55a650e1, 0x5f0a, 0x4eca, [8]byte{0xa6, 0x53, 0x88, 0xf5, 0x3b, 0x26, 0xaa, 0x8c}} 233 | LayerALEResourceAssignmentV6Discard = LayerID{0xcbc998bb, 0xc51f, 0x4c1a, [8]byte{0xbb, 0x4f, 0x97, 0x75, 0xfc, 0xac, 0xab, 0x2f}} 234 | LayerALEResourceReleaseV4 = LayerID{0x74365cce, 0xccb0, 0x401a, [8]byte{0xbf, 0xc1, 0xb8, 0x99, 0x34, 0xad, 0x7e, 0x15}} 235 | LayerALEResourceReleaseV6 = LayerID{0xf4e5ce80, 0xedcc, 0x4e13, [8]byte{0x8a, 0x2f, 0xb9, 0x14, 0x54, 0xbb, 0x05, 0x7b}} 236 | LayerDatagramDataV4 = LayerID{0x3d08bf4e, 0x45f6, 0x4930, [8]byte{0xa9, 0x22, 0x41, 0x70, 0x98, 0xe2, 0x00, 0x27}} 237 | LayerDatagramDataV4Discard = LayerID{0x18e330c6, 0x7248, 0x4e52, [8]byte{0xaa, 0xab, 0x47, 0x2e, 0xd6, 0x77, 0x04, 0xfd}} 238 | LayerDatagramDataV6 = LayerID{0xfa45fe2f, 0x3cba, 0x4427, [8]byte{0x87, 0xfc, 0x57, 0xb9, 0xa4, 0xb1, 0x0d, 0x00}} 239 | LayerDatagramDataV6Discard = LayerID{0x09d1dfe1, 0x9b86, 0x4a42, [8]byte{0xbe, 0x9d, 0x8c, 0x31, 0x5b, 0x92, 0xa5, 0xd0}} 240 | LayerEgressVSwitchEthernet = LayerID{0x86c872b0, 0x76fa, 0x4b79, [8]byte{0x93, 0xa4, 0x07, 0x50, 0x53, 0x0a, 0xe2, 0x92}} 241 | LayerEgressVSwitchTransportV4 = LayerID{0xb92350b6, 0x91f0, 0x46b6, [8]byte{0xbd, 0xc4, 0x87, 0x1d, 0xfd, 0x4a, 0x7c, 0x98}} 242 | LayerEgressVSwitchTransportV6 = LayerID{0x1b2def23, 0x1881, 0x40bd, [8]byte{0x82, 0xf4, 0x42, 0x54, 0xe6, 0x31, 0x41, 0xcb}} 243 | LayerIKEExtV4 = LayerID{0xb14b7bdb, 0xdbbd, 0x473e, [8]byte{0xbe, 0xd4, 0x8b, 0x47, 0x08, 0xd4, 0xf2, 0x70}} 244 | LayerIKEExtV6 = LayerID{0xb64786b3, 0xf687, 0x4eb9, [8]byte{0x89, 0xd2, 0x8e, 0xf3, 0x2a, 0xcd, 0xab, 0xe2}} 245 | LayerIPForwardV4 = LayerID{0xa82acc24, 0x4ee1, 0x4ee1, [8]byte{0xb4, 0x65, 0xfd, 0x1d, 0x25, 0xcb, 0x10, 0xa4}} 246 | LayerIPForwardV4Discard = LayerID{0x9e9ea773, 0x2fae, 0x4210, [8]byte{0x8f, 0x17, 0x34, 0x12, 0x9e, 0xf3, 0x69, 0xeb}} 247 | LayerIPForwardV6 = LayerID{0x7b964818, 0x19c7, 0x493a, [8]byte{0xb7, 0x1f, 0x83, 0x2c, 0x36, 0x84, 0xd2, 0x8c}} 248 | LayerIPForwardV6Discard = LayerID{0x31524a5d, 0x1dfe, 0x472f, [8]byte{0xbb, 0x93, 0x51, 0x8e, 0xe9, 0x45, 0xd8, 0xa2}} 249 | LayerIPSecKMDemuxV4 = LayerID{0xf02b1526, 0xa459, 0x4a51, [8]byte{0xb9, 0xe3, 0x75, 0x9d, 0xe5, 0x2b, 0x9d, 0x2c}} 250 | LayerIPSecKMDemuxV6 = LayerID{0x2f755cf6, 0x2fd4, 0x4e88, [8]byte{0xb3, 0xe4, 0xa9, 0x1b, 0xca, 0x49, 0x52, 0x35}} 251 | LayerIPSecV4 = LayerID{0xeda65c74, 0x610d, 0x4bc5, [8]byte{0x94, 0x8f, 0x3c, 0x4f, 0x89, 0x55, 0x68, 0x67}} 252 | LayerIPSecV6 = LayerID{0x13c48442, 0x8d87, 0x4261, [8]byte{0x9a, 0x29, 0x59, 0xd2, 0xab, 0xc3, 0x48, 0xb4}} 253 | LayerInboundICMPErrorV4 = LayerID{0x61499990, 0x3cb6, 0x4e84, [8]byte{0xb9, 0x50, 0x53, 0xb9, 0x4b, 0x69, 0x64, 0xf3}} 254 | LayerInboundICMPErrorV4Discard = LayerID{0xa6b17075, 0xebaf, 0x4053, [8]byte{0xa4, 0xe7, 0x21, 0x3c, 0x81, 0x21, 0xed, 0xe5}} 255 | LayerInboundICMPErrorV6 = LayerID{0x65f9bdff, 0x3b2d, 0x4e5d, [8]byte{0xb8, 0xc6, 0xc7, 0x20, 0x65, 0x1f, 0xe8, 0x98}} 256 | LayerInboundICMPErrorV6Discard = LayerID{0xa6e7ccc0, 0x08fb, 0x468d, [8]byte{0xa4, 0x72, 0x97, 0x71, 0xd5, 0x59, 0x5e, 0x09}} 257 | LayerInboundIPPacketV4 = LayerID{0xc86fd1bf, 0x21cd, 0x497e, [8]byte{0xa0, 0xbb, 0x17, 0x42, 0x5c, 0x88, 0x5c, 0x58}} 258 | LayerInboundIPPacketV4Discard = LayerID{0xb5a230d0, 0xa8c0, 0x44f2, [8]byte{0x91, 0x6e, 0x99, 0x1b, 0x53, 0xde, 0xd1, 0xf7}} 259 | LayerInboundIPPacketV6 = LayerID{0xf52032cb, 0x991c, 0x46e7, [8]byte{0x97, 0x1d, 0x26, 0x01, 0x45, 0x9a, 0x91, 0xca}} 260 | LayerInboundIPPacketV6Discard = LayerID{0xbb24c279, 0x93b4, 0x47a2, [8]byte{0x83, 0xad, 0xae, 0x16, 0x98, 0xb5, 0x08, 0x85}} 261 | LayerInboundMACFrameEthernet = LayerID{0xeffb7edb, 0x0055, 0x4f9a, [8]byte{0xa2, 0x31, 0x4f, 0xf8, 0x13, 0x1a, 0xd1, 0x91}} 262 | LayerInboundMACFrameNative = LayerID{0xd4220bd3, 0x62ce, 0x4f08, [8]byte{0xae, 0x88, 0xb5, 0x6e, 0x85, 0x26, 0xdf, 0x50}} 263 | LayerInboundMACFrameNativeFast = LayerID{0x853aaa8e, 0x2b78, 0x4d24, [8]byte{0xa8, 0x04, 0x36, 0xdb, 0x08, 0xb2, 0x97, 0x11}} 264 | LayerInboundReserved2 = LayerID{0xf4fb8d55, 0xc076, 0x46d8, [8]byte{0xa2, 0xc7, 0x6a, 0x4c, 0x72, 0x2c, 0xa4, 0xed}} 265 | LayerInboundTransportFast = LayerID{0xe41d2719, 0x05c7, 0x40f0, [8]byte{0x89, 0x83, 0xea, 0x8d, 0x17, 0xbb, 0xc2, 0xf6}} 266 | LayerInboundTransportV4 = LayerID{0x5926dfc8, 0xe3cf, 0x4426, [8]byte{0xa2, 0x83, 0xdc, 0x39, 0x3f, 0x5d, 0x0f, 0x9d}} 267 | LayerInboundTransportV4Discard = LayerID{0xac4a9833, 0xf69d, 0x4648, [8]byte{0xb2, 0x61, 0x6d, 0xc8, 0x48, 0x35, 0xef, 0x39}} 268 | LayerInboundTransportV6 = LayerID{0x634a869f, 0xfc23, 0x4b90, [8]byte{0xb0, 0xc1, 0xbf, 0x62, 0x0a, 0x36, 0xae, 0x6f}} 269 | LayerInboundTransportV6Discard = LayerID{0x2a6ff955, 0x3b2b, 0x49d2, [8]byte{0x98, 0x48, 0xad, 0x9d, 0x72, 0xdc, 0xaa, 0xb7}} 270 | LayerIngressVSwitchEthernet = LayerID{0x7d98577a, 0x9a87, 0x41ec, [8]byte{0x97, 0x18, 0x7c, 0xf5, 0x89, 0xc9, 0xf3, 0x2d}} 271 | LayerIngressVSwitchTransportV4 = LayerID{0xb2696ff6, 0x774f, 0x4554, [8]byte{0x9f, 0x7d, 0x3d, 0xa3, 0x94, 0x5f, 0x8e, 0x85}} 272 | LayerIngressVSwitchTransportV6 = LayerID{0x5ee314fc, 0x7d8a, 0x47f4, [8]byte{0xb7, 0xe3, 0x29, 0x1a, 0x36, 0xda, 0x4e, 0x12}} 273 | LayerKMAuthorization = LayerID{0x4aa226e9, 0x9020, 0x45fb, [8]byte{0x95, 0x6a, 0xc0, 0x24, 0x9d, 0x84, 0x11, 0x95}} 274 | LayerNameResolutionCacheV4 = LayerID{0x0c2aa681, 0x905b, 0x4ccd, [8]byte{0xa4, 0x67, 0x4d, 0xd8, 0x11, 0xd0, 0x7b, 0x7b}} 275 | LayerNameResolutionCacheV6 = LayerID{0x92d592fa, 0x6b01, 0x434a, [8]byte{0x9d, 0xea, 0xd1, 0xe9, 0x6e, 0xa9, 0x7d, 0xa9}} 276 | LayerOutboundICMPErrorV4 = LayerID{0x41390100, 0x564c, 0x4b32, [8]byte{0xbc, 0x1d, 0x71, 0x80, 0x48, 0x35, 0x4d, 0x7c}} 277 | LayerOutboundICMPErrorV4Discard = LayerID{0xb3598d36, 0x0561, 0x4588, [8]byte{0xa6, 0xbf, 0xe9, 0x55, 0xe3, 0xf6, 0x26, 0x4b}} 278 | LayerOutboundICMPErrorV6 = LayerID{0x7fb03b60, 0x7b8d, 0x4dfa, [8]byte{0xba, 0xdd, 0x98, 0x01, 0x76, 0xfc, 0x4e, 0x12}} 279 | LayerOutboundICMPErrorV6Discard = LayerID{0x65f2e647, 0x8d0c, 0x4f47, [8]byte{0xb1, 0x9b, 0x33, 0xa4, 0xd3, 0xf1, 0x35, 0x7c}} 280 | LayerOutboundIPPacketV4 = LayerID{0x1e5c9fae, 0x8a84, 0x4135, [8]byte{0xa3, 0x31, 0x95, 0x0b, 0x54, 0x22, 0x9e, 0xcd}} 281 | LayerOutboundIPPacketV4Discard = LayerID{0x08e4bcb5, 0xb647, 0x48f3, [8]byte{0x95, 0x3c, 0xe5, 0xdd, 0xbd, 0x03, 0x93, 0x7e}} 282 | LayerOutboundIPPacketV6 = LayerID{0xa3b3ab6b, 0x3564, 0x488c, [8]byte{0x91, 0x17, 0xf3, 0x4e, 0x82, 0x14, 0x27, 0x63}} 283 | LayerOutboundIPPacketV6Discard = LayerID{0x9513d7c4, 0xa934, 0x49dc, [8]byte{0x91, 0xa7, 0x6c, 0xcb, 0x80, 0xcc, 0x02, 0xe3}} 284 | LayerOutboundMACFrameEthernet = LayerID{0x694673bc, 0xd6db, 0x4870, [8]byte{0xad, 0xee, 0x0a, 0xcd, 0xbd, 0xb7, 0xf4, 0xb2}} 285 | LayerOutboundMACFrameNative = LayerID{0x94c44912, 0x9d6f, 0x4ebf, [8]byte{0xb9, 0x95, 0x05, 0xab, 0x8a, 0x08, 0x8d, 0x1b}} 286 | LayerOutboundMACFrameNativeFast = LayerID{0x470df946, 0xc962, 0x486f, [8]byte{0x94, 0x46, 0x82, 0x93, 0xcb, 0xc7, 0x5e, 0xb8}} 287 | LayerOutboundTransportFast = LayerID{0x13ed4388, 0xa070, 0x4815, [8]byte{0x99, 0x35, 0x7a, 0x9b, 0xe6, 0x40, 0x8b, 0x78}} 288 | LayerOutboundTransportV4 = LayerID{0x09e61aea, 0xd214, 0x46e2, [8]byte{0x9b, 0x21, 0xb2, 0x6b, 0x0b, 0x2f, 0x28, 0xc8}} 289 | LayerOutboundTransportV4Discard = LayerID{0xc5f10551, 0xbdb0, 0x43d7, [8]byte{0xa3, 0x13, 0x50, 0xe2, 0x11, 0xf4, 0xd6, 0x8a}} 290 | LayerOutboundTransportV6 = LayerID{0xe1735bde, 0x013f, 0x4655, [8]byte{0xb3, 0x51, 0xa4, 0x9e, 0x15, 0x76, 0x2d, 0xf0}} 291 | LayerOutboundTransportV6Discard = LayerID{0xf433df69, 0xccbd, 0x482e, [8]byte{0xb9, 0xb2, 0x57, 0x16, 0x56, 0x58, 0xc3, 0xb3}} 292 | LayerRPCEPAdd = LayerID{0x618dffc7, 0xc450, 0x4943, [8]byte{0x95, 0xdb, 0x99, 0xb4, 0xc1, 0x6a, 0x55, 0xd4}} 293 | LayerRPCEPMap = LayerID{0x9247bc61, 0xeb07, 0x47ee, [8]byte{0x87, 0x2c, 0xbf, 0xd7, 0x8b, 0xfd, 0x16, 0x16}} 294 | LayerRPCProxyConn = LayerID{0x94a4b50b, 0xba5c, 0x4f27, [8]byte{0x90, 0x7a, 0x22, 0x9f, 0xac, 0x0c, 0x2a, 0x7a}} 295 | LayerRPCProxyIf = LayerID{0xf8a38615, 0xe12c, 0x41ac, [8]byte{0x98, 0xdf, 0x12, 0x1a, 0xd9, 0x81, 0xaa, 0xde}} 296 | LayerRPCUM = LayerID{0x75a89dda, 0x95e4, 0x40f3, [8]byte{0xad, 0xc7, 0x76, 0x88, 0xa9, 0xc8, 0x47, 0xe1}} 297 | LayerStreamPacketV4 = LayerID{0xaf52d8ec, 0xcb2d, 0x44e5, [8]byte{0xad, 0x92, 0xf8, 0xdc, 0x38, 0xd2, 0xeb, 0x29}} 298 | LayerStreamPacketV6 = LayerID{0x779a8ca3, 0xf099, 0x468f, [8]byte{0xb5, 0xd4, 0x83, 0x53, 0x5c, 0x46, 0x1c, 0x02}} 299 | LayerStreamV4 = LayerID{0x3b89653c, 0xc170, 0x49e4, [8]byte{0xb1, 0xcd, 0xe0, 0xee, 0xee, 0xe1, 0x9a, 0x3e}} 300 | LayerStreamV4Discard = LayerID{0x25c4c2c2, 0x25ff, 0x4352, [8]byte{0x82, 0xf9, 0xc5, 0x4a, 0x4a, 0x47, 0x26, 0xdc}} 301 | LayerStreamV6 = LayerID{0x47c9137a, 0x7ec4, 0x46b3, [8]byte{0xb6, 0xe4, 0x48, 0xe9, 0x26, 0xb1, 0xed, 0xa4}} 302 | LayerStreamV6Discard = LayerID{0x10a59fc7, 0xb628, 0x4c41, [8]byte{0x9e, 0xb8, 0xcf, 0x37, 0xd5, 0x51, 0x03, 0xcf}} 303 | ) 304 | 305 | // Well-known provider IDs. 306 | var ( 307 | guidProviderContextSecureSocketAuthIP = windows.GUID{0xb25ea800, 0x0d02, 0x46ed, [8]byte{0x92, 0xbd, 0x7f, 0xa8, 0x4b, 0xb7, 0x3e, 0x9d}} 308 | guidProviderContextSecureSocketIPSec = windows.GUID{0x8c2d4144, 0xf8e0, 0x42c0, [8]byte{0x94, 0xce, 0x7c, 0xcf, 0xc6, 0x3b, 0x2f, 0x9b}} 309 | guidProviderIKEExt = windows.GUID{0x10ad9216, 0xccde, 0x456c, [8]byte{0x8b, 0x16, 0xe9, 0xf0, 0x4e, 0x60, 0xa9, 0x0b}} 310 | guidProviderIPSecDospConfig = windows.GUID{0x3c6c05a9, 0xc05c, 0x4bb9, [8]byte{0x83, 0x38, 0x23, 0x27, 0x81, 0x4c, 0xe8, 0xbf}} 311 | guidProviderTCPChimneyOffload = windows.GUID{0x896aa19e, 0x9a34, 0x4bcb, [8]byte{0xae, 0x79, 0xbe, 0xb9, 0x12, 0x7c, 0x84, 0xb9}} 312 | guidProviderTCPTemplates = windows.GUID{0x76cfcd30, 0x3394, 0x432d, [8]byte{0xbe, 0xd3, 0x44, 0x1a, 0xe5, 0x0e, 0x63, 0xc3}} 313 | ) 314 | 315 | // Well-known sublayer IDs. 316 | var ( 317 | guidSublayerIPSecDosp = SublayerID{0xe076d572, 0x5d3d, 0x48ef, [8]byte{0x80, 0x2b, 0x90, 0x9e, 0xdd, 0xb0, 0x98, 0xbd}} 318 | guidSublayerIPSecForwardOutboundTunnel = SublayerID{0xa5082e73, 0x8f71, 0x4559, [8]byte{0x8a, 0x9a, 0x10, 0x1c, 0xea, 0x04, 0xef, 0x87}} 319 | guidSublayerIPSecSecurityRealm = SublayerID{0x37a57701, 0x5884, 0x4964, [8]byte{0x92, 0xb8, 0x3e, 0x70, 0x46, 0x88, 0xb0, 0xad}} 320 | guidSublayerIPSecTunnel = SublayerID{0x83f299ed, 0x9ff4, 0x4967, [8]byte{0xaf, 0xf4, 0xc3, 0x09, 0xf4, 0xda, 0xb8, 0x27}} 321 | guidSublayerInspection = SublayerID{0x877519e1, 0xe6a9, 0x41a5, [8]byte{0x81, 0xb4, 0x8c, 0x4f, 0x11, 0x8e, 0x4a, 0x60}} 322 | guidSublayerLIPS = SublayerID{0x1b75c0ce, 0xff60, 0x4711, [8]byte{0xa7, 0x0f, 0xb4, 0x95, 0x8c, 0xc3, 0xb2, 0xd0}} 323 | guidSublayerRPCAudit = SublayerID{0x758c84f4, 0xfb48, 0x4de9, [8]byte{0x9a, 0xeb, 0x3e, 0xd9, 0x55, 0x1a, 0xb1, 0xfd}} 324 | guidSublayerSecureSocket = SublayerID{0x15a66e17, 0x3f3c, 0x4f7b, [8]byte{0xaa, 0x6c, 0x81, 0x2a, 0xa6, 0x13, 0xdd, 0x82}} 325 | guidSublayerTCPChimneyOffload = SublayerID{0x337608b9, 0xb7d5, 0x4d5f, [8]byte{0x82, 0xf9, 0x36, 0x18, 0x61, 0x8b, 0xc0, 0x58}} 326 | guidSublayerTCPTemplates = SublayerID{0x24421dcf, 0x0ac5, 0x4caa, [8]byte{0x9e, 0x14, 0x50, 0xf6, 0xe3, 0x63, 0x6a, 0xf0}} 327 | guidSublayerTeredo = SublayerID{0xba69dc66, 0x5176, 0x4979, [8]byte{0x9c, 0x89, 0x26, 0xa7, 0xb4, 0x6a, 0x83, 0x27}} 328 | guidSublayerUniversal = SublayerID{0xeebecc03, 0xced4, 0x4380, [8]byte{0x81, 0x9a, 0x27, 0x34, 0x39, 0x7b, 0x2b, 0x74}} 329 | ) 330 | 331 | var guidNames = map[windows.GUID]string{ 332 | guidCalloutEdgeTraversalALEListenV4: "CALLOUT_EDGE_TRAVERSAL_ALE_LISTEN_V4", 333 | guidCalloutEdgeTraversalALEResourceAssignmentV4: "CALLOUT_EDGE_TRAVERSAL_ALE_RESOURCE_ASSIGNMENT_V4", 334 | guidCalloutHttpTemplateSslHandshake: "CALLOUT_HTTP_TEMPLATE_SSL_HANDSHAKE", 335 | guidCalloutIPSecALEConnectV4: "CALLOUT_IPSEC_ALE_CONNECT_V4", 336 | guidCalloutIPSecALEConnectV6: "CALLOUT_IPSEC_ALE_CONNECT_V6", 337 | guidCalloutIPSecDospForwardV4: "CALLOUT_IPSEC_DOSP_FORWARD_V4", 338 | guidCalloutIPSecDospForwardV6: "CALLOUT_IPSEC_DOSP_FORWARD_V6", 339 | guidCalloutIPSecForwardInboundTunnelV4: "CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4", 340 | guidCalloutIPSecForwardInboundTunnelV6: "CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6", 341 | guidCalloutIPSecForwardOutboundTunnelV4: "CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4", 342 | guidCalloutIPSecForwardOutboundTunnelV6: "CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6", 343 | guidCalloutIPSecInboundInitiateSecureV4: "CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V4", 344 | guidCalloutIPSecInboundInitiateSecureV6: "CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V6", 345 | guidCalloutIPSecInboundTransportV4: "CALLOUT_IPSEC_INBOUND_TRANSPORT_V4", 346 | guidCalloutIPSecInboundTransportV6: "CALLOUT_IPSEC_INBOUND_TRANSPORT_V6", 347 | guidCalloutIPSecInboundTunnelALEAcceptV4: "CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4", 348 | guidCalloutIPSecInboundTunnelALEAcceptV6: "CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6", 349 | guidCalloutIPSecInboundTunnelV4: "CALLOUT_IPSEC_INBOUND_TUNNEL_V4", 350 | guidCalloutIPSecInboundTunnelV6: "CALLOUT_IPSEC_INBOUND_TUNNEL_V6", 351 | guidCalloutIPSecOutboundTransportV4: "CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V4", 352 | guidCalloutIPSecOutboundTransportV6: "CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V6", 353 | guidCalloutIPSecOutboundTunnelV4: "CALLOUT_IPSEC_OUTBOUND_TUNNEL_V4", 354 | guidCalloutIPSecOutboundTunnelV6: "CALLOUT_IPSEC_OUTBOUND_TUNNEL_V6", 355 | guidCalloutPolicySilentModeAuthConnectLayerV4: "CALLOUT_POLICY_SILENT_MODE_AUTH_CONNECT_LAYER_V4", 356 | guidCalloutPolicySilentModeAuthConnectLayerV6: "CALLOUT_POLICY_SILENT_MODE_AUTH_CONNECT_LAYER_V6", 357 | guidCalloutPolicySilentModeAuthRecvAcceptLayerV4: "CALLOUT_POLICY_SILENT_MODE_AUTH_RECV_ACCEPT_LAYER_V4", 358 | guidCalloutPolicySilentModeAuthRecvAcceptLayerV6: "CALLOUT_POLICY_SILENT_MODE_AUTH_RECV_ACCEPT_LAYER_V6", 359 | guidCalloutReservedAuthConnectLayerV4: "CALLOUT_RESERVED_AUTH_CONNECT_LAYER_V4", 360 | guidCalloutReservedAuthConnectLayerV6: "CALLOUT_RESERVED_AUTH_CONNECT_LAYER_V6", 361 | guidCalloutSetOptionsAuthConnectLayerV4: "CALLOUT_SET_OPTIONS_AUTH_CONNECT_LAYER_V4", 362 | guidCalloutSetOptionsAuthConnectLayerV6: "CALLOUT_SET_OPTIONS_AUTH_CONNECT_LAYER_V6", 363 | guidCalloutSetOptionsAuthRecvAcceptLayerV4: "CALLOUT_SET_OPTIONS_AUTH_RECV_ACCEPT_LAYER_V4", 364 | guidCalloutSetOptionsAuthRecvAcceptLayerV6: "CALLOUT_SET_OPTIONS_AUTH_RECV_ACCEPT_LAYER_V6", 365 | guidCalloutTCPChimneyAcceptLayerV4: "CALLOUT_TCP_CHIMNEY_ACCEPT_LAYER_V4", 366 | guidCalloutTCPChimneyAcceptLayerV6: "CALLOUT_TCP_CHIMNEY_ACCEPT_LAYER_V6", 367 | guidCalloutTCPChimneyConnectLayerV4: "CALLOUT_TCP_CHIMNEY_CONNECT_LAYER_V4", 368 | guidCalloutTCPChimneyConnectLayerV6: "CALLOUT_TCP_CHIMNEY_CONNECT_LAYER_V6", 369 | guidCalloutTCPTemplatesAcceptLayerV4: "CALLOUT_TCP_TEMPLATES_ACCEPT_LAYER_V4", 370 | guidCalloutTCPTemplatesAcceptLayerV6: "CALLOUT_TCP_TEMPLATES_ACCEPT_LAYER_V6", 371 | guidCalloutTCPTemplatesConnectLayerV4: "CALLOUT_TCP_TEMPLATES_CONNECT_LAYER_V4", 372 | guidCalloutTCPTemplatesConnectLayerV6: "CALLOUT_TCP_TEMPLATES_CONNECT_LAYER_V6", 373 | guidCalloutTeredoALEListenV6: "CALLOUT_TEREDO_ALE_LISTEN_V6", 374 | guidCalloutTeredoALEResourceAssignmentV6: "CALLOUT_TEREDO_ALE_RESOURCE_ASSIGNMENT_V6", 375 | guidCalloutWFPTransportLayerV4SilentDrop: "CALLOUT_WFP_TRANSPORT_LAYER_V4_SILENT_DROP", 376 | guidCalloutWFPTransportLayerV6SilentDrop: "CALLOUT_WFP_TRANSPORT_LAYER_V6_SILENT_DROP", 377 | windows.GUID(FieldALEAppID): "ALE_APP_ID", 378 | windows.GUID(FieldALEEffectiveName): "ALE_EFFECTIVE_NAME", 379 | windows.GUID(FieldALENAPContext): "ALE_NAP_CONTEXT", 380 | windows.GUID(FieldALEOriginalAppID): "ALE_ORIGINAL_APP_ID", 381 | windows.GUID(FieldALEPackageID): "ALE_PACKAGE_ID", 382 | windows.GUID(FieldALEPromiscuousMode): "ALE_PROMISCUOUS_MODE", 383 | windows.GUID(FieldALEReauthReason): "ALE_REAUTH_REASON", 384 | windows.GUID(FieldALERemoteMachineID): "ALE_REMOTE_MACHINE_ID", 385 | windows.GUID(FieldALERemoteUserID): "ALE_REMOTE_USER_ID", 386 | windows.GUID(FieldALESecurityAttributeFqbnValue): "ALE_SECURITY_ATTRIBUTE_FQBN_VALUE", 387 | windows.GUID(FieldALESioFirewallSystemPort): "ALE_SIO_FIREWALL_SYSTEM_PORT", 388 | windows.GUID(FieldALEUserID): "ALE_USER_ID", 389 | windows.GUID(FieldArrivalInterfaceIndex): "ARRIVAL_INTERFACE_INDEX", 390 | windows.GUID(FieldArrivalInterfaceProfileID): "ARRIVAL_INTERFACE_PROFILE_ID", 391 | windows.GUID(FieldArrivalInterfaceType): "ARRIVAL_INTERFACE_TYPE", 392 | windows.GUID(FieldArrivalTunnelType): "ARRIVAL_TUNNEL_TYPE", 393 | windows.GUID(FieldAuthenticationType): "AUTHENTICATION_TYPE", 394 | windows.GUID(FieldBitmapIndexKey): "BITMAP_INDEX_KEY", 395 | windows.GUID(FieldBitmapIPLocalAddress): "BITMAP_IP_LOCAL_ADDRESS", 396 | windows.GUID(FieldBitmapIPLocalPort): "BITMAP_IP_LOCAL_PORT", 397 | windows.GUID(FieldBitmapIPRemoteAddress): "BITMAP_IP_REMOTE_ADDRESS", 398 | windows.GUID(FieldBitmapIPRemotePort): "BITMAP_IP_REMOTE_PORT", 399 | windows.GUID(FieldClientCertKeyLength): "CLIENT_CERT_KEY_LENGTH", 400 | windows.GUID(FieldClientCertOid): "CLIENT_CERT_OID", 401 | windows.GUID(FieldClientToken): "CLIENT_TOKEN", 402 | windows.GUID(FieldCompartmentID): "COMPARTMENT_ID", 403 | windows.GUID(FieldCurrentProfileID): "CURRENT_PROFILE_ID", 404 | windows.GUID(FieldDCOMAppID): "DCOM_APP_ID", 405 | windows.GUID(FieldDestinationInterfaceIndex): "DESTINATION_INTERFACE_INDEX", 406 | windows.GUID(FieldDestinationSubInterfaceIndex): "DESTINATION_SUB_INTERFACE_INDEX", 407 | windows.GUID(FieldDirection): "DIRECTION", 408 | windows.GUID(FieldEmbeddedLocalAddressType): "EMBEDDED_LOCAL_ADDRESS_TYPE", 409 | windows.GUID(FieldEmbeddedLocalPort): "EMBEDDED_LOCAL_PORT", 410 | windows.GUID(FieldEmbeddedProtocol): "EMBEDDED_PROTOCOL", 411 | windows.GUID(FieldEmbeddedRemoteAddress): "EMBEDDED_REMOTE_ADDRESS", 412 | windows.GUID(FieldEmbeddedRemotePort): "EMBEDDED_REMOTE_PORT", 413 | windows.GUID(FieldEtherType): "ETHER_TYPE", 414 | windows.GUID(FieldFlags): "FLAGS", 415 | windows.GUID(FieldImageName): "IMAGE_NAME", 416 | windows.GUID(FieldInterfaceIndex): "INTERFACE_INDEX", 417 | windows.GUID(FieldInterfaceMACAddress): "INTERFACE_MAC_ADDRESS", 418 | windows.GUID(FieldInterfaceQuarantineEpoch): "INTERFACE_QUARANTINE_EPOCH", 419 | windows.GUID(FieldInterfaceType): "INTERFACE_TYPE", 420 | windows.GUID(FieldIPSecPolicyKey): "IPSEC_POLICY_KEY", 421 | windows.GUID(FieldIPSecSecurityRealmID): "IPSEC_SECURITY_REALM_ID", 422 | windows.GUID(FieldIPArrivalInterface): "IP_ARRIVAL_INTERFACE", 423 | windows.GUID(FieldIPDestinationAddress): "IP_DESTINATION_ADDRESS", 424 | windows.GUID(FieldIPDestinationAddressType): "IP_DESTINATION_ADDRESS_TYPE", 425 | windows.GUID(FieldIPDestinationPort): "IP_DESTINATION_PORT", 426 | windows.GUID(FieldIPForwardInterface): "IP_FORWARD_INTERFACE", 427 | windows.GUID(FieldIPLocalAddress): "IP_LOCAL_ADDRESS", 428 | windows.GUID(FieldIPLocalAddressType): "IP_LOCAL_ADDRESS_TYPE", 429 | windows.GUID(FieldIPLocalAddressV4): "IP_LOCAL_ADDRESS_V4", 430 | windows.GUID(FieldIPLocalAddressV6): "IP_LOCAL_ADDRESS_V6", 431 | windows.GUID(FieldIPLocalInterface): "IP_LOCAL_INTERFACE", 432 | windows.GUID(FieldIPLocalPort): "IP_LOCAL_PORT", 433 | windows.GUID(FieldIPNexthopAddress): "IP_NEXTHOP_ADDRESS", 434 | windows.GUID(FieldIPNexthopInterface): "IP_NEXTHOP_INTERFACE", 435 | windows.GUID(FieldIPPhysicalArrivalInterface): "IP_PHYSICAL_ARRIVAL_INTERFACE", 436 | windows.GUID(FieldIPPhysicalNexthopInterface): "IP_PHYSICAL_NEXTHOP_INTERFACE", 437 | windows.GUID(FieldIPProtocol): "IP_PROTOCOL", 438 | windows.GUID(FieldIPRemoteAddress): "IP_REMOTE_ADDRESS", 439 | windows.GUID(FieldIPRemoteAddressV4): "IP_REMOTE_ADDRESS_V4", 440 | windows.GUID(FieldIPRemoteAddressV6): "IP_REMOTE_ADDRESS_V6", 441 | windows.GUID(FieldIPRemotePort): "IP_REMOTE_PORT", 442 | windows.GUID(FieldIPSourceAddress): "IP_SOURCE_ADDRESS", 443 | windows.GUID(FieldIPSourcePort): "IP_SOURCE_PORT", 444 | windows.GUID(FieldKMAuthNAPContext): "KM_AUTH_NAP_CONTEXT", 445 | windows.GUID(FieldKMMode): "KM_MODE", 446 | windows.GUID(FieldKMType): "KM_TYPE", 447 | windows.GUID(FieldL2Flags): "L2_FLAGS", 448 | windows.GUID(FieldLocalInterfaceProfileID): "LOCAL_INTERFACE_PROFILE_ID", 449 | windows.GUID(FieldMACDestinationAddress): "MAC_DESTINATION_ADDRESS", 450 | windows.GUID(FieldMACDestinationAddressType): "MAC_DESTINATION_ADDRESS_TYPE", 451 | windows.GUID(FieldMACLocalAddress): "MAC_LOCAL_ADDRESS", 452 | windows.GUID(FieldMACLocalAddressType): "MAC_LOCAL_ADDRESS_TYPE", 453 | windows.GUID(FieldMACRemoteAddress): "MAC_REMOTE_ADDRESS", 454 | windows.GUID(FieldMACRemoteAddressType): "MAC_REMOTE_ADDRESS_TYPE", 455 | windows.GUID(FieldMACSourceAddress): "MAC_SOURCE_ADDRESS", 456 | windows.GUID(FieldMACSourceAddressType): "MAC_SOURCE_ADDRESS_TYPE", 457 | windows.GUID(FieldNdisMediaType): "NDIS_MEDIA_TYPE", 458 | windows.GUID(FieldNdisPhysicalMediaType): "NDIS_PHYSICAL_MEDIA_TYPE", 459 | windows.GUID(FieldNdisPort): "NDIS_PORT", 460 | windows.GUID(FieldNetEventType): "NET_EVENT_TYPE", 461 | windows.GUID(FieldNexthopInterfaceIndex): "NEXTHOP_INTERFACE_INDEX", 462 | windows.GUID(FieldNexthopInterfaceProfileID): "NEXTHOP_INTERFACE_PROFILE_ID", 463 | windows.GUID(FieldNexthopInterfaceType): "NEXTHOP_INTERFACE_TYPE", 464 | windows.GUID(FieldNexthopSubInterfaceIndex): "NEXTHOP_SUB_INTERFACE_INDEX", 465 | windows.GUID(FieldNexthopTunnelType): "NEXTHOP_TUNNEL_TYPE", 466 | windows.GUID(FieldOriginalICMPType): "ORIGINAL_ICMP_TYPE", 467 | windows.GUID(FieldOriginalProfileID): "ORIGINAL_PROFILE_ID", 468 | windows.GUID(FieldPeerName): "PEER_NAME", 469 | windows.GUID(FieldPipe): "PIPE", 470 | windows.GUID(FieldProcessWithRPCIfUUID): "PROCESS_WITH_RPC_IF_UUID", 471 | windows.GUID(FieldQMMode): "QM_MODE", 472 | windows.GUID(FieldReauthorizeReason): "REAUTHORIZE_REASON", 473 | windows.GUID(FieldRemoteID): "REMOTE_ID", 474 | windows.GUID(FieldRemoteUserToken): "REMOTE_USER_TOKEN", 475 | windows.GUID(FieldReserved0): "RESERVED0", 476 | windows.GUID(FieldReserved1): "RESERVED1", 477 | windows.GUID(FieldReserved10): "RESERVED10", 478 | windows.GUID(FieldReserved11): "RESERVED11", 479 | windows.GUID(FieldReserved12): "RESERVED12", 480 | windows.GUID(FieldReserved13): "RESERVED13", 481 | windows.GUID(FieldReserved14): "RESERVED14", 482 | windows.GUID(FieldReserved15): "RESERVED15", 483 | windows.GUID(FieldReserved2): "RESERVED2", 484 | windows.GUID(FieldReserved3): "RESERVED3", 485 | windows.GUID(FieldReserved4): "RESERVED4", 486 | windows.GUID(FieldReserved5): "RESERVED5", 487 | windows.GUID(FieldReserved6): "RESERVED6", 488 | windows.GUID(FieldReserved7): "RESERVED7", 489 | windows.GUID(FieldReserved8): "RESERVED8", 490 | windows.GUID(FieldReserved9): "RESERVED9", 491 | windows.GUID(FieldRPCAuthLevel): "RPC_AUTH_LEVEL", 492 | windows.GUID(FieldRPCAuthType): "RPC_AUTH_TYPE", 493 | windows.GUID(FieldRPCEPFlags): "RPC_EP_FLAGS", 494 | windows.GUID(FieldRPCEPValue): "RPC_EP_VALUE", 495 | windows.GUID(FieldRPCIfFlag): "RPC_IF_FLAG", 496 | windows.GUID(FieldRPCIfUUID): "RPC_IF_UUID", 497 | windows.GUID(FieldRPCIfVersion): "RPC_IF_VERSION", 498 | windows.GUID(FieldRPCProtocol): "RPC_PROTOCOL", 499 | windows.GUID(FieldRPCProxyAuthType): "RPC_PROXY_AUTH_TYPE", 500 | windows.GUID(FieldRPCServerName): "RPC_SERVER_NAME", 501 | windows.GUID(FieldRPCServerPort): "RPC_SERVER_PORT", 502 | windows.GUID(FieldSecEncryptAlgorithm): "SEC_ENCRYPT_ALGORITHM", 503 | windows.GUID(FieldSecKeySize): "SEC_KEY_SIZE", 504 | windows.GUID(FieldSourceInterfaceIndex): "SOURCE_INTERFACE_INDEX", 505 | windows.GUID(FieldSourceSubInterfaceIndex): "SOURCE_SUB_INTERFACE_INDEX", 506 | windows.GUID(FieldSubInterfaceIndex): "SUB_INTERFACE_INDEX", 507 | windows.GUID(FieldTunnelType): "TUNNEL_TYPE", 508 | windows.GUID(FieldVLANID): "VLAN_ID", 509 | windows.GUID(FieldVSwitchDestinationInterfaceID): "VSWITCH_DESTINATION_INTERFACE_ID", 510 | windows.GUID(FieldVSwitchDestinationInterfaceType): "VSWITCH_DESTINATION_INTERFACE_TYPE", 511 | windows.GUID(FieldVSwitchDestinationVmID): "VSWITCH_DESTINATION_VM_ID", 512 | windows.GUID(FieldVSwitchID): "VSWITCH_ID", 513 | windows.GUID(FieldVSwitchNetworkType): "VSWITCH_NETWORK_TYPE", 514 | windows.GUID(FieldVSwitchSourceInterfaceID): "VSWITCH_SOURCE_INTERFACE_ID", 515 | windows.GUID(FieldVSwitchSourceInterfaceType): "VSWITCH_SOURCE_INTERFACE_TYPE", 516 | windows.GUID(FieldVSwitchSourceVmID): "VSWITCH_SOURCE_VM_ID", 517 | windows.GUID(FieldVSwitchTenantNetworkID): "VSWITCH_TENANT_NETWORK_ID", 518 | guidKeyingModuleAuthIP: "KEYING_MODULE_AUTHIP", 519 | guidKeyingModuleIKE: "KEYING_MODULE_IKE", 520 | guidKeyingModuleIKEv2: "KEYING_MODULE_IKEV2", 521 | windows.GUID(LayerALEAuthConnectV4): "ALE_AUTH_CONNECT_V4", 522 | windows.GUID(LayerALEAuthConnectV4Discard): "ALE_AUTH_CONNECT_V4_DISCARD", 523 | windows.GUID(LayerALEAuthConnectV6): "ALE_AUTH_CONNECT_V6", 524 | windows.GUID(LayerALEAuthConnectV6Discard): "ALE_AUTH_CONNECT_V6_DISCARD", 525 | windows.GUID(LayerALEAuthListenV4): "ALE_AUTH_LISTEN_V4", 526 | windows.GUID(LayerALEAuthListenV4Discard): "ALE_AUTH_LISTEN_V4_DISCARD", 527 | windows.GUID(LayerALEAuthListenV6): "ALE_AUTH_LISTEN_V6", 528 | windows.GUID(LayerALEAuthListenV6Discard): "ALE_AUTH_LISTEN_V6_DISCARD", 529 | windows.GUID(LayerALEAuthRecvAcceptV4): "ALE_AUTH_RECV_ACCEPT_V4", 530 | windows.GUID(LayerALEAuthRecvAcceptV4Discard): "ALE_AUTH_RECV_ACCEPT_V4_DISCARD", 531 | windows.GUID(LayerALEAuthRecvAcceptV6): "ALE_AUTH_RECV_ACCEPT_V6", 532 | windows.GUID(LayerALEAuthRecvAcceptV6Discard): "ALE_AUTH_RECV_ACCEPT_V6_DISCARD", 533 | windows.GUID(LayerALEBindRedirectV4): "ALE_BIND_REDIRECT_V4", 534 | windows.GUID(LayerALEBindRedirectV6): "ALE_BIND_REDIRECT_V6", 535 | windows.GUID(LayerALEConnectRedirectV4): "ALE_CONNECT_REDIRECT_V4", 536 | windows.GUID(LayerALEConnectRedirectV6): "ALE_CONNECT_REDIRECT_V6", 537 | windows.GUID(LayerALEEndpointClosureV4): "ALE_ENDPOINT_CLOSURE_V4", 538 | windows.GUID(LayerALEEndpointClosureV6): "ALE_ENDPOINT_CLOSURE_V6", 539 | windows.GUID(LayerALEFlowEstablishedV4): "ALE_FLOW_ESTABLISHED_V4", 540 | windows.GUID(LayerALEFlowEstablishedV4Discard): "ALE_FLOW_ESTABLISHED_V4_DISCARD", 541 | windows.GUID(LayerALEFlowEstablishedV6): "ALE_FLOW_ESTABLISHED_V6", 542 | windows.GUID(LayerALEFlowEstablishedV6Discard): "ALE_FLOW_ESTABLISHED_V6_DISCARD", 543 | windows.GUID(LayerALEResourceAssignmentV4): "ALE_RESOURCE_ASSIGNMENT_V4", 544 | windows.GUID(LayerALEResourceAssignmentV4Discard): "ALE_RESOURCE_ASSIGNMENT_V4_DISCARD", 545 | windows.GUID(LayerALEResourceAssignmentV6): "ALE_RESOURCE_ASSIGNMENT_V6", 546 | windows.GUID(LayerALEResourceAssignmentV6Discard): "ALE_RESOURCE_ASSIGNMENT_V6_DISCARD", 547 | windows.GUID(LayerALEResourceReleaseV4): "ALE_RESOURCE_RELEASE_V4", 548 | windows.GUID(LayerALEResourceReleaseV6): "ALE_RESOURCE_RELEASE_V6", 549 | windows.GUID(LayerDatagramDataV4): "DATAGRAM_DATA_V4", 550 | windows.GUID(LayerDatagramDataV4Discard): "DATAGRAM_DATA_V4_DISCARD", 551 | windows.GUID(LayerDatagramDataV6): "DATAGRAM_DATA_V6", 552 | windows.GUID(LayerDatagramDataV6Discard): "DATAGRAM_DATA_V6_DISCARD", 553 | windows.GUID(LayerEgressVSwitchEthernet): "EGRESS_VSWITCH_ETHERNET", 554 | windows.GUID(LayerEgressVSwitchTransportV4): "EGRESS_VSWITCH_TRANSPORT_V4", 555 | windows.GUID(LayerEgressVSwitchTransportV6): "EGRESS_VSWITCH_TRANSPORT_V6", 556 | windows.GUID(LayerIKEExtV4): "IKEEXT_V4", 557 | windows.GUID(LayerIKEExtV6): "IKEEXT_V6", 558 | windows.GUID(LayerInboundICMPErrorV4): "INBOUND_ICMP_ERROR_V4", 559 | windows.GUID(LayerInboundICMPErrorV4Discard): "INBOUND_ICMP_ERROR_V4_DISCARD", 560 | windows.GUID(LayerInboundICMPErrorV6): "INBOUND_ICMP_ERROR_V6", 561 | windows.GUID(LayerInboundICMPErrorV6Discard): "INBOUND_ICMP_ERROR_V6_DISCARD", 562 | windows.GUID(LayerInboundIPPacketV4): "INBOUND_IPPACKET_V4", 563 | windows.GUID(LayerInboundIPPacketV4Discard): "INBOUND_IPPACKET_V4_DISCARD", 564 | windows.GUID(LayerInboundIPPacketV6): "INBOUND_IPPACKET_V6", 565 | windows.GUID(LayerInboundIPPacketV6Discard): "INBOUND_IPPACKET_V6_DISCARD", 566 | windows.GUID(LayerInboundMACFrameEthernet): "INBOUND_MAC_FRAME_ETHERNET", 567 | windows.GUID(LayerInboundMACFrameNative): "INBOUND_MAC_FRAME_NATIVE", 568 | windows.GUID(LayerInboundMACFrameNativeFast): "INBOUND_MAC_FRAME_NATIVE_FAST", 569 | windows.GUID(LayerInboundReserved2): "INBOUND_RESERVED2", 570 | windows.GUID(LayerInboundTransportFast): "INBOUND_TRANSPORT_FAST", 571 | windows.GUID(LayerInboundTransportV4): "INBOUND_TRANSPORT_V4", 572 | windows.GUID(LayerInboundTransportV4Discard): "INBOUND_TRANSPORT_V4_DISCARD", 573 | windows.GUID(LayerInboundTransportV6): "INBOUND_TRANSPORT_V6", 574 | windows.GUID(LayerInboundTransportV6Discard): "INBOUND_TRANSPORT_V6_DISCARD", 575 | windows.GUID(LayerIngressVSwitchEthernet): "INGRESS_VSWITCH_ETHERNET", 576 | windows.GUID(LayerIngressVSwitchTransportV4): "INGRESS_VSWITCH_TRANSPORT_V4", 577 | windows.GUID(LayerIngressVSwitchTransportV6): "INGRESS_VSWITCH_TRANSPORT_V6", 578 | windows.GUID(LayerIPForwardV4): "IPFORWARD_V4", 579 | windows.GUID(LayerIPForwardV4Discard): "IPFORWARD_V4_DISCARD", 580 | windows.GUID(LayerIPForwardV6): "IPFORWARD_V6", 581 | windows.GUID(LayerIPForwardV6Discard): "IPFORWARD_V6_DISCARD", 582 | windows.GUID(LayerIPSecKMDemuxV4): "IPSEC_KM_DEMUX_V4", 583 | windows.GUID(LayerIPSecKMDemuxV6): "IPSEC_KM_DEMUX_V6", 584 | windows.GUID(LayerIPSecV4): "IPSEC_V4", 585 | windows.GUID(LayerIPSecV6): "IPSEC_V6", 586 | windows.GUID(LayerKMAuthorization): "KM_AUTHORIZATION", 587 | windows.GUID(LayerNameResolutionCacheV4): "NAME_RESOLUTION_CACHE_V4", 588 | windows.GUID(LayerNameResolutionCacheV6): "NAME_RESOLUTION_CACHE_V6", 589 | windows.GUID(LayerOutboundICMPErrorV4): "OUTBOUND_ICMP_ERROR_V4", 590 | windows.GUID(LayerOutboundICMPErrorV4Discard): "OUTBOUND_ICMP_ERROR_V4_DISCARD", 591 | windows.GUID(LayerOutboundICMPErrorV6): "OUTBOUND_ICMP_ERROR_V6", 592 | windows.GUID(LayerOutboundICMPErrorV6Discard): "OUTBOUND_ICMP_ERROR_V6_DISCARD", 593 | windows.GUID(LayerOutboundIPPacketV4): "OUTBOUND_IPPACKET_V4", 594 | windows.GUID(LayerOutboundIPPacketV4Discard): "OUTBOUND_IPPACKET_V4_DISCARD", 595 | windows.GUID(LayerOutboundIPPacketV6): "OUTBOUND_IPPACKET_V6", 596 | windows.GUID(LayerOutboundIPPacketV6Discard): "OUTBOUND_IPPACKET_V6_DISCARD", 597 | windows.GUID(LayerOutboundMACFrameEthernet): "OUTBOUND_MAC_FRAME_ETHERNET", 598 | windows.GUID(LayerOutboundMACFrameNative): "OUTBOUND_MAC_FRAME_NATIVE", 599 | windows.GUID(LayerOutboundMACFrameNativeFast): "OUTBOUND_MAC_FRAME_NATIVE_FAST", 600 | windows.GUID(LayerOutboundTransportFast): "OUTBOUND_TRANSPORT_FAST", 601 | windows.GUID(LayerOutboundTransportV4): "OUTBOUND_TRANSPORT_V4", 602 | windows.GUID(LayerOutboundTransportV4Discard): "OUTBOUND_TRANSPORT_V4_DISCARD", 603 | windows.GUID(LayerOutboundTransportV6): "OUTBOUND_TRANSPORT_V6", 604 | windows.GUID(LayerOutboundTransportV6Discard): "OUTBOUND_TRANSPORT_V6_DISCARD", 605 | windows.GUID(LayerRPCEPMap): "RPC_EPMAP", 606 | windows.GUID(LayerRPCEPAdd): "RPC_EP_ADD", 607 | windows.GUID(LayerRPCProxyConn): "RPC_PROXY_CONN", 608 | windows.GUID(LayerRPCProxyIf): "RPC_PROXY_IF", 609 | windows.GUID(LayerRPCUM): "RPC_UM", 610 | windows.GUID(LayerStreamPacketV4): "STREAM_PACKET_V4", 611 | windows.GUID(LayerStreamPacketV6): "STREAM_PACKET_V6", 612 | windows.GUID(LayerStreamV4): "STREAM_V4", 613 | windows.GUID(LayerStreamV4Discard): "STREAM_V4_DISCARD", 614 | windows.GUID(LayerStreamV6): "STREAM_V6", 615 | windows.GUID(LayerStreamV6Discard): "STREAM_V6_DISCARD", 616 | guidProviderContextSecureSocketAuthIP: "PROVIDER_CONTEXT_SECURE_SOCKET_AUTHIP", 617 | guidProviderContextSecureSocketIPSec: "PROVIDER_CONTEXT_SECURE_SOCKET_IPSEC", 618 | guidProviderIKEExt: "PROVIDER_IKEEXT", 619 | guidProviderIPSecDospConfig: "PROVIDER_IPSEC_DOSP_CONFIG", 620 | guidProviderTCPChimneyOffload: "PROVIDER_TCP_CHIMNEY_OFFLOAD", 621 | guidProviderTCPTemplates: "PROVIDER_TCP_TEMPLATES", 622 | windows.GUID(guidSublayerInspection): "SUBLAYER_INSPECTION", 623 | windows.GUID(guidSublayerIPSecDosp): "SUBLAYER_IPSEC_DOSP", 624 | windows.GUID(guidSublayerIPSecForwardOutboundTunnel): "SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL", 625 | windows.GUID(guidSublayerIPSecSecurityRealm): "SUBLAYER_IPSEC_SECURITY_REALM", 626 | windows.GUID(guidSublayerIPSecTunnel): "SUBLAYER_IPSEC_TUNNEL", 627 | windows.GUID(guidSublayerLIPS): "SUBLAYER_LIPS", 628 | windows.GUID(guidSublayerRPCAudit): "SUBLAYER_RPC_AUDIT", 629 | windows.GUID(guidSublayerSecureSocket): "SUBLAYER_SECURE_SOCKET", 630 | windows.GUID(guidSublayerTCPChimneyOffload): "SUBLAYER_TCP_CHIMNEY_OFFLOAD", 631 | windows.GUID(guidSublayerTCPTemplates): "SUBLAYER_TCP_TEMPLATES", 632 | windows.GUID(guidSublayerTeredo): "SUBLAYER_TEREDO", 633 | windows.GUID(guidSublayerUniversal): "SUBLAYER_UNIVERSAL", 634 | } 635 | -------------------------------------------------------------------------------- /zipproto_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zipproto_strings.go -type=IPProto -trimprefix=IPProto"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[IPProtoICMP-1] 12 | _ = x[IPProtoICMPV6-58] 13 | _ = x[IPProtoTCP-6] 14 | _ = x[IPProtoUDP-17] 15 | } 16 | 17 | const ( 18 | _IPProto_name_0 = "ICMP" 19 | _IPProto_name_1 = "TCP" 20 | _IPProto_name_2 = "UDP" 21 | _IPProto_name_3 = "ICMPV6" 22 | ) 23 | 24 | func (i IPProto) String() string { 25 | switch { 26 | case i == 1: 27 | return _IPProto_name_0 28 | case i == 6: 29 | return _IPProto_name_1 30 | case i == 17: 31 | return _IPProto_name_2 32 | case i == 58: 33 | return _IPProto_name_3 34 | default: 35 | return "IPProto(" + strconv.FormatInt(int64(i), 10) + ")" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /zproviderflags_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zproviderflags_strings.go -type=fwpmProviderFlags -trimprefix=fwpmProviderFlags"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[fwpmProviderFlagsPersistent-1] 12 | _ = x[fwpmProviderFlagsDisabled-16] 13 | } 14 | 15 | const ( 16 | _fwpmProviderFlags_name_0 = "Persistent" 17 | _fwpmProviderFlags_name_1 = "Disabled" 18 | ) 19 | 20 | func (i fwpmProviderFlags) String() string { 21 | switch { 22 | case i == 1: 23 | return _fwpmProviderFlags_name_0 24 | case i == 16: 25 | return _fwpmProviderFlags_name_1 26 | default: 27 | return "fwpmProviderFlags(" + strconv.FormatInt(int64(i), 10) + ")" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /zsublayerflags_strings.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -output=zsublayerflags_strings.go -type=fwpmSublayerFlags -trimprefix=fwpmSublayerFlags"; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[fwpmSublayerFlagsPersistent-1] 12 | } 13 | 14 | const _fwpmSublayerFlags_name = "Persistent" 15 | 16 | var _fwpmSublayerFlags_index = [...]uint8{0, 10} 17 | 18 | func (i fwpmSublayerFlags) String() string { 19 | i -= 1 20 | if i >= fwpmSublayerFlags(len(_fwpmSublayerFlags_index)-1) { 21 | return "fwpmSublayerFlags(" + strconv.FormatInt(int64(i+1), 10) + ")" 22 | } 23 | return _fwpmSublayerFlags_name[_fwpmSublayerFlags_index[i]:_fwpmSublayerFlags_index[i+1]] 24 | } 25 | -------------------------------------------------------------------------------- /zsyscall_windows.go: -------------------------------------------------------------------------------- 1 | // Code generated by 'go generate'; DO NOT EDIT. 2 | 3 | package wf 4 | 5 | import ( 6 | "syscall" 7 | "unsafe" 8 | 9 | "golang.org/x/sys/windows" 10 | ) 11 | 12 | var _ unsafe.Pointer 13 | 14 | // Do the interface allocations only once for common 15 | // Errno values. 16 | const ( 17 | errnoERROR_IO_PENDING = 997 18 | ) 19 | 20 | var ( 21 | errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) 22 | errERROR_EINVAL error = syscall.EINVAL 23 | ) 24 | 25 | // errnoErr returns common boxed Errno values, to prevent 26 | // allocations at runtime. 27 | func errnoErr(e syscall.Errno) error { 28 | switch e { 29 | case 0: 30 | return errERROR_EINVAL 31 | case errnoERROR_IO_PENDING: 32 | return errERROR_IO_PENDING 33 | } 34 | // TODO: add more here, after collecting data on the common 35 | // error values see on Windows. (perhaps when running 36 | // all.bat?) 37 | return e 38 | } 39 | 40 | var ( 41 | modfwpuclnt = windows.NewLazySystemDLL("fwpuclnt.dll") 42 | 43 | procFwpmEngineClose0 = modfwpuclnt.NewProc("FwpmEngineClose0") 44 | procFwpmEngineOpen0 = modfwpuclnt.NewProc("FwpmEngineOpen0") 45 | procFwpmFilterAdd0 = modfwpuclnt.NewProc("FwpmFilterAdd0") 46 | procFwpmFilterCreateEnumHandle0 = modfwpuclnt.NewProc("FwpmFilterCreateEnumHandle0") 47 | procFwpmFilterDeleteByKey0 = modfwpuclnt.NewProc("FwpmFilterDeleteByKey0") 48 | procFwpmFilterDestroyEnumHandle0 = modfwpuclnt.NewProc("FwpmFilterDestroyEnumHandle0") 49 | procFwpmFilterEnum0 = modfwpuclnt.NewProc("FwpmFilterEnum0") 50 | procFwpmFreeMemory0 = modfwpuclnt.NewProc("FwpmFreeMemory0") 51 | procFwpmGetAppIdFromFileName0 = modfwpuclnt.NewProc("FwpmGetAppIdFromFileName0") 52 | procFwpmLayerCreateEnumHandle0 = modfwpuclnt.NewProc("FwpmLayerCreateEnumHandle0") 53 | procFwpmLayerDestroyEnumHandle0 = modfwpuclnt.NewProc("FwpmLayerDestroyEnumHandle0") 54 | procFwpmLayerEnum0 = modfwpuclnt.NewProc("FwpmLayerEnum0") 55 | procFwpmNetEventCreateEnumHandle0 = modfwpuclnt.NewProc("FwpmNetEventCreateEnumHandle0") 56 | procFwpmNetEventDestroyEnumHandle0 = modfwpuclnt.NewProc("FwpmNetEventDestroyEnumHandle0") 57 | procFwpmNetEventEnum1 = modfwpuclnt.NewProc("FwpmNetEventEnum1") 58 | procFwpmProviderAdd0 = modfwpuclnt.NewProc("FwpmProviderAdd0") 59 | procFwpmProviderCreateEnumHandle0 = modfwpuclnt.NewProc("FwpmProviderCreateEnumHandle0") 60 | procFwpmProviderDeleteByKey0 = modfwpuclnt.NewProc("FwpmProviderDeleteByKey0") 61 | procFwpmProviderDestroyEnumHandle0 = modfwpuclnt.NewProc("FwpmProviderDestroyEnumHandle0") 62 | procFwpmProviderEnum0 = modfwpuclnt.NewProc("FwpmProviderEnum0") 63 | procFwpmSubLayerAdd0 = modfwpuclnt.NewProc("FwpmSubLayerAdd0") 64 | procFwpmSubLayerCreateEnumHandle0 = modfwpuclnt.NewProc("FwpmSubLayerCreateEnumHandle0") 65 | procFwpmSubLayerDeleteByKey0 = modfwpuclnt.NewProc("FwpmSubLayerDeleteByKey0") 66 | procFwpmSubLayerDestroyEnumHandle0 = modfwpuclnt.NewProc("FwpmSubLayerDestroyEnumHandle0") 67 | procFwpmSubLayerEnum0 = modfwpuclnt.NewProc("FwpmSubLayerEnum0") 68 | procFwpmTransactionAbort0 = modfwpuclnt.NewProc("FwpmTransactionAbort0") 69 | procFwpmTransactionBegin0 = modfwpuclnt.NewProc("FwpmTransactionBegin0") 70 | procFwpmTransactionCommit0 = modfwpuclnt.NewProc("FwpmTransactionCommit0") 71 | ) 72 | 73 | func fwpmEngineClose0(engineHandle windows.Handle) (ret error) { 74 | r0, _, _ := syscall.Syscall(procFwpmEngineClose0.Addr(), 1, uintptr(engineHandle), 0, 0) 75 | if r0 != 0 { 76 | ret = syscall.Errno(r0) 77 | } 78 | return 79 | } 80 | 81 | func fwpmEngineOpen0(mustBeNil *uint16, authnService authnService, authIdentity *uintptr, session *fwpmSession0, engineHandle *windows.Handle) (ret error) { 82 | r0, _, _ := syscall.Syscall6(procFwpmEngineOpen0.Addr(), 5, uintptr(unsafe.Pointer(mustBeNil)), uintptr(authnService), uintptr(unsafe.Pointer(authIdentity)), uintptr(unsafe.Pointer(session)), uintptr(unsafe.Pointer(engineHandle)), 0) 83 | if r0 != 0 { 84 | ret = syscall.Errno(r0) 85 | } 86 | return 87 | } 88 | 89 | func fwpmFilterAdd0(engineHandle windows.Handle, rule *fwpmFilter0, sd *windows.SECURITY_DESCRIPTOR, id *uint64) (ret error) { 90 | r0, _, _ := syscall.Syscall6(procFwpmFilterAdd0.Addr(), 4, uintptr(engineHandle), uintptr(unsafe.Pointer(rule)), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(id)), 0, 0) 91 | if r0 != 0 { 92 | ret = syscall.Errno(r0) 93 | } 94 | return 95 | } 96 | 97 | func fwpmFilterCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *fwpmFilterEnumTemplate0, handle *windows.Handle) (ret error) { 98 | r0, _, _ := syscall.Syscall(procFwpmFilterCreateEnumHandle0.Addr(), 3, uintptr(engineHandle), uintptr(unsafe.Pointer(enumTemplate)), uintptr(unsafe.Pointer(handle))) 99 | if r0 != 0 { 100 | ret = syscall.Errno(r0) 101 | } 102 | return 103 | } 104 | 105 | func fwpmFilterDeleteByKey0(engineHandle windows.Handle, guid *RuleID) (ret error) { 106 | r0, _, _ := syscall.Syscall(procFwpmFilterDeleteByKey0.Addr(), 2, uintptr(engineHandle), uintptr(unsafe.Pointer(guid)), 0) 107 | if r0 != 0 { 108 | ret = syscall.Errno(r0) 109 | } 110 | return 111 | } 112 | 113 | func fwpmFilterDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) { 114 | r0, _, _ := syscall.Syscall(procFwpmFilterDestroyEnumHandle0.Addr(), 2, uintptr(engineHandle), uintptr(enumHandle), 0) 115 | if r0 != 0 { 116 | ret = syscall.Errno(r0) 117 | } 118 | return 119 | } 120 | 121 | func fwpmFilterEnum0(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmFilter0, numEntriesReturned *uint32) (ret error) { 122 | r0, _, _ := syscall.Syscall6(procFwpmFilterEnum0.Addr(), 5, uintptr(engineHandle), uintptr(enumHandle), uintptr(numEntriesRequested), uintptr(unsafe.Pointer(entries)), uintptr(unsafe.Pointer(numEntriesReturned)), 0) 123 | if r0 != 0 { 124 | ret = syscall.Errno(r0) 125 | } 126 | return 127 | } 128 | 129 | func fwpmFreeMemory0(p *struct{}) { 130 | syscall.Syscall(procFwpmFreeMemory0.Addr(), 1, uintptr(unsafe.Pointer(p)), 0, 0) 131 | return 132 | } 133 | 134 | func fwpmGetAppIdFromFileName0(path *byte, appId **fwpByteBlob) (ret error) { 135 | r0, _, _ := syscall.Syscall(procFwpmGetAppIdFromFileName0.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(appId)), 0) 136 | if r0 != 0 { 137 | ret = syscall.Errno(r0) 138 | } 139 | return 140 | } 141 | 142 | func fwpmLayerCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *fwpmLayerEnumTemplate0, handle *windows.Handle) (ret error) { 143 | r0, _, _ := syscall.Syscall(procFwpmLayerCreateEnumHandle0.Addr(), 3, uintptr(engineHandle), uintptr(unsafe.Pointer(enumTemplate)), uintptr(unsafe.Pointer(handle))) 144 | if r0 != 0 { 145 | ret = syscall.Errno(r0) 146 | } 147 | return 148 | } 149 | 150 | func fwpmLayerDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) { 151 | r0, _, _ := syscall.Syscall(procFwpmLayerDestroyEnumHandle0.Addr(), 2, uintptr(engineHandle), uintptr(enumHandle), 0) 152 | if r0 != 0 { 153 | ret = syscall.Errno(r0) 154 | } 155 | return 156 | } 157 | 158 | func fwpmLayerEnum0(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmLayer0, numEntriesReturned *uint32) (ret error) { 159 | r0, _, _ := syscall.Syscall6(procFwpmLayerEnum0.Addr(), 5, uintptr(engineHandle), uintptr(enumHandle), uintptr(numEntriesRequested), uintptr(unsafe.Pointer(entries)), uintptr(unsafe.Pointer(numEntriesReturned)), 0) 160 | if r0 != 0 { 161 | ret = syscall.Errno(r0) 162 | } 163 | return 164 | } 165 | 166 | func fwpmNetEventCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *struct{}, handle *windows.Handle) (ret error) { 167 | r0, _, _ := syscall.Syscall(procFwpmNetEventCreateEnumHandle0.Addr(), 3, uintptr(engineHandle), uintptr(unsafe.Pointer(enumTemplate)), uintptr(unsafe.Pointer(handle))) 168 | if r0 != 0 { 169 | ret = syscall.Errno(r0) 170 | } 171 | return 172 | } 173 | 174 | func fwpmNetEventDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) { 175 | r0, _, _ := syscall.Syscall(procFwpmNetEventDestroyEnumHandle0.Addr(), 2, uintptr(engineHandle), uintptr(enumHandle), 0) 176 | if r0 != 0 { 177 | ret = syscall.Errno(r0) 178 | } 179 | return 180 | } 181 | 182 | func fwpmNetEventEnum1(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmNetEvent1, numEntriesReturned *uint32) (ret error) { 183 | r0, _, _ := syscall.Syscall6(procFwpmNetEventEnum1.Addr(), 5, uintptr(engineHandle), uintptr(enumHandle), uintptr(numEntriesRequested), uintptr(unsafe.Pointer(entries)), uintptr(unsafe.Pointer(numEntriesReturned)), 0) 184 | if r0 != 0 { 185 | ret = syscall.Errno(r0) 186 | } 187 | return 188 | } 189 | 190 | func fwpmProviderAdd0(engineHandle windows.Handle, provider *fwpmProvider0, nilForNow *uintptr) (ret error) { 191 | r0, _, _ := syscall.Syscall(procFwpmProviderAdd0.Addr(), 3, uintptr(engineHandle), uintptr(unsafe.Pointer(provider)), uintptr(unsafe.Pointer(nilForNow))) 192 | if r0 != 0 { 193 | ret = syscall.Errno(r0) 194 | } 195 | return 196 | } 197 | 198 | func fwpmProviderCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *struct{}, handle *windows.Handle) (ret error) { 199 | r0, _, _ := syscall.Syscall(procFwpmProviderCreateEnumHandle0.Addr(), 3, uintptr(engineHandle), uintptr(unsafe.Pointer(enumTemplate)), uintptr(unsafe.Pointer(handle))) 200 | if r0 != 0 { 201 | ret = syscall.Errno(r0) 202 | } 203 | return 204 | } 205 | 206 | func fwpmProviderDeleteByKey0(engineHandle windows.Handle, guid *ProviderID) (ret error) { 207 | r0, _, _ := syscall.Syscall(procFwpmProviderDeleteByKey0.Addr(), 2, uintptr(engineHandle), uintptr(unsafe.Pointer(guid)), 0) 208 | if r0 != 0 { 209 | ret = syscall.Errno(r0) 210 | } 211 | return 212 | } 213 | 214 | func fwpmProviderDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) { 215 | r0, _, _ := syscall.Syscall(procFwpmProviderDestroyEnumHandle0.Addr(), 2, uintptr(engineHandle), uintptr(enumHandle), 0) 216 | if r0 != 0 { 217 | ret = syscall.Errno(r0) 218 | } 219 | return 220 | } 221 | 222 | func fwpmProviderEnum0(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmProvider0, numEntriesReturned *uint32) (ret error) { 223 | r0, _, _ := syscall.Syscall6(procFwpmProviderEnum0.Addr(), 5, uintptr(engineHandle), uintptr(enumHandle), uintptr(numEntriesRequested), uintptr(unsafe.Pointer(entries)), uintptr(unsafe.Pointer(numEntriesReturned)), 0) 224 | if r0 != 0 { 225 | ret = syscall.Errno(r0) 226 | } 227 | return 228 | } 229 | 230 | func fwpmSubLayerAdd0(engineHandle windows.Handle, sublayer *fwpmSublayer0, nilForNow *uintptr) (ret error) { 231 | r0, _, _ := syscall.Syscall(procFwpmSubLayerAdd0.Addr(), 3, uintptr(engineHandle), uintptr(unsafe.Pointer(sublayer)), uintptr(unsafe.Pointer(nilForNow))) 232 | if r0 != 0 { 233 | ret = syscall.Errno(r0) 234 | } 235 | return 236 | } 237 | 238 | func fwpmSubLayerCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *fwpmSublayerEnumTemplate0, handle *windows.Handle) (ret error) { 239 | r0, _, _ := syscall.Syscall(procFwpmSubLayerCreateEnumHandle0.Addr(), 3, uintptr(engineHandle), uintptr(unsafe.Pointer(enumTemplate)), uintptr(unsafe.Pointer(handle))) 240 | if r0 != 0 { 241 | ret = syscall.Errno(r0) 242 | } 243 | return 244 | } 245 | 246 | func fwpmSubLayerDeleteByKey0(engineHandle windows.Handle, guid *SublayerID) (ret error) { 247 | r0, _, _ := syscall.Syscall(procFwpmSubLayerDeleteByKey0.Addr(), 2, uintptr(engineHandle), uintptr(unsafe.Pointer(guid)), 0) 248 | if r0 != 0 { 249 | ret = syscall.Errno(r0) 250 | } 251 | return 252 | } 253 | 254 | func fwpmSubLayerDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (ret error) { 255 | r0, _, _ := syscall.Syscall(procFwpmSubLayerDestroyEnumHandle0.Addr(), 2, uintptr(engineHandle), uintptr(enumHandle), 0) 256 | if r0 != 0 { 257 | ret = syscall.Errno(r0) 258 | } 259 | return 260 | } 261 | 262 | func fwpmSubLayerEnum0(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmSublayer0, numEntriesReturned *uint32) (ret error) { 263 | r0, _, _ := syscall.Syscall6(procFwpmSubLayerEnum0.Addr(), 5, uintptr(engineHandle), uintptr(enumHandle), uintptr(numEntriesRequested), uintptr(unsafe.Pointer(entries)), uintptr(unsafe.Pointer(numEntriesReturned)), 0) 264 | if r0 != 0 { 265 | ret = syscall.Errno(r0) 266 | } 267 | return 268 | } 269 | 270 | func fwpmTransactionAbort0(engineHandle windows.Handle) (ret error) { 271 | r0, _, _ := syscall.Syscall(procFwpmTransactionAbort0.Addr(), 1, uintptr(engineHandle), 0, 0) 272 | if r0 != 0 { 273 | ret = syscall.Errno(r0) 274 | } 275 | return 276 | } 277 | 278 | func fwpmTransactionBegin0(engineHandle windows.Handle, flags uint32) (ret error) { 279 | r0, _, _ := syscall.Syscall(procFwpmTransactionBegin0.Addr(), 2, uintptr(engineHandle), uintptr(flags), 0) 280 | if r0 != 0 { 281 | ret = syscall.Errno(r0) 282 | } 283 | return 284 | } 285 | 286 | func fwpmTransactionCommit0(engineHandle windows.Handle) (ret error) { 287 | r0, _, _ := syscall.Syscall(procFwpmTransactionCommit0.Addr(), 1, uintptr(engineHandle), 0, 0) 288 | if r0 != 0 { 289 | ret = syscall.Errno(r0) 290 | } 291 | return 292 | } 293 | --------------------------------------------------------------------------------