aboutsummaryrefslogtreecommitdiffstats
path: root/extras/gomemif/examples
diff options
context:
space:
mode:
Diffstat (limited to 'extras/gomemif/examples')
-rw-r--r--extras/gomemif/examples/BUILD.bazel36
-rw-r--r--extras/gomemif/examples/bridge.go286
-rw-r--r--extras/gomemif/examples/icmp_responder_cb.go326
-rw-r--r--extras/gomemif/examples/icmp_responder_poll.go317
4 files changed, 0 insertions, 965 deletions
diff --git a/extras/gomemif/examples/BUILD.bazel b/extras/gomemif/examples/BUILD.bazel
deleted file mode 100644
index eb10422027f..00000000000
--- a/extras/gomemif/examples/BUILD.bazel
+++ /dev/null
@@ -1,36 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_binary")
-
-go_binary(
- name = "icmp_responder_poll",
- srcs = ["icmp_responder_poll.go"],
- visibility = ["//visibility:public",],
- deps = [
- "//memif:memif",
- "@com_github_profile//:go_default_library",
- "@com_github_gopacket//layers:go_default_library",
- "@com_github_gopacket//:go_default_library"
- ],
-)
-
-go_binary(
- name = "bridge",
- srcs = ["bridge.go"],
- visibility = ["//visibility:public",],
- deps = [
- "//memif:memif",
- "@com_github_profile//:go_default_library",
- ],
-)
-
-go_binary(
- name = "icmp_responder_cb",
- srcs = ["icmp_responder_cb.go"],
- visibility = ["//visibility:public",],
- deps = [
- "//memif:memif",
- "@com_github_profile//:go_default_library",
- "@com_github_gopacket//layers:go_default_library",
- "@com_github_gopacket//:go_default_library"
- ],
-)
-
diff --git a/extras/gomemif/examples/bridge.go b/extras/gomemif/examples/bridge.go
deleted file mode 100644
index a192034e3be..00000000000
--- a/extras/gomemif/examples/bridge.go
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2020 Cisco and/or its affiliates.
- * Licensed 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 main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "os"
- "strings"
- "sync"
- "time"
-
- "github.com/pkg/profile"
- "memif"
-)
-
-func Disconnected(i *memif.Interface) error {
- fmt.Println("Disconnected: ", i.GetName())
-
- data, ok := i.GetPrivateData().(*interfaceData)
- if !ok {
- return fmt.Errorf("Invalid private data")
- }
- close(data.quitChan) // stop polling
- close(data.errChan)
- data.wg.Wait() // wait until polling stops, then continue disconnect
-
- return nil
-}
-
-func Connected(i *memif.Interface) error {
- fmt.Println("Connected: ", i.GetName())
-
- data, ok := i.GetPrivateData().(*interfaceData)
- if !ok {
- return fmt.Errorf("Invalid private data")
- }
- data.errChan = make(chan error, 1)
- data.quitChan = make(chan struct{}, 1)
- data.wg.Add(1)
-
- go func(errChan chan<- error, quitChan <-chan struct{}, wg *sync.WaitGroup) {
- defer wg.Done()
- // allocate packet buffer
- pkt := make([]byte, 2048)
- // get rx queue
- rxq0, err := i.GetRxQueue(0)
- if err != nil {
- errChan <- err
- return
- }
-
- // wait until both interfaces are connected
- for !data.bri.IsConnected() {
- time.Sleep(100 * time.Millisecond)
- }
-
- // get bridged interfaces tx queue
- txq0, err := data.bri.GetTxQueue(0)
- if err != nil {
- errChan <- err
- return
- }
- for {
- select {
- case <-quitChan: // channel closed
- return
- default:
- // read packet from shared memory
- pktLen, err := rxq0.ReadPacket(pkt)
- if pktLen > 0 {
- // FIXME: prevent packet write if interface is disconencted
- // write packet to shared memory
- txq0.WritePacket(pkt[:pktLen])
- } else if err != nil {
- errChan <- err
- return
- }
- }
- }
- }(data.errChan, data.quitChan, &data.wg)
-
- return nil
-}
-
-type interfaceData struct {
- errChan chan error
- quitChan chan struct{}
- wg sync.WaitGroup
- // bridged interface
- bri *memif.Interface
-}
-
-func interractiveHelp() {
- fmt.Println("help - print this help")
- fmt.Println("start - start connecting loop")
- fmt.Println("show - print interface details")
- fmt.Println("exit - exit the application")
-}
-
-func newMemifInterface(socket *memif.Socket, id uint32, isMaster bool, name string) (*memif.Interface, *interfaceData, error) {
- data := &interfaceData{}
- args := &memif.Arguments{
- Id: id,
- IsMaster: isMaster,
- ConnectedFunc: Connected,
- DisconnectedFunc: Disconnected,
- PrivateData: data,
- Name: name,
- }
-
- i, err := socket.NewInterface(args)
- if err != nil {
- return nil, nil, fmt.Errorf("Failed to create interface on socket %s: %s", socket.GetFilename(), err)
- }
-
- // slave attempts to connect to control socket
- // to handle control communication call socket.StartPolling()
- if !i.IsMaster() {
- fmt.Println(args.Name, ": Connecting to control socket...")
- for !i.IsConnecting() {
- err = i.RequestConnection()
- if err != nil {
- /* TODO: check for ECONNREFUSED errno
- * if error is ECONNREFUSED it may simply mean that master
- * interface is not up yet, use i.RequestConnection()
- */
- return nil, nil, fmt.Errorf("Faild to connect: ", err)
- }
- }
- }
-
- return i, data, nil
-}
-
-func printMemifInterfaceDetails(i *memif.Interface) {
- fmt.Println(i.GetName(), ":")
- fmt.Println("\trole: ", memif.RoleToString(i.IsMaster()))
- fmt.Println("\tid: ", i.GetId())
- link := "down"
- if i.IsConnected() {
- link = "up"
- }
- fmt.Println("\tlink: ", link)
- fmt.Println("\tremote: ", i.GetRemoteName())
- fmt.Println("\tpeer: ", i.GetPeerName())
- if i.IsConnected() {
- mc := i.GetMemoryConfig()
- fmt.Println("queue pairs: ", mc.NumQueuePairs)
- fmt.Println("ring size: ", (1 << mc.Log2RingSize))
- fmt.Println("buffer size: ", mc.PacketBufferSize)
- }
-}
-
-func main() {
- memifErrChan := make(chan error)
- exitChan := make(chan struct{})
- var i0, i1 *memif.Interface
- var d0, d1 *interfaceData
-
- cpuprof := flag.String("cpuprof", "", "cpu profiling output file")
- memprof := flag.String("memprof", "", "mem profiling output file")
- role := flag.String("role", "slave", "interface role")
- name := flag.String("name", "gomemif", "interface name")
- socketName := flag.String("socket", "", "control socket filename")
-
- flag.Parse()
-
- // profiling options
- if *cpuprof != "" {
- defer profile.Start(profile.CPUProfile, profile.ProfilePath(*cpuprof)).Stop()
- }
- if *memprof != "" {
- defer profile.Start(profile.MemProfile, profile.ProfilePath(*memprof)).Stop()
- }
-
- // memif options
- var isMaster bool
- switch *role {
- case "slave":
- isMaster = false
- case "master":
- isMaster = true
- default:
- fmt.Println("Invalid role")
- return
- }
-
- // create memif socket
- socket, err := memif.NewSocket("gomemif_example", *socketName)
- if err != nil {
- fmt.Println("Failed to create socket: ", err)
- return
- }
-
- i0, d0, err = newMemifInterface(socket, 0, isMaster, *name)
- if err != nil {
- fmt.Println(err)
- goto exit
- }
-
- // TODO: update name
- i1, d1, err = newMemifInterface(socket, 1, isMaster, *name)
- if err != nil {
- fmt.Println(err)
- goto exit
- }
-
- // set up bridge
- d0.bri = i1
- d1.bri = i0
-
- // user input goroutine
- go func(exitChan chan<- struct{}) {
- reader := bufio.NewReader(os.Stdin)
- fmt.Println("GoMemif: Responder")
- fmt.Println("-----------------------")
- for {
- fmt.Print("gomemif# ")
- text, _ := reader.ReadString('\n')
- // convert CRLF to LF
- text = strings.Replace(text, "\n", "", -1)
- switch text {
- case "help":
- interractiveHelp()
- case "start":
- // start polling for events on this socket
- socket.StartPolling(memifErrChan)
- case "show":
- printMemifInterfaceDetails(i0)
- printMemifInterfaceDetails(i1)
- case "exit":
- err = socket.StopPolling()
- if err != nil {
- fmt.Println("Failed to stop polling: ", err)
- }
- close(exitChan)
- return
- default:
- fmt.Println("Unknown input")
- }
- }
- }(exitChan)
-
- // main loop
- for {
- select {
- case <-exitChan:
- goto exit
- case err, ok := <-memifErrChan:
- if ok {
- fmt.Println(err)
- }
- case err, ok := <-d0.errChan:
- if ok {
- fmt.Println(err)
- }
- case err, ok := <-d1.errChan:
- if ok {
- fmt.Println(err)
- }
- default:
- continue
- }
- }
-
-exit:
- socket.Delete()
- close(memifErrChan)
-}
diff --git a/extras/gomemif/examples/icmp_responder_cb.go b/extras/gomemif/examples/icmp_responder_cb.go
deleted file mode 100644
index 8d8adcfc892..00000000000
--- a/extras/gomemif/examples/icmp_responder_cb.go
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2020 Cisco and/or its affiliates.
- * Licensed 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 main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "net"
- "os"
- "strings"
- "sync"
-
- "memif"
-
- "github.com/google/gopacket"
- "github.com/google/gopacket/layers"
- "github.com/pkg/profile"
-)
-
-func Disconnected(i *memif.Interface) error {
- fmt.Println("Disconnected: ", i.GetName())
-
- data, ok := i.GetPrivateData().(*interfaceData)
- if !ok {
- return fmt.Errorf("Invalid private data")
- }
- close(data.quitChan) // stop polling
- close(data.errChan)
- data.wg.Wait() // wait until polling stops, then continue disconnect
-
- return nil
-}
-
-func Responder(i *memif.Interface) error {
- data, ok := i.GetPrivateData().(*interfaceData)
- if !ok {
- return fmt.Errorf("Invalid private data")
- }
- data.errChan = make(chan error, 1)
- data.quitChan = make(chan struct{}, 1)
- data.wg.Add(1)
-
- // allocate packet buffer
- pkt := make([]byte, 2048)
- // get rx queue
- rxq0, err := i.GetRxQueue(0)
- if err != nil {
- return err
- }
- // get tx queue
- txq0, err := i.GetTxQueue(0)
- if err != nil {
- return err
- }
- for {
-
- // read packet from shared memory
- pktLen, err := rxq0.ReadPacket(pkt)
- _ = err
- if pktLen > 0 {
- fmt.Printf("pktLen: %d\n", pktLen)
- gopkt := gopacket.NewPacket(pkt[:pktLen], layers.LayerTypeEthernet, gopacket.NoCopy)
- etherLayer := gopkt.Layer(layers.LayerTypeEthernet)
- if etherLayer.(*layers.Ethernet).EthernetType == layers.EthernetTypeARP {
- rEth := layers.Ethernet{
- SrcMAC: net.HardwareAddr{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa},
- DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
-
- EthernetType: layers.EthernetTypeARP,
- }
- rArp := layers.ARP{
- AddrType: layers.LinkTypeEthernet,
- Protocol: layers.EthernetTypeIPv4,
- HwAddressSize: 6,
- ProtAddressSize: 4,
- Operation: layers.ARPReply,
- SourceHwAddress: []byte(net.HardwareAddr{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}),
- SourceProtAddress: []byte("\xc0\xa8\x01\x01"),
- DstHwAddress: []byte(net.HardwareAddr{0x02, 0xfe, 0x08, 0x88, 0x45, 0x7f}),
- DstProtAddress: []byte("\xc0\xa8\x01\x02"),
- }
- buf := gopacket.NewSerializeBuffer()
- opts := gopacket.SerializeOptions{
- FixLengths: true,
- ComputeChecksums: true,
- }
- gopacket.SerializeLayers(buf, opts, &rEth, &rArp)
- // write packet to shared memory
- txq0.WritePacket(buf.Bytes())
- }
-
- if etherLayer.(*layers.Ethernet).EthernetType == layers.EthernetTypeIPv4 {
- ipLayer := gopkt.Layer(layers.LayerTypeIPv4)
- if ipLayer == nil {
- fmt.Println("Missing IPv4 layer.")
-
- }
- ipv4, _ := ipLayer.(*layers.IPv4)
- if ipv4.Protocol != layers.IPProtocolICMPv4 {
- fmt.Println("Not ICMPv4 protocol.")
- }
- icmpLayer := gopkt.Layer(layers.LayerTypeICMPv4)
- if icmpLayer == nil {
- fmt.Println("Missing ICMPv4 layer.")
- }
- icmp, _ := icmpLayer.(*layers.ICMPv4)
- if icmp.TypeCode.Type() != layers.ICMPv4TypeEchoRequest {
- fmt.Println("Not ICMPv4 echo request.")
- }
- fmt.Println("Received an ICMPv4 echo request.")
-
- // Build packet layers.
- ethResp := layers.Ethernet{
- DstMAC: net.HardwareAddr{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa},
- //DstMAC: net.HardwareAddr{0x02, 0xfe, 0xa8, 0x77, 0xaf, 0x20},
- SrcMAC: []byte(net.HardwareAddr{0x02, 0xfe, 0x08, 0x88, 0x45, 0x7f}),
-
- EthernetType: layers.EthernetTypeIPv4,
- }
- ipv4Resp := layers.IPv4{
- Version: 4,
- IHL: 5,
- TOS: 0,
- Id: 0,
- Flags: 0,
- FragOffset: 0,
- TTL: 255,
- Protocol: layers.IPProtocolICMPv4,
- SrcIP: []byte("\xc0\xa8\x01\x01"),
- DstIP: []byte("\xc0\xa8\x01\x02"),
- }
- icmpResp := layers.ICMPv4{
- TypeCode: layers.CreateICMPv4TypeCode(layers.ICMPv4TypeEchoReply, 0),
- Id: icmp.Id,
- Seq: icmp.Seq,
- }
-
- // Set up buffer and options for serialization.
- buf := gopacket.NewSerializeBuffer()
- opts := gopacket.SerializeOptions{
- FixLengths: true,
- ComputeChecksums: true,
- }
- gopacket.SerializeLayers(buf, opts, &ethResp, &ipv4Resp, &icmpResp,
- gopacket.Payload(icmp.Payload))
- // write packet to shared memory
- txq0.WritePacket(buf.Bytes())
- }
-
- }
- return nil
-
- }
-
-}
-func Connected(i *memif.Interface) error {
- data, ok := i.GetPrivateData().(*interfaceData)
- if !ok {
- return fmt.Errorf("Invalid private data")
- }
- _ = data
-
- // allocate packet buffer
- pkt := make([]byte, 2048)
- // get rx queue
- rxq0, err := i.GetRxQueue(0)
- _ = err
-
- // read packet from shared memory
- pktLen, err := rxq0.ReadPacket(pkt)
- _, _ = err, pktLen
-
- return nil
-}
-
-type interfaceData struct {
- errChan chan error
- quitChan chan struct{}
- wg sync.WaitGroup
-}
-
-func interractiveHelp() {
- fmt.Println("help - print this help")
- fmt.Println("start - start connecting loop")
- fmt.Println("show - print interface details")
- fmt.Println("exit - exit the application")
-}
-
-func main() {
- cpuprof := flag.String("cpuprof", "", "cpu profiling output file")
- memprof := flag.String("memprof", "", "mem profiling output file")
- role := flag.String("role", "slave", "interface role")
- name := flag.String("name", "gomemif", "interface name")
- socketName := flag.String("socket", "/run/vpp/memif.sock", "control socket filename")
-
- flag.Parse()
-
- if *cpuprof != "" {
- defer profile.Start(profile.CPUProfile, profile.ProfilePath(*cpuprof)).Stop()
- }
- if *memprof != "" {
- defer profile.Start(profile.MemProfile, profile.ProfilePath(*memprof)).Stop()
- }
-
- memifErrChan := make(chan error)
- exitChan := make(chan struct{})
-
- var isMaster bool
- switch *role {
- case "slave":
- isMaster = false
- case "master":
- isMaster = true
- default:
- fmt.Println("Invalid role")
- return
- }
-
- fmt.Println("GoMemif: Responder")
- fmt.Println("-----------------------")
-
- socket, err := memif.NewSocket("gomemif_example", *socketName)
- if err != nil {
- fmt.Println("Failed to create socket: ", err)
- return
- }
-
- data := interfaceData{}
- args := &memif.Arguments{
- IsMaster: isMaster,
- ConnectedFunc: Connected,
- DisconnectedFunc: Disconnected,
- PrivateData: &data,
- Name: *name,
- InterruptFunc: Responder,
- }
-
- i, err := socket.NewInterface(args)
- if err != nil {
- fmt.Println("Failed to create interface on socket %s: %s", socket.GetFilename(), err)
- goto exit
- }
-
- // slave attempts to connect to control socket
- // to handle control communication call socket.StartPolling()
- if !i.IsMaster() {
- fmt.Println(args.Name, ": Connecting to control socket...")
- for !i.IsConnecting() {
- err = i.RequestConnection()
- if err != nil {
- /* TODO: check for ECONNREFUSED errno
- * if error is ECONNREFUSED it may simply mean that master
- * interface is not up yet, use i.RequestConnection()
- */
- fmt.Println("Failed to connect: ", err)
- goto exit
- }
- }
- }
-
- go func(exitChan chan<- struct{}) {
- reader := bufio.NewReader(os.Stdin)
- for {
- fmt.Print("gomemif# ")
- text, _ := reader.ReadString('\n')
- // convert CRLF to LF
- text = strings.Replace(text, "\n", "", -1)
- switch text {
- case "help":
- interractiveHelp()
- case "start":
- // start polling for events on this socket
- socket.StartPolling(memifErrChan)
- case "show":
- fmt.Println("remote: ", i.GetRemoteName())
- fmt.Println("peer: ", i.GetPeerName())
- case "exit":
- err = socket.StopPolling()
- if err != nil {
- fmt.Println("Failed to stop polling: ", err)
- }
- close(exitChan)
- return
- default:
- fmt.Println("Unknown input")
- }
- }
- }(exitChan)
-
- for {
- select {
- case <-exitChan:
- goto exit
- case err, ok := <-memifErrChan:
- if ok {
- fmt.Println(err)
- }
- case err, ok := <-data.errChan:
- if ok {
- fmt.Println(err)
- }
- default:
- continue
- }
- }
-
-exit:
- socket.Delete()
- close(memifErrChan)
-}
diff --git a/extras/gomemif/examples/icmp_responder_poll.go b/extras/gomemif/examples/icmp_responder_poll.go
deleted file mode 100644
index f9f1c3e8208..00000000000
--- a/extras/gomemif/examples/icmp_responder_poll.go
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2020 Cisco and/or its affiliates.
- * Licensed 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 main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "net"
- "os"
- "strings"
- "sync"
-
- "memif"
-
- "github.com/google/gopacket"
- "github.com/google/gopacket/layers"
- "github.com/pkg/profile"
-)
-
-func Disconnected(i *memif.Interface) error {
- fmt.Println("Disconnected: ", i.GetName())
-
- data, ok := i.GetPrivateData().(*interfaceData)
- if !ok {
- return fmt.Errorf("Invalid private data")
- }
- close(data.quitChan) // stop polling
- close(data.errChan)
- data.wg.Wait() // wait until polling stops, then continue disconnect
-
- return nil
-}
-
-func Connected(i *memif.Interface) error {
- fmt.Println("Connected: ", i.GetName())
-
- data, ok := i.GetPrivateData().(*interfaceData)
- if !ok {
- return fmt.Errorf("Invalid private data")
- }
- data.errChan = make(chan error, 1)
- data.quitChan = make(chan struct{}, 1)
- data.wg.Add(1)
-
- go func(errChan chan<- error, quitChan <-chan struct{}, wg *sync.WaitGroup) {
- defer wg.Done()
- // allocate packet buffer
- pkt := make([]byte, 2048)
- // get rx queue
- rxq0, err := i.GetRxQueue(0)
- if err != nil {
- errChan <- err
- return
- }
- // get tx queue
- txq0, err := i.GetTxQueue(0)
- if err != nil {
- errChan <- err
- return
- }
- for {
- select {
- case <-quitChan: // channel closed
- return
- default:
- // read packet from shared memory
- pktLen, err := rxq0.ReadPacket(pkt)
- if pktLen > 0 {
- fmt.Printf("pktLen: %d\n", pktLen)
- gopkt := gopacket.NewPacket(pkt[:pktLen], layers.LayerTypeEthernet, gopacket.NoCopy)
- etherLayer := gopkt.Layer(layers.LayerTypeEthernet)
- if etherLayer.(*layers.Ethernet).EthernetType == layers.EthernetTypeARP {
-
- rEth := layers.Ethernet{
- SrcMAC: net.HardwareAddr{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa},
- DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- EthernetType: layers.EthernetTypeARP,
- }
- rArp := layers.ARP{
- AddrType: layers.LinkTypeEthernet,
- Protocol: layers.EthernetTypeIPv4,
- HwAddressSize: 6,
- ProtAddressSize: 4,
- Operation: layers.ARPReply,
- SourceHwAddress: []byte(net.HardwareAddr{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}),
- SourceProtAddress: []byte("\xc0\xa8\x01\x01"),
- DstHwAddress: []byte(net.HardwareAddr{0x02, 0xfe, 0x08, 0x88, 0x45, 0x7f}),
- DstProtAddress: []byte("\xc0\xa8\x01\x02"),
- }
- buf := gopacket.NewSerializeBuffer()
- opts := gopacket.SerializeOptions{
- FixLengths: true,
- ComputeChecksums: true,
- }
- gopacket.SerializeLayers(buf, opts, &rEth, &rArp)
- // write packet to shared memory
- txq0.WritePacket(buf.Bytes())
- }
-
- if etherLayer.(*layers.Ethernet).EthernetType == layers.EthernetTypeIPv4 {
- ipLayer := gopkt.Layer(layers.LayerTypeIPv4)
- if ipLayer == nil {
- fmt.Println("Missing IPv4 layer.")
-
- }
- ipv4, _ := ipLayer.(*layers.IPv4)
- if ipv4.Protocol != layers.IPProtocolICMPv4 {
- fmt.Println("Not ICMPv4 protocol.")
- }
- icmpLayer := gopkt.Layer(layers.LayerTypeICMPv4)
- if icmpLayer == nil {
- fmt.Println("Missing ICMPv4 layer.")
- }
- icmp, _ := icmpLayer.(*layers.ICMPv4)
- if icmp.TypeCode.Type() != layers.ICMPv4TypeEchoRequest {
- fmt.Println("Not ICMPv4 echo request.")
- }
- fmt.Println("Received an ICMPv4 echo request.")
-
- // Build packet layers.
- ethResp := layers.Ethernet{
- DstMAC: net.HardwareAddr{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa},
- //DstMAC: net.HardwareAddr{0x02, 0xfe, 0xa8, 0x77, 0xaf, 0x20},
- SrcMAC: []byte(net.HardwareAddr{0x02, 0xfe, 0x08, 0x88, 0x45, 0x7f}),
-
- EthernetType: layers.EthernetTypeIPv4,
- }
- ipv4Resp := layers.IPv4{
- Version: 4,
- IHL: 5,
- TOS: 0,
- Id: 0,
- Flags: 0,
- FragOffset: 0,
- TTL: 255,
- Protocol: layers.IPProtocolICMPv4,
- SrcIP: []byte("\xc0\xa8\x01\x01"),
- DstIP: []byte("\xc0\xa8\x01\x02"),
- }
- icmpResp := layers.ICMPv4{
- TypeCode: layers.CreateICMPv4TypeCode(layers.ICMPv4TypeEchoReply, 0),
- Id: icmp.Id,
- Seq: icmp.Seq,
- }
-
- // Set up buffer and options for serialization.
- buf := gopacket.NewSerializeBuffer()
- opts := gopacket.SerializeOptions{
- FixLengths: true,
- ComputeChecksums: true,
- }
- gopacket.SerializeLayers(buf, opts, &ethResp, &ipv4Resp, &icmpResp,
- gopacket.Payload(icmp.Payload))
- // write packet to shared memory
- txq0.WritePacket(buf.Bytes())
- }
- } else if err != nil {
- errChan <- err
- return
- }
- }
- }
- }(data.errChan, data.quitChan, &data.wg)
-
- return nil
-}
-
-type interfaceData struct {
- errChan chan error
- quitChan chan struct{}
- wg sync.WaitGroup
-}
-
-func interractiveHelp() {
- fmt.Println("help - print this help")
- fmt.Println("start - start connecting loop")
- fmt.Println("show - print interface details")
- fmt.Println("exit - exit the application")
-}
-
-func main() {
- cpuprof := flag.String("cpuprof", "", "cpu profiling output file")
- memprof := flag.String("memprof", "", "mem profiling output file")
- role := flag.String("role", "slave", "interface role")
- name := flag.String("name", "gomemif", "interface name")
- socketName := flag.String("socket", "", "control socket filename")
-
- flag.Parse()
-
- if *cpuprof != "" {
- defer profile.Start(profile.CPUProfile, profile.ProfilePath(*cpuprof)).Stop()
- }
- if *memprof != "" {
- defer profile.Start(profile.MemProfile, profile.ProfilePath(*memprof)).Stop()
- }
-
- memifErrChan := make(chan error)
- exitChan := make(chan struct{})
-
- var isMaster bool
- switch *role {
- case "slave":
- isMaster = false
- case "master":
- isMaster = true
- default:
- fmt.Println("Invalid role")
- return
- }
-
- fmt.Println("GoMemif: Responder")
- fmt.Println("-----------------------")
-
- socket, err := memif.NewSocket("gomemif_example", *socketName)
- if err != nil {
- fmt.Println("Failed to create socket: ", err)
- return
- }
-
- data := interfaceData{}
- args := &memif.Arguments{
- IsMaster: isMaster,
- ConnectedFunc: Connected,
- DisconnectedFunc: Disconnected,
- PrivateData: &data,
- Name: *name,
- }
-
- i, err := socket.NewInterface(args)
- if err != nil {
- fmt.Println("Failed to create interface on socket %s: %s", socket.GetFilename(), err)
- goto exit
- }
-
- // slave attempts to connect to control socket
- // to handle control communication call socket.StartPolling()
- if !i.IsMaster() {
- fmt.Println(args.Name, ": Connecting to control socket...")
- for !i.IsConnecting() {
- err = i.RequestConnection()
- if err != nil {
- /* TODO: check for ECONNREFUSED errno
- * if error is ECONNREFUSED it may simply mean that master
- * interface is not up yet, use i.RequestConnection()
- */
- fmt.Println("Faild to connect: ", err)
- goto exit
- }
- }
- }
-
- go func(exitChan chan<- struct{}) {
- reader := bufio.NewReader(os.Stdin)
- for {
- fmt.Print("gomemif# ")
- text, _ := reader.ReadString('\n')
- // convert CRLF to LF
- text = strings.Replace(text, "\n", "", -1)
- switch text {
- case "help":
- interractiveHelp()
- case "start":
- // start polling for events on this socket
- socket.StartPolling(memifErrChan)
- case "show":
- fmt.Println("remote: ", i.GetRemoteName())
- fmt.Println("peer: ", i.GetPeerName())
- case "exit":
- err = socket.StopPolling()
- if err != nil {
- fmt.Println("Failed to stop polling: ", err)
- }
- close(exitChan)
- return
- default:
- fmt.Println("Unknown input")
- }
- }
- }(exitChan)
-
- for {
- select {
- case <-exitChan:
- goto exit
- case err, ok := <-memifErrChan:
- if ok {
- fmt.Println(err)
- }
- case err, ok := <-data.errChan:
- if ok {
- fmt.Println(err)
- }
- default:
- continue
- }
- }
-
-exit:
- socket.Delete()
- close(memifErrChan)
-}