-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate_defs.go
157 lines (136 loc) · 4.18 KB
/
generate_defs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// 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()
}
}