| // Copyright 2019 The GoPacket Authors. All rights reserved. |
| // |
| // Use of this source code is governed by a BSD-style license |
| // that can be found in the LICENSE file in the root of the source |
| // tree. |
| |
| // +build ignore |
| |
| package main |
| |
| // This file generates the godefs needed for the windows version. |
| // Rebuild is only necessary if additional libpcap functionality is implemented, or a new arch is implemented in golang. |
| // Call with go run generate_windows.go [-I includepath] |
| // Needs npcap sdk, go tool cgo, and gofmt to work. Location of npcap includes can be specified with -I |
| |
| import ( |
| "bytes" |
| "flag" |
| "fmt" |
| "io/ioutil" |
| "log" |
| "os" |
| "os/exec" |
| "path/filepath" |
| "strings" |
| ) |
| |
| const header = `// Copyright 2019 The GoPacket Authors. All rights reserved. |
| // |
| // Use of this source code is governed by a BSD-style license |
| // that can be found in the LICENSE file in the root of the source |
| // tree. |
| |
| // This file contains necessary structs/constants generated from libpcap headers with cgo -godefs |
| // generated with: %s |
| // DO NOT MODIFY |
| |
| ` |
| |
| const source = ` |
| package pcap |
| |
| //#include <pcap.h> |
| import "C" |
| |
| import "syscall" // needed for RawSockaddr |
| |
| const errorBufferSize = C.PCAP_ERRBUF_SIZE |
| |
| const ( |
| pcapErrorNotActivated = C.PCAP_ERROR_NOT_ACTIVATED |
| pcapErrorActivated = C.PCAP_ERROR_ACTIVATED |
| pcapWarningPromisc = C.PCAP_WARNING_PROMISC_NOTSUP |
| pcapErrorNoSuchDevice = C.PCAP_ERROR_NO_SUCH_DEVICE |
| pcapErrorDenied = C.PCAP_ERROR_PERM_DENIED |
| pcapErrorNotUp = C.PCAP_ERROR_IFACE_NOT_UP |
| pcapError = C.PCAP_ERROR |
| pcapWarning = C.PCAP_WARNING |
| pcapDIN = C.PCAP_D_IN |
| pcapDOUT = C.PCAP_D_OUT |
| pcapDINOUT = C.PCAP_D_INOUT |
| pcapNetmaskUnknown = C.PCAP_NETMASK_UNKNOWN |
| pcapTstampPrecisionMicro = C.PCAP_TSTAMP_PRECISION_MICRO |
| pcapTstampPrecisionNano = C.PCAP_TSTAMP_PRECISION_NANO |
| ) |
| |
| type timeval C.struct_timeval |
| type pcapPkthdr C.struct_pcap_pkthdr |
| type pcapTPtr uintptr |
| type pcapBpfInstruction C.struct_bpf_insn |
| type pcapBpfProgram C.struct_bpf_program |
| type pcapStats C.struct_pcap_stat |
| type pcapCint C.int |
| type pcapIf C.struct_pcap_if |
| // +godefs map struct_sockaddr syscall.RawSockaddr |
| type pcapAddr C.struct_pcap_addr |
| ` |
| |
| var includes = flag.String("I", "C:\\npcap-sdk-1.01\\Include", "Include path containing libpcap headers") |
| |
| func main() { |
| flag.Parse() |
| |
| infile, err := ioutil.TempFile(".", "defs.*.go") |
| if err != nil { |
| log.Fatal("Couldn't create temporary source file: ", err) |
| } |
| defer infile.Close() |
| defer os.Remove(infile.Name()) |
| |
| _, err = infile.WriteString(source) |
| if err != nil { |
| log.Fatalf("Couldn't write definitions to temporary file %s: %s", infile.Name(), err) |
| } |
| err = infile.Close() |
| if err != nil { |
| log.Fatalf("Couldn't close temporary source file %s: %s", infile.Name(), err) |
| } |
| |
| archs := []string{"386", "amd64"} |
| for _, arch := range archs { |
| env := append(os.Environ(), "GOARCH="+arch) |
| cmd := exec.Command("go", "tool", "cgo", "-godefs", "--", "-I", *includes, infile.Name()) |
| cmd.Env = env |
| cmd.Stderr = os.Stderr |
| var generated bytes.Buffer |
| cmd.Stdout = &generated |
| err := cmd.Run() |
| if err != nil { |
| log.Fatalf("Couldn't generated defs for %s: %s\n", arch, err) |
| } |
| |
| cmd = exec.Command("gofmt") |
| cmd.Env = env |
| cmd.Stderr = os.Stderr |
| outName := fmt.Sprintf("defs_windows_%s.go", arch) |
| out, err := os.Create(outName) |
| if err != nil { |
| log.Fatalf("Couldn't open file %s: %s", outName, err) |
| } |
| cmd.Stdout = out |
| in, err := cmd.StdinPipe() |
| if err != nil { |
| log.Fatal("Couldn't create input pipe for gofmt: ", err) |
| } |
| err = cmd.Start() |
| if err != nil { |
| log.Fatal("Couldn't start gofmt: ", err) |
| } |
| |
| _, err = fmt.Fprintf(in, header, strings.Join(append([]string{filepath.Base(os.Args[0])}, os.Args[1:]...), " ")) |
| if err != nil { |
| log.Fatal("Couldn't write header to gofmt: ", err) |
| } |
| |
| for { |
| line, err := generated.ReadBytes('\n') |
| if err != nil { |
| break |
| } |
| // remove godefs comments |
| if bytes.HasPrefix(line, []byte("//")) { |
| continue |
| } |
| _, err = in.Write(line) |
| if err != nil { |
| log.Fatal("Couldn't write line to gofmt: ", err) |
| } |
| } |
| in.Close() |
| err = cmd.Wait() |
| if err != nil { |
| log.Fatal("gofmt failed: ", err) |
| } |
| out.Close() |
| } |
| } |