generate_defs.go 4.2 KB

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