github.com/gopacket/gopacket@v1.1.0/pcap/generate_defs.go (about)

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