1// Copyright 2019 The GoPacket Authors. All rights reserved. 2// 3// Use of this source code is governed by a BSD-style license 4// that can be found in the LICENSE file in the root of the source 5// tree. 6 7// +build ignore 8 9package main 10 11// This file generates the godefs needed for the windows version. 12// Rebuild is only necessary if additional libpcap functionality is implemented, or a new arch is implemented in golang. 13// Call with go run generate_windows.go [-I includepath] 14// Needs npcap sdk, go tool cgo, and gofmt to work. Location of npcap includes can be specified with -I 15 16import ( 17 "bytes" 18 "flag" 19 "fmt" 20 "io/ioutil" 21 "log" 22 "os" 23 "os/exec" 24 "path/filepath" 25 "strings" 26) 27 28const header = `// Copyright 2019 The GoPacket Authors. All rights reserved. 29// 30// Use of this source code is governed by a BSD-style license 31// that can be found in the LICENSE file in the root of the source 32// tree. 33 34// This file contains necessary structs/constants generated from libpcap headers with cgo -godefs 35// generated with: %s 36// DO NOT MODIFY 37 38` 39 40const source = ` 41package pcap 42 43//#include <pcap.h> 44import "C" 45 46import "syscall" // needed for RawSockaddr 47 48const errorBufferSize = C.PCAP_ERRBUF_SIZE 49 50const ( 51 pcapErrorNotActivated = C.PCAP_ERROR_NOT_ACTIVATED 52 pcapErrorActivated = C.PCAP_ERROR_ACTIVATED 53 pcapWarningPromisc = C.PCAP_WARNING_PROMISC_NOTSUP 54 pcapErrorNoSuchDevice = C.PCAP_ERROR_NO_SUCH_DEVICE 55 pcapErrorDenied = C.PCAP_ERROR_PERM_DENIED 56 pcapErrorNotUp = C.PCAP_ERROR_IFACE_NOT_UP 57 pcapError = C.PCAP_ERROR 58 pcapWarning = C.PCAP_WARNING 59 pcapDIN = C.PCAP_D_IN 60 pcapDOUT = C.PCAP_D_OUT 61 pcapDINOUT = C.PCAP_D_INOUT 62 pcapNetmaskUnknown = C.PCAP_NETMASK_UNKNOWN 63 pcapTstampPrecisionMicro = C.PCAP_TSTAMP_PRECISION_MICRO 64 pcapTstampPrecisionNano = C.PCAP_TSTAMP_PRECISION_NANO 65) 66 67type timeval C.struct_timeval 68type pcapPkthdr C.struct_pcap_pkthdr 69type pcapTPtr uintptr 70type pcapBpfInstruction C.struct_bpf_insn 71type pcapBpfProgram C.struct_bpf_program 72type pcapStats C.struct_pcap_stat 73type pcapCint C.int 74type pcapIf C.struct_pcap_if 75// +godefs map struct_sockaddr syscall.RawSockaddr 76type pcapAddr C.struct_pcap_addr 77` 78 79var includes = flag.String("I", "C:\\npcap-sdk-1.01\\Include", "Include path containing libpcap headers") 80 81func main() { 82 flag.Parse() 83 84 infile, err := ioutil.TempFile(".", "defs.*.go") 85 if err != nil { 86 log.Fatal("Couldn't create temporary source file: ", err) 87 } 88 defer infile.Close() 89 defer os.Remove(infile.Name()) 90 91 _, err = infile.WriteString(source) 92 if err != nil { 93 log.Fatalf("Couldn't write definitions to temporary file %s: %s", infile.Name(), err) 94 } 95 err = infile.Close() 96 if err != nil { 97 log.Fatalf("Couldn't close temporary source file %s: %s", infile.Name(), err) 98 } 99 100 archs := []string{"386", "amd64"} 101 for _, arch := range archs { 102 env := append(os.Environ(), "GOARCH="+arch) 103 cmd := exec.Command("go", "tool", "cgo", "-godefs", "--", "-I", *includes, infile.Name()) 104 cmd.Env = env 105 cmd.Stderr = os.Stderr 106 var generated bytes.Buffer 107 cmd.Stdout = &generated 108 err := cmd.Run() 109 if err != nil { 110 log.Fatalf("Couldn't generated defs for %s: %s\n", arch, err) 111 } 112 113 cmd = exec.Command("gofmt") 114 cmd.Env = env 115 cmd.Stderr = os.Stderr 116 outName := fmt.Sprintf("defs_windows_%s.go", arch) 117 out, err := os.Create(outName) 118 if err != nil { 119 log.Fatalf("Couldn't open file %s: %s", outName, err) 120 } 121 cmd.Stdout = out 122 in, err := cmd.StdinPipe() 123 if err != nil { 124 log.Fatal("Couldn't create input pipe for gofmt: ", err) 125 } 126 err = cmd.Start() 127 if err != nil { 128 log.Fatal("Couldn't start gofmt: ", err) 129 } 130 131 _, err = fmt.Fprintf(in, header, strings.Join(append([]string{filepath.Base(os.Args[0])}, os.Args[1:]...), " ")) 132 if err != nil { 133 log.Fatal("Couldn't write header to gofmt: ", err) 134 } 135 136 for { 137 line, err := generated.ReadBytes('\n') 138 if err != nil { 139 break 140 } 141 // remove godefs comments 142 if bytes.HasPrefix(line, []byte("//")) { 143 continue 144 } 145 _, err = in.Write(line) 146 if err != nil { 147 log.Fatal("Couldn't write line to gofmt: ", err) 148 } 149 } 150 in.Close() 151 err = cmd.Wait() 152 if err != nil { 153 log.Fatal("gofmt failed: ", err) 154 } 155 out.Close() 156 } 157} 158