diff options
Diffstat (limited to 'extras/gomemif/examples')
-rw-r--r-- | extras/gomemif/examples/BUILD.bazel | 36 | ||||
-rw-r--r-- | extras/gomemif/examples/bridge.go | 286 | ||||
-rw-r--r-- | extras/gomemif/examples/icmp_responder_cb.go | 326 | ||||
-rw-r--r-- | extras/gomemif/examples/icmp_responder_poll.go | 317 |
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, ðResp, &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, ðResp, &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) -} |