This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 580454ffe9f5eb4ef9841cff236dabeb0d397e52
Author: Sebastian Rühl <sru...@apache.org>
AuthorDate: Fri Sep 17 20:33:18 2021 +0200

    feat(pl4go): Added initial pcap transport
---
 plc4go/go.mod                                      |   4 +-
 plc4go/go.sum                                      |  13 ++
 .../plc4go/spi/transports/pcap/Transport.go        | 173 +++++++++++++++++++++
 3 files changed, 188 insertions(+), 2 deletions(-)

diff --git a/plc4go/go.mod b/plc4go/go.mod
index fe7d241..016d3eb 100644
--- a/plc4go/go.mod
+++ b/plc4go/go.mod
@@ -24,6 +24,7 @@ go 1.16
 require (
        github.com/ajankovic/xdiff v0.0.1
        github.com/elastic/go-licenser v0.3.1 // indirect
+       github.com/google/gopacket v1.1.19
        github.com/icza/bitio v1.0.0
        github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4
        github.com/pkg/errors v0.9.1
@@ -31,7 +32,6 @@ require (
        github.com/snksoft/crc v1.1.0
        github.com/subchen/go-xmldom v1.1.2
        github.com/tebeka/go2xunit v1.4.10 // indirect
-       golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
-       golang.org/x/tools v0.1.5 // indirect
+       golang.org/x/tools v0.1.6 // indirect
        gotest.tools/gotestsum v1.7.0 // indirect
 )
diff --git a/plc4go/go.sum b/plc4go/go.sum
index b834a94..dd14d14 100644
--- a/plc4go/go.sum
+++ b/plc4go/go.sum
@@ -13,6 +13,8 @@ github.com/fsnotify/fsnotify v1.4.9 
h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
 github.com/fsnotify/fsnotify v1.4.9/go.mod 
h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/google/go-cmp v0.4.0/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/gopacket v1.1.19 
h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
+github.com/google/gopacket v1.1.19/go.mod 
h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 
h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod 
h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 github.com/icza/bitio v1.0.0 h1:squ/m1SHyFeCA6+6Gyol1AxV9nmPPlJFT8c2vKdj3U8=
@@ -42,9 +44,12 @@ github.com/tebeka/go2xunit v1.4.10 
h1:0UO+9YoLpXTZ0DL9XbTmIIibgmKBGiwroo8uhFMSyR
 github.com/tebeka/go2xunit v1.4.10/go.mod 
h1:wmc9jKT7KlU4QLU6DNTaIXNnYNOjKKNlp6mjOS0UrqY=
 github.com/yuin/goldmark v1.2.1/go.mod 
h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod 
h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.0/go.mod 
h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod 
h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod 
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod 
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod 
h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod 
h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -53,6 +58,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod 
h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod 
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod 
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod 
h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c 
h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
@@ -66,20 +72,27 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod 
h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 
h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e 
h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 
h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod 
h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod 
h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod 
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod 
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod 
h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.1.0/go.mod 
h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
 golang.org/x/tools v0.1.5/go.mod 
h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.6 h1:SIasE1FVIQOWz2GEAHFOmoW7xchJcqlucjSULTL0Ag4=
+golang.org/x/tools v0.1.6/go.mod 
h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/plc4go/internal/plc4go/spi/transports/pcap/Transport.go 
b/plc4go/internal/plc4go/spi/transports/pcap/Transport.go
new file mode 100644
index 0000000..ed81c02
--- /dev/null
+++ b/plc4go/internal/plc4go/spi/transports/pcap/Transport.go
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package pcap
+
+import (
+       "bufio"
+       "bytes"
+       "github.com/apache/plc4x/plc4go/internal/plc4go/spi/transports"
+       "github.com/google/gopacket/pcap"
+       "github.com/pkg/errors"
+       "github.com/rs/zerolog/log"
+       "net/url"
+       "sync"
+)
+
+type TransportType string
+
+const (
+       UDP TransportType = "udp"
+       TCP TransportType = "tcp"
+)
+
+type Transport struct {
+}
+
+func NewTransport() *Transport {
+       return &Transport{}
+}
+
+func (m Transport) GetTransportCode() string {
+       return "pcap"
+}
+
+func (m Transport) GetTransportName() string {
+       return "PCAP(NG) Playback Transport"
+}
+
+func (m Transport) CreateTransportInstance(transportUrl url.URL, options 
map[string][]string) (transports.TransportInstance, error) {
+       var transportType = TCP
+       if val, ok := options["transport-type"]; ok {
+               transportType = TransportType(val[0])
+       }
+       var portRange = ""
+       if val, ok := options["transport-port-range"]; ok {
+               portRange = val[0]
+       }
+
+       transportInstance := NewPcapTransportInstance(transportUrl.Path, 
transportType, portRange, &m)
+
+       castFunc := func(typ interface{}) (transports.TransportInstance, error) 
{
+               if transportInstance, ok := typ.(transports.TransportInstance); 
ok {
+                       return transportInstance, nil
+               }
+               return nil, errors.New("couldn't cast to TransportInstance")
+       }
+       return castFunc(transportInstance)
+}
+
+type TransportInstance struct {
+       transportFile string
+       transportType TransportType
+       portRange     string
+       connected     bool
+       transport     *Transport
+       reader        *bufio.Reader
+       handle        *pcap.Handle
+       mutex         sync.Mutex
+}
+
+func NewPcapTransportInstance(transportFile string, transportType 
TransportType, portRange string, transport *Transport) *TransportInstance {
+       return &TransportInstance{
+               transportFile: transportFile,
+               transportType: transportType,
+               portRange:     portRange,
+               transport:     transport,
+       }
+}
+
+func (m *TransportInstance) Connect() error {
+       handle, err := pcap.OpenOffline(m.transportFile)
+       if err != nil {
+               return err
+       }
+       filter := string(m.transportType)
+       if m.portRange != "" {
+               filter += " dst port " + m.portRange
+       }
+       if err := handle.SetBPFFilter(filter); err != nil {
+               return err
+       }
+       m.handle = handle
+       m.connected = true
+       return nil
+}
+
+func (m *TransportInstance) Close() error {
+       m.handle.Close()
+       m.connected = false
+       return nil
+}
+
+func (m *TransportInstance) IsConnected() bool {
+       return m.connected
+}
+
+func (m *TransportInstance) GetNumReadableBytes() (uint32, error) {
+       if err := m.checkForNextPackage(); err != nil {
+               return 0, err
+       }
+       if m.reader == nil {
+               return 0, nil
+       }
+       _, _ = m.reader.Peek(1)
+       return uint32(m.reader.Buffered()), nil
+}
+
+func (m *TransportInstance) PeekReadableBytes(numBytes uint32) ([]uint8, 
error) {
+       if m.reader == nil {
+               return nil, errors.New("error peeking from transport. No reader 
available")
+       }
+       return m.reader.Peek(int(numBytes))
+}
+
+func (m *TransportInstance) Read(numBytes uint32) ([]uint8, error) {
+       if m.reader == nil {
+               return nil, errors.New("error reading from transport. No reader 
available")
+       }
+       data := make([]uint8, numBytes)
+       for i := uint32(0); i < numBytes; i++ {
+               val, err := m.reader.ReadByte()
+               if err != nil {
+                       return nil, errors.Wrap(err, "error reading")
+               }
+               data[i] = val
+       }
+       return data, nil
+}
+
+func (m *TransportInstance) Write(_ []uint8) error {
+       panic("Write to pcap not supported")
+}
+
+func (m *TransportInstance) checkForNextPackage() error {
+       m.mutex.Lock()
+       defer m.mutex.Lock()
+       // TODO: this will only work with the first packet and after this we 
are done
+       if m.reader == nil {
+               packetData, captureInfo, err := m.handle.ReadPacketData()
+               log.Info().Msgf("Read new package %v", captureInfo)
+               if err != nil {
+                       return err
+               }
+               m.reader = bufio.NewReader(bytes.NewBuffer(packetData))
+       }
+       return nil
+}

Reply via email to