ethertap.hh revision 12056
12SN/A/* 21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A * 282665SN/A * Authors: Nathan Binkert 292SN/A */ 302SN/A 312SN/A/* @file 322SN/A * Interface to connect a simulated ethernet device to the real world 332SN/A */ 342SN/A 3511263Sandreas.sandberg@arm.com#ifndef __DEV_NET_ETHERTAP_HH__ 3611263Sandreas.sandberg@arm.com#define __DEV_NET_ETHERTAP_HH__ 372SN/A 382SN/A#include <queue> 392SN/A#include <string> 402SN/A 414981SN/A#include "base/pollevent.hh" 4212056Sgabeblack@google.com#include "config/use_tuntap.hh" 4311263Sandreas.sandberg@arm.com#include "dev/net/etherint.hh" 4411263Sandreas.sandberg@arm.com#include "dev/net/etherobject.hh" 4511263Sandreas.sandberg@arm.com#include "dev/net/etherpkt.hh" 4612056Sgabeblack@google.com 4712056Sgabeblack@google.com#if USE_TUNTAP 4812056Sgabeblack@google.com#include "params/EtherTap.hh" 4912056Sgabeblack@google.com 5012056Sgabeblack@google.com#endif 5112056Sgabeblack@google.com 5212054Sgabeblack@google.com#include "params/EtherTapStub.hh" 5356SN/A#include "sim/eventq.hh" 5456SN/A#include "sim/sim_object.hh" 552SN/A 561872SN/Aclass TapEvent; 5712055Sgabeblack@google.comclass EtherTapInt; 5812055Sgabeblack@google.com 5912055Sgabeblack@google.comclass EtherTapBase : public EtherObject 6012055Sgabeblack@google.com{ 6112055Sgabeblack@google.com public: 6212055Sgabeblack@google.com typedef EtherTapBaseParams Params; 6312055Sgabeblack@google.com EtherTapBase(const Params *p); 6412055Sgabeblack@google.com virtual ~EtherTapBase(); 6512055Sgabeblack@google.com 6612055Sgabeblack@google.com const Params * 6712055Sgabeblack@google.com params() const 6812055Sgabeblack@google.com { 6912055Sgabeblack@google.com return dynamic_cast<const Params *>(_params); 7012055Sgabeblack@google.com } 7112055Sgabeblack@google.com 7212055Sgabeblack@google.com void serialize(CheckpointOut &cp) const override; 7312055Sgabeblack@google.com void unserialize(CheckpointIn &cp) override; 7412055Sgabeblack@google.com 7512055Sgabeblack@google.com protected: 7612055Sgabeblack@google.com uint8_t *buffer; 7712055Sgabeblack@google.com int buflen; 7812055Sgabeblack@google.com 7912055Sgabeblack@google.com EtherDump *dump; 8012055Sgabeblack@google.com 8112055Sgabeblack@google.com 8212055Sgabeblack@google.com /* 8312055Sgabeblack@google.com * Interface to the real network. 8412055Sgabeblack@google.com */ 8512055Sgabeblack@google.com protected: 8612055Sgabeblack@google.com friend class TapEvent; 8712055Sgabeblack@google.com TapEvent *event; 8812055Sgabeblack@google.com void pollFd(int fd); 8912055Sgabeblack@google.com void stopPolling(); 9012055Sgabeblack@google.com 9112055Sgabeblack@google.com // Receive data from the real network. 9212055Sgabeblack@google.com virtual void recvReal(int revent) = 0; 9312055Sgabeblack@google.com // Prepare and send data out to the real network. 9412055Sgabeblack@google.com virtual bool sendReal(const void *data, size_t len) = 0; 9512055Sgabeblack@google.com 9612055Sgabeblack@google.com 9712055Sgabeblack@google.com /* 9812055Sgabeblack@google.com * Interface to the simulated network. 9912055Sgabeblack@google.com */ 10012055Sgabeblack@google.com protected: 10112055Sgabeblack@google.com EtherTapInt *interface; 10212055Sgabeblack@google.com 10312055Sgabeblack@google.com public: 10412055Sgabeblack@google.com EtherInt *getEthPort(const std::string &if_name, int idx) override; 10512055Sgabeblack@google.com 10612055Sgabeblack@google.com bool recvSimulated(EthPacketPtr packet); 10712055Sgabeblack@google.com void sendSimulated(void *data, size_t len); 10812055Sgabeblack@google.com 10912055Sgabeblack@google.com protected: 11012055Sgabeblack@google.com std::queue<EthPacketPtr> packetBuffer; 11112055Sgabeblack@google.com void retransmit(); 11212055Sgabeblack@google.com 11312055Sgabeblack@google.com class TxEvent : public Event 11412055Sgabeblack@google.com { 11512055Sgabeblack@google.com protected: 11612055Sgabeblack@google.com EtherTapBase *tap; 11712055Sgabeblack@google.com 11812055Sgabeblack@google.com public: 11912055Sgabeblack@google.com TxEvent(EtherTapBase *_tap) : tap(_tap) {} 12012055Sgabeblack@google.com void process() { tap->retransmit(); } 12112055Sgabeblack@google.com virtual const char *description() const 12212055Sgabeblack@google.com { return "EtherTapBase retransmit"; } 12312055Sgabeblack@google.com }; 12412055Sgabeblack@google.com 12512055Sgabeblack@google.com friend class TxEvent; 12612055Sgabeblack@google.com TxEvent txEvent; 12712055Sgabeblack@google.com}; 12812055Sgabeblack@google.com 12912055Sgabeblack@google.comclass EtherTapInt : public EtherInt 13012055Sgabeblack@google.com{ 13112055Sgabeblack@google.com private: 13212055Sgabeblack@google.com EtherTapBase *tap; 13312055Sgabeblack@google.com public: 13412055Sgabeblack@google.com EtherTapInt(const std::string &name, EtherTapBase *t) : 13512055Sgabeblack@google.com EtherInt(name), tap(t) 13612055Sgabeblack@google.com { } 13712055Sgabeblack@google.com 13812055Sgabeblack@google.com bool recvPacket(EthPacketPtr pkt) override 13912055Sgabeblack@google.com { return tap->recvSimulated(pkt); } 14012055Sgabeblack@google.com void sendDone() override {} 14112055Sgabeblack@google.com}; 14212055Sgabeblack@google.com 14312055Sgabeblack@google.com 1441872SN/Aclass TapListener; 1451872SN/A 1462SN/A/* 14712054Sgabeblack@google.com * Interface to connect a simulated ethernet device to the real world. An 14812054Sgabeblack@google.com * external helper program bridges between this object's TCP port and a 14912054Sgabeblack@google.com * source/sink for Ethernet frames. Each frame going in either direction is 15012054Sgabeblack@google.com * prepended with the frame's length in a 32 bit integer in network byte order. 1512SN/A */ 15212055Sgabeblack@google.comclass EtherTapStub : public EtherTapBase 1532SN/A{ 1542SN/A public: 15512054Sgabeblack@google.com typedef EtherTapStubParams Params; 15612054Sgabeblack@google.com EtherTapStub(const Params *p); 15712055Sgabeblack@google.com ~EtherTapStub(); 1582SN/A 1594981SN/A const Params * 1604981SN/A params() const 1614981SN/A { 1624981SN/A return dynamic_cast<const Params *>(_params); 1634981SN/A } 1644981SN/A 16511168SN/A void serialize(CheckpointOut &cp) const override; 16611168SN/A void unserialize(CheckpointIn &cp) override; 16712055Sgabeblack@google.com 16812055Sgabeblack@google.com 16912055Sgabeblack@google.com protected: 17012055Sgabeblack@google.com friend class TapListener; 17112055Sgabeblack@google.com TapListener *listener; 17212055Sgabeblack@google.com 17312055Sgabeblack@google.com int socket; 17412055Sgabeblack@google.com 17512055Sgabeblack@google.com void attach(int fd); 17612055Sgabeblack@google.com void detach(); 17712055Sgabeblack@google.com 17812055Sgabeblack@google.com uint32_t buffer_used; 17912055Sgabeblack@google.com uint32_t frame_len; 18012055Sgabeblack@google.com 18112055Sgabeblack@google.com void recvReal(int revent) override; 18212055Sgabeblack@google.com bool sendReal(const void *data, size_t len) override; 1832SN/A}; 1842SN/A 1854981SN/A 18612056Sgabeblack@google.com#if USE_TUNTAP 18712056Sgabeblack@google.comclass EtherTap : public EtherTapBase 18812056Sgabeblack@google.com{ 18912056Sgabeblack@google.com public: 19012056Sgabeblack@google.com typedef EtherTapParams Params; 19112056Sgabeblack@google.com EtherTap(const Params *p); 19212056Sgabeblack@google.com ~EtherTap(); 19312056Sgabeblack@google.com 19412056Sgabeblack@google.com const Params * 19512056Sgabeblack@google.com params() const 19612056Sgabeblack@google.com { 19712056Sgabeblack@google.com return dynamic_cast<const Params *>(_params); 19812056Sgabeblack@google.com } 19912056Sgabeblack@google.com 20012056Sgabeblack@google.com 20112056Sgabeblack@google.com protected: 20212056Sgabeblack@google.com int tap; 20312056Sgabeblack@google.com 20412056Sgabeblack@google.com void recvReal(int revent) override; 20512056Sgabeblack@google.com bool sendReal(const void *data, size_t len) override; 20612056Sgabeblack@google.com}; 20712056Sgabeblack@google.com#endif 20812056Sgabeblack@google.com 20912056Sgabeblack@google.com 21011263Sandreas.sandberg@arm.com#endif // __DEV_NET_ETHERTAP_HH__ 211