diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml index 2577b04..b6b3f0f 100644 --- a/.github/workflows/go.yaml +++ b/.github/workflows/go.yaml @@ -28,10 +28,4 @@ jobs: run: make - name: Run tests - run: make test - - - name: Check Go Format - run: make test-fmt - - - name: Check go.mod is tidy - run: make test-tidy + run: make test test-fmt test-tidy diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml new file mode 100644 index 0000000..eff5561 --- /dev/null +++ b/.github/workflows/golangci-lint.yaml @@ -0,0 +1,43 @@ +name: golangci-lint +on: + push: + branches: [main] + pull_request: + # The branches below must be a subset of the branches above + branches: [main] + +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + pull-requests: read + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: v1.43.0 + + # Optional: working directory, useful for monorepos + # working-directory: somedir + + # Optional: golangci-lint command line arguments. + # args: --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true then the action will use pre-installed Go. + # skip-go-installation: true + + # Optional: if set to true then the action don't cache or restore ~/go/pkg. + # skip-pkg-cache: true + + # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. + # skip-build-cache: true + diff --git a/.gitignore b/.gitignore index d371e0a..fbd43c1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.dll *.so *.dylib +*.pcap # Test binary, built with `go test -c` *.test diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..916a233 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,12 @@ +linters: + enable: + - asciicheck + - ineffassign + - gocyclo + - dupl + # - funlen + - gofmt + - gosec + - misspell + - whitespace + # - unparam diff --git a/CHANGELOG.md b/CHANGELOG.md index 57a3ca8..640ac4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,12 @@ ## Unreleased -## v0.0.9 - 2022-01-10 +## v0.0.9 - Unreleased Added: - Linux/ARMv5 support + - Add support for writing pcap files for debugging #79 Changed: @@ -15,6 +16,9 @@ Changed: - --cache-ttl is now 3 hours - ARMv6/v7 now have unique binaries and use hardware floating point - No more "arm32" builds which isn't a real ARM arch + - Remove str2pcap since we have direct pcap support now + - Switch from pflag to Kong for CLI arg parsing + - Update to logrus 1.8.1 ## v0.0.8 - 2021-11-07 diff --git a/Makefile b/Makefile index 6be59f8..9e81f39 100644 --- a/Makefile +++ b/Makefile @@ -26,15 +26,9 @@ LDFLAGS := -X "main.Version=$(PROJECT_VERSION)" -X "main.Delta=$(PROJ LDFLAGS += -X "main.Buildinfos=$(BUILDINFOS)" -X "main.Tag=$(PROJECT_TAG)" LDFLAGS += -X "main.CommitID=$(PROJECT_COMMIT)" -s -w OUTPUT_NAME := $(DIST_DIR)$(PROJECT_NAME)-$(GOOS)-$(GOARCH) -STR2PCAP_NAME := $(DIST_DIR)str2pcap-$(PROJECT_VERSION)-$(GOOS)-$(GOARCH) DOCKER_VERSION ?= v$(PROJECT_VERSION) -ALL: $(OUTPUT_NAME) str2pcap ## Build our current str2pcap platform binary - -str2pcap: $(STR2PCAP_NAME) - -$(STR2PCAP_NAME): str2pcap/*.go - go build -o $(STR2PCAP_NAME) str2pcap/*.go +ALL: $(OUTPUT_NAME) include help.mk # place after ALL target and before all other targets @@ -44,6 +38,10 @@ release: build-release ## Build and sign official release build-release: clean linux-amd64 linux-mips64 linux-arm darwin-amd64 freebsd docker ## Build our release binaries +tags: cmd/*.go ## Create tags file for vim, etc + @echo Make sure you have Universal Ctags installed: https://github.com/universal-ctags/ctags + ctags -R + .PHONY: run run: cmd/*.go ## build and run udp-proxy-2020 using $UDP_PROXY_2020_ARGS sudo go run cmd/*.go $(UDP_PROXY_2020_ARGS) @@ -108,7 +106,10 @@ test-tidy: ## Test to make sure go.mod is tidy exit -1 ; \ fi -precheck: test test-fmt test-tidy ## Run all tests that happen in a PR +precheck: test test-fmt test-tidy lint ## Run all tests that happen in a PR + +lint: ## Run golangci-lint + golangci-lint run ###################################################################### # Linux targets for building Linux in Docker @@ -339,7 +340,7 @@ docker-shell: ## Get a shell in the docker image $(DOCKER_REPO)/$(PROJECT_NAME):$(DOCKER_VERSION) \ /bin/sh -docker-release: docker ## Tag and push docker images Linux AMD64/ARM64 +docker-release: ## Tag and push docker images Linux AMD64/ARM64 docker buildx build \ -t $(DOCKER_REPO)/$(PROJECT_NAME):$(DOCKER_VERSION) \ -t $(DOCKER_REPO)/$(PROJECT_NAME):latest \ diff --git a/cmd/listen.go b/cmd/listen.go index 6551540..4986813 100644 --- a/cmd/listen.go +++ b/cmd/listen.go @@ -2,8 +2,10 @@ package main import ( "encoding/binary" - "encoding/hex" + "fmt" "net" + "os" + "path/filepath" "strings" "sync" "time" @@ -12,6 +14,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/google/gopacket/pcap" + "github.com/google/gopacket/pcapgo" log "github.com/sirupsen/logrus" ) @@ -25,9 +28,12 @@ type Listen struct { ipaddr string // dstip we send packets to promisc bool // do we enable promisc on this interface? handle *pcap.Handle // gopacket.pcap handle + writer *pcapgo.Writer // in and outbound write packet handle + inwriter *pcapgo.Writer // inbound write packet handle + outwriter *pcapgo.Writer // outbound write packet handle timeout time.Duration // timeout for loop clientTTL time.Duration // ttl for client cache - sendpkt chan Send // channel used to recieve packets we need to send + sendpkt chan Send // channel used to receive packets we need to send clients map[string]time.Time // keep track of clients for non-promisc interfaces } @@ -94,6 +100,37 @@ func newListener(netif *net.Interface, promisc bool, ports []int32, to time.Dura return new } +type Direction string + +const ( + In Direction = "in" + Out Direction = "out" + InOut Direction = "inout" +) + +// OpenWrite will open the write file pcap handle +func (l *Listen) OpenWriter(path string, dir Direction) (string, error) { + var err error + fName := fmt.Sprintf("udp-proxy-%s-%s.pcap", dir, l.iname) + filePath := filepath.Join(path, fName) + f, err := os.Create(filePath) + if err != nil { + return fName, err + } + switch dir { + case "in": + l.inwriter = pcapgo.NewWriter(f) + return fName, l.inwriter.WriteFileHeader(65536, l.handle.LinkType()) + case "out": + l.outwriter = pcapgo.NewWriter(f) + return fName, l.outwriter.WriteFileHeader(65536, l.handle.LinkType()) + case "inout": + l.writer = pcapgo.NewWriter(f) + return fName, l.writer.WriteFileHeader(65536, l.handle.LinkType()) + } + return fName, fmt.Errorf("Invalid direction: %s", dir) +} + // Our goroutine for processing packets func (l *Listen) handlePackets(s *SendPktFeed, wg *sync.WaitGroup) { // add ourself as a sender @@ -128,6 +165,25 @@ func (l *Listen) handlePackets(s *SendPktFeed, wg *sync.WaitGroup) { log.Debugf("%s: received packet and fowarding onto other interfaces", l.iname) s.Send(packet, l.iname, l.handle.LinkType()) + + // write to pcap? + if l.inwriter != nil { + md := packet.Metadata() + ci := gopacket.CaptureInfo{ + Timestamp: md.Timestamp, + CaptureLength: md.CaptureLength, + Length: md.Length, + InterfaceIndex: md.InterfaceIndex, + AncillaryData: md.AncillaryData, + } + if err := l.inwriter.WritePacket(ci, packet.Data()); err != nil { + log.WithError(err).Warnf("Unable to write packet to pcap file") + } + if err := l.writer.WritePacket(ci, packet.Data()); err != nil { + log.WithError(err).Warnf("Unable to write packet to pcap file") + } + } + case <-ticker: // our timer log.Debugf("handlePackets(%s) ticker", l.iname) // clean client cache @@ -190,7 +246,7 @@ func (l *Listen) sendPackets(sndpkt Send) { if !l.promisc { // send one packet to broadcast IP dstip := net.ParseIP(l.ipaddr).To4() - if err, bytes := l.sendPacket(dstip, eth, loop, ip4, udp, payload); err != nil { + if err, bytes := l.sendPacket(sndpkt, dstip, eth, loop, ip4, udp, payload); err != nil { log.Warnf("Unable to send %d bytes from %s out %s: %s", bytes, sndpkt.srcif, l.iname, err) } @@ -199,9 +255,9 @@ func (l *Listen) sendPackets(sndpkt Send) { if len(l.clients) == 0 { log.Debugf("%s: Unable to send packet; no discovered clients", l.iname) } - for ip, _ := range l.clients { + for ip := range l.clients { dstip := net.ParseIP(ip).To4() - if err, bytes := l.sendPacket(dstip, eth, loop, ip4, udp, payload); err != nil { + if err, bytes := l.sendPacket(sndpkt, dstip, eth, loop, ip4, udp, payload); err != nil { log.Warnf("Unable to send %d bytes from %s out %s: %s", bytes, sndpkt.srcif, l.iname, err) } @@ -209,7 +265,7 @@ func (l *Listen) sendPackets(sndpkt Send) { } } -func (l *Listen) sendPacket(dstip net.IP, eth layers.Ethernet, loop layers.Loopback, +func (l *Listen) sendPacket(sndpkt Send, dstip net.IP, eth layers.Ethernet, loop layers.Loopback, ip4 layers.IPv4, udp layers.UDP, payload gopacket.Payload) (error, int) { // Build our packet to send buffer := gopacket.NewSerializeBuffer() @@ -288,8 +344,26 @@ func (l *Listen) sendPacket(dstip net.IP, eth layers.Ethernet, loop layers.Loopb } outgoingPacket := buffer.Bytes() - log.Debugf("%s => %s: packet len: %d: %s", - l.iname, dstip.String(), len(outgoingPacket), hex.EncodeToString(outgoingPacket)) + log.Debugf("%s => %s: packet len: %d", l.iname, dstip.String(), len(outgoingPacket)) + + // write to pcap? + if l.outwriter != nil { + md := sndpkt.packet.Metadata() + ci := gopacket.CaptureInfo{ + Timestamp: md.Timestamp, + CaptureLength: len(outgoingPacket), + Length: len(outgoingPacket), + InterfaceIndex: md.InterfaceIndex, + AncillaryData: md.AncillaryData, + } + if err := l.outwriter.WritePacket(ci, outgoingPacket); err != nil { + log.WithError(err).Warnf("Unable to write packet to pcap file") + } + if err := l.writer.WritePacket(ci, outgoingPacket); err != nil { + log.WithError(err).Warnf("Unable to write packet to pcap file") + } + } + return l.handle.WritePacketData(outgoingPacket), len(outgoingPacket) } diff --git a/cmd/main.go b/cmd/main.go index aba99e8..afc342c 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -8,8 +8,8 @@ import ( "sync" "time" + "github.com/alecthomas/kong" log "github.com/sirupsen/logrus" - flag "github.com/spf13/pflag" ) var Version = "unknown" @@ -18,52 +18,42 @@ var Tag = "NO-TAG" var CommitID = "unknown" var Delta = "" -func main() { - var _fixed_ip = []string{} - var interfaces = []string{} - var ports = []int32{} - var timeout int64 - var cachettl int64 - var debug bool - var logfile string - var version bool - var ilist bool - var fixed_ip = map[string][]string{} - - // option parsing - flag.StringSliceVar(&interfaces, "interface", []string{}, "Two or more interfaces to use") - flag.StringSliceVar(&_fixed_ip, "fixed-ip", []string{}, "IPs to always send to: iface@ip") - flag.Int32SliceVar(&ports, "port", []int32{}, "One or more UDP ports to process") - flag.Int64Var(&timeout, "timeout", 250, "Timeout in msec") - flag.Int64Var(&cachettl, "cachettl", 3*60, "Client IP cache TTL in min") - flag.BoolVar(&debug, "debug", false, "Enable debugging") - flag.StringVar(&logfile, "logfile", "stderr", "Log to file instead of stderr") - flag.BoolVar(&ilist, "list-interfaces", false, "List available interfaces and exit") - flag.BoolVar(&version, "version", false, "Print version and exit") - - flag.Parse() - - // log.DisableLevelTruncation(true) <-- supposed to work, but doesn't? - - // turn on debugging? - if debug == true { - log.SetReportCaller(true) - log.SetLevel(log.DebugLevel) - } else { - log.SetLevel(log.WarnLevel) - } +type CLI struct { + Interface []string `kong:"short='i',help='Two or more interfaces to use'"` + FixedIp []string `kong:"short='I',help='IPs to always send to iface@ip'"` + Port []int32 `kong:"short='p',help='One or more UDP ports to process'"` + Timeout int64 `kong:"short='t',default=250,help='Timeout in msec'"` + CacheTTL int64 `kong:"short='T',default=180,help='Client IP cache TTL in minutes'"` + Level string `kong:"short='L',default='info',enum='trace,debug,info,warn,error',help='Log level [trace|debug|info|warn|error]'"` + LogLines bool `kong:"help='Print line number in logs'"` + Logfile string `kong:"default='stderr',help='Write logs to filename'"` + Pcap bool `kong:"short='P',help='Generate pcap files for debugging'"` + PcapPath string `kong:"short='d',default='/root',help='Directory to write debug pcap files'"` + ListInterfaces bool `kong:"short='l',help='List available interfaces and exit'"` + Version bool `kong:"short='v',help='Print version information'"` +} - if logfile == "stderr" { - log.SetOutput(os.Stderr) - } else { - file, err := os.OpenFile(logfile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) - if err != nil { - log.WithError(err).Fatalf("Unable to open log file: %s", logfile) - } - log.SetOutput(file) - } +func init() { + log.SetFormatter(&log.TextFormatter{ + DisableLevelTruncation: true, + PadLevelText: true, + DisableTimestamp: true, + }) + log.SetOutput(os.Stderr) +} - if version == true { +func main() { + cli := CLI{} + parser := kong.Must( + &cli, + kong.Name("udp-proxy-2020"), + kong.Description("A crappy UDP proxy for the year 2020 and beyond!"), + kong.UsageOnError(), + ) + _, err := parser.Parse(os.Args[1:]) + parser.FatalIfErrorf(err) + + if cli.Version { delta := "" if len(Delta) > 0 { delta = fmt.Sprintf(" [%s delta]", Delta) @@ -74,20 +64,49 @@ func main() { os.Exit(0) } - if ilist == true { + // Setup Logging + switch cli.Level { + case "trace": + log.SetLevel(log.TraceLevel) + case "debug": + log.SetLevel(log.DebugLevel) + case "warn": + log.SetLevel(log.WarnLevel) + case "info": + log.SetLevel(log.InfoLevel) + case "error": + log.SetLevel(log.ErrorLevel) + } + + if cli.LogLines { + log.SetReportCaller(true) + } + + if cli.ListInterfaces { listInterfaces() os.Exit(0) } - // Neeed at least two interfaces - if len(interfaces) < 2 { - log.Fatal("Please specify two or more interfaces via --interface") + if len(cli.Interface) < 2 { + log.Fatalf("Please specify two or more --interface") + } + if len(cli.Port) < 1 { + log.Fatalf("Please specify one or more --port") + } + + if cli.Logfile != "stderr" { + file, err := os.OpenFile(cli.Logfile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) + if err != nil { + log.WithError(err).Fatalf("Unable to open log file: %s", cli.Logfile) + } + log.SetOutput(file) } // handle our timeout - to := parseTimeout(timeout) + to := parseTimeout(cli.Timeout) - for _, fip := range _fixed_ip { + var fixed_ip = map[string][]string{} + for _, fip := range cli.FixedIp { split := strings.Split(fip, "@") if len(split) != 2 { log.Fatalf("--fixed-ip %s is not in the correct format of @", fip) @@ -95,7 +114,7 @@ func main() { if net.ParseIP(split[1]) == nil { log.Fatalf("--fixed-ip %s IP address is not a valid IPv4 address", fip) } - if !stringInSlice(split[0], interfaces) { + if !stringInSlice(split[0], cli.Interface) { log.Fatalf("--fixed-ip %s interface must be specified via --interface", fip) } fixed_ip[split[0]] = append(fixed_ip[split[0]], split[1]) @@ -104,7 +123,7 @@ func main() { // create our Listeners var seenInterfaces = []string{} var listeners = []Listen{} - for _, iface := range interfaces { + for _, iface := range cli.Interface { // check for duplicates if stringPrefixInSlice(iface, seenInterfaces) { log.Fatalf("Can't specify the same interface (%s) multiple times", iface) @@ -117,13 +136,25 @@ func main() { } var promisc bool = (netif.Flags & net.FlagBroadcast) == 0 - listeners = append(listeners, newListener(netif, promisc, ports, to, fixed_ip[iface])) + l := newListener(netif, promisc, cli.Port, to, fixed_ip[iface]) + listeners = append(listeners, l) } // init each listener - ttl, _ := time.ParseDuration(fmt.Sprintf("%dm", cachettl)) + ttl, _ := time.ParseDuration(fmt.Sprintf("%dm", cli.CacheTTL)) for i := range listeners { initializeInterface(&listeners[i]) + if cli.Pcap { + if fName, err := listeners[i].OpenWriter(cli.PcapPath, In); err != nil { + log.Fatalf("Unable to open pcap file %s: %s", fName, err.Error()) + } + if fName, err := listeners[i].OpenWriter(cli.PcapPath, Out); err != nil { + log.Fatalf("Unable to open pcap file %s: %s", fName, err.Error()) + } + if fName, err := listeners[i].OpenWriter(cli.PcapPath, InOut); err != nil { + log.Fatalf("Unable to open pcap file %s: %s", fName, err.Error()) + } + } listeners[i].clientTTL = ttl defer listeners[i].handle.Close() } diff --git a/cmd/send.go b/cmd/send.go index 405956f..9fa8c9e 100644 --- a/cmd/send.go +++ b/cmd/send.go @@ -35,7 +35,7 @@ func (s *SendPktFeed) Send(p gopacket.Packet, srcif string, linkType layers.Link s.lock.Unlock() } -// RegisterSender registers a channel to recieve packet data we want to send +// RegisterSender registers a channel to receive packet data we want to send func (s *SendPktFeed) RegisterSender(send chan Send, iname string) { s.lock.Lock() if s.senders == nil { diff --git a/go.mod b/go.mod index 60f8251..25c52c4 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module github.com/synfinatic/udp-proxy-2020 go 1.16 require ( + github.com/alecthomas/kong v0.4.1 github.com/davecgh/go-spew v1.1.1 github.com/google/gopacket v1.1.18 - github.com/sirupsen/logrus v1.7.0 - github.com/spf13/pflag v1.0.5 + github.com/sirupsen/logrus v1.8.1 // see: https://github.com/sirupsen/logrus/issues/1275 golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect ) diff --git a/go.sum b/go.sum index ecb98c7..c5e26b4 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,22 @@ +github.com/alecthomas/kong v0.4.1 h1:0sFnMts+ijOiFuSHsMB9MlDi3NGINBkx9KIw1/gcuDw= +github.com/alecthomas/kong v0.4.1/go.mod h1:uzxf/HUh0tj43x1AyJROl3JT7SgsZ5m+icOv1csRhc0= +github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48= +github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY= github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -19,3 +26,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/str2pcap/main.go b/str2pcap/main.go deleted file mode 100644 index ac27eaa..0000000 --- a/str2pcap/main.go +++ /dev/null @@ -1,74 +0,0 @@ -package main - -// Code to take a file with each line representing a packet in hex -// Intended to be used with the log output from udp-proxy-2020 - -import ( - "bufio" - "encoding/hex" - "os" - "time" - - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/google/gopacket/pcapgo" - log "github.com/sirupsen/logrus" - flag "github.com/spf13/pflag" -) - -func main() { - var out = flag.String("out", "", "Pcap file to create") - var in = flag.String("in", "", "Input file name with packet data to read") - var dlt = flag.Uint8("dlt", 1, "DLT value") - var debug = flag.Bool("debug", false, "Enable debugging") - - flag.Parse() - if *debug == true { - log.SetReportCaller(true) - log.SetLevel(log.DebugLevel) - } else { - log.SetLevel(log.WarnLevel) - } - - if len(*out) == 0 || len(*in) == 0 { - log.Fatal("Please specify --in, --out and --dlt") - } - - infile, err := os.Open(*in) - if err != nil { - log.Fatalf("--in %s: %s", *in, err) - } - inScanner := bufio.NewScanner(infile) - inScanner.Split(bufio.ScanLines) - - fh, err := os.Create(*out) - if err != nil { - log.Fatalf("--out %s: %s", *out, err) - } - - var linktype = layers.LinkType(*dlt) - pcap := pcapgo.NewWriterNanos(fh) - pcap.WriteFileHeader(65535, linktype) - var i = 0 - for inScanner.Scan() { - i += 1 - bytes, err := hex.DecodeString(inScanner.Text()) - if err != nil { - log.Fatalf("reading line %d: %s", i, err) - } - - ci := gopacket.CaptureInfo{ - Timestamp: time.Time{}, - CaptureLength: len(bytes), - Length: len(bytes), - InterfaceIndex: 0, - } - err = pcap.WritePacket(ci, bytes) - if err != nil { - log.Fatal(err) - } - } - - infile.Close() - // no method to close a gopcap Writer???? WTF? -}