Merge m5read@m5.eecs.umich.edu:/bk/m5
into zed.eecs.umich.edu:/z/benash/bk/m5 --HG-- extra : convert_revision : 453615c8194ae9ca96330b7493c6b19fc89c3a72
This commit is contained in:
commit
bc76a807af
11 changed files with 264 additions and 83 deletions
|
@ -58,6 +58,16 @@ const Addr PAddrUncachedBit39 = ULL(0x8000000000);
|
|||
const Addr PAddrUncachedBit40 = ULL(0x10000000000);
|
||||
const Addr PAddrUncachedBit43 = ULL(0x80000000000);
|
||||
const Addr PAddrUncachedMask = ULL(0x807ffffffff); // Clear PA<42:35>
|
||||
inline Addr Phys2K0Seg(Addr addr)
|
||||
{
|
||||
#ifndef ALPHA_TLASER
|
||||
if (addr & PAddrUncachedBit43) {
|
||||
addr &= PAddrUncachedMask;
|
||||
addr |= PAddrUncachedBit40;
|
||||
}
|
||||
#endif
|
||||
return addr | AlphaISA::K0SegBase;
|
||||
}
|
||||
|
||||
inline int DTB_ASN_ASN(uint64_t reg) { return reg >> 57 & AsnMask; }
|
||||
inline Addr DTB_PTE_PPN(uint64_t reg)
|
||||
|
|
|
@ -33,12 +33,11 @@
|
|||
* System Console Memory Mapped Register Definition
|
||||
*/
|
||||
|
||||
#define ALPHA_ACCESS_VERSION (1301)
|
||||
#define ALPHA_ACCESS_VERSION (1303)
|
||||
|
||||
#ifndef CONSOLE
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
class Checkpoint;
|
||||
#ifdef CONSOLE
|
||||
typedef unsigned uint32_t;
|
||||
typedef unsigned long uint64_t;
|
||||
#endif
|
||||
|
||||
// This structure hacked up from simos
|
||||
|
@ -71,11 +70,6 @@ struct AlphaAccess
|
|||
uint64_t bootStrapImpure; // 70:
|
||||
uint32_t bootStrapCPU; // 78:
|
||||
uint32_t align2; // 7C: Dummy placeholder for alignment
|
||||
|
||||
#ifndef CONSOLE
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // __ALPHA_ACCESS_H__
|
||||
|
|
|
@ -35,23 +35,22 @@
|
|||
#include <string>
|
||||
|
||||
#include "base/inifile.hh"
|
||||
#include "base/str.hh" // for to_number()
|
||||
#include "base/str.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "dev/alpha_console.hh"
|
||||
#include "dev/simconsole.hh"
|
||||
#include "dev/simple_disk.hh"
|
||||
#include "dev/tsunami_io.hh"
|
||||
#include "mem/bus/bus.hh"
|
||||
#include "mem/bus/pio_interface.hh"
|
||||
#include "mem/bus/pio_interface_impl.hh"
|
||||
#include "mem/functional/memory_control.hh"
|
||||
#include "mem/functional/physical.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/system.hh"
|
||||
#include "dev/tsunami_io.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
#include "targetarch/byte_swap.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -69,7 +68,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
|
|||
pioInterface->addAddrRange(RangeSize(addr, size));
|
||||
}
|
||||
|
||||
alphaAccess = new AlphaAccess;
|
||||
alphaAccess = new Access;
|
||||
alphaAccess->last_offset = size - 1;
|
||||
|
||||
alphaAccess->version = ALPHA_ACCESS_VERSION;
|
||||
|
@ -85,6 +84,8 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
|
|||
alphaAccess->bootStrapImpure = 0;
|
||||
alphaAccess->bootStrapCPU = 0;
|
||||
alphaAccess->align2 = 0;
|
||||
|
||||
system->setAlphaAccess(addr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -108,7 +109,8 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
|
|||
switch (req->size)
|
||||
{
|
||||
case sizeof(uint32_t):
|
||||
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint32_t*)data);
|
||||
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
|
||||
*(uint32_t*)data);
|
||||
switch (daddr)
|
||||
{
|
||||
case offsetof(AlphaAccess, last_offset):
|
||||
|
@ -133,7 +135,8 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
|
|||
}
|
||||
break;
|
||||
case sizeof(uint64_t):
|
||||
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint64_t*)data);
|
||||
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
|
||||
*(uint64_t*)data);
|
||||
switch (daddr)
|
||||
{
|
||||
case offsetof(AlphaAccess, inputChar):
|
||||
|
@ -266,7 +269,7 @@ AlphaConsole::cacheAccess(MemReqPtr &req)
|
|||
}
|
||||
|
||||
void
|
||||
AlphaAccess::serialize(ostream &os)
|
||||
AlphaConsole::Access::serialize(ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(last_offset);
|
||||
SERIALIZE_SCALAR(version);
|
||||
|
@ -289,7 +292,7 @@ AlphaAccess::serialize(ostream &os)
|
|||
}
|
||||
|
||||
void
|
||||
AlphaAccess::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(last_offset);
|
||||
UNSERIALIZE_SCALAR(version);
|
||||
|
|
|
@ -72,8 +72,14 @@ class SimpleDisk;
|
|||
class AlphaConsole : public PioDevice
|
||||
{
|
||||
protected:
|
||||
struct Access : public AlphaAccess
|
||||
{
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
union {
|
||||
AlphaAccess *alphaAccess;
|
||||
Access *alphaAccess;
|
||||
uint8_t *consoleData;
|
||||
};
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ NSGigE::NSGigE(Params *p)
|
|||
txDmaReadEvent(this), txDmaWriteEvent(this),
|
||||
dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free),
|
||||
txDelay(p->tx_delay), rxDelay(p->rx_delay),
|
||||
rxKickTick(0), txKickTick(0),
|
||||
rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
|
||||
txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false),
|
||||
acceptMulticast(false), acceptUnicast(false),
|
||||
acceptPerfect(false), acceptArp(false),
|
||||
|
@ -841,7 +841,8 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
|
|||
panic("writing to read-only or reserved CFGR bits!\n");
|
||||
|
||||
regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
|
||||
CFGR_RESERVED | CFGR_T64ADDR | CFGR_PCI64_DET);
|
||||
CFGR_RESERVED | CFGR_T64ADDR |
|
||||
CFGR_PCI64_DET);
|
||||
|
||||
// all these #if 0's are because i don't THINK the kernel needs to
|
||||
// have these implemented. if there is a problem relating to one of
|
||||
|
@ -1487,13 +1488,19 @@ NSGigE::rxKick()
|
|||
DPRINTF(EthernetSM, "receive kick rxState=%s (rxBuf.size=%d)\n",
|
||||
NsRxStateStrings[rxState], rxFifo.size());
|
||||
|
||||
if (rxKickTick > curTick) {
|
||||
DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n",
|
||||
rxKickTick);
|
||||
return;
|
||||
next:
|
||||
if (clock) {
|
||||
if (rxKickTick > curTick) {
|
||||
DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n",
|
||||
rxKickTick);
|
||||
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Go to the next state machine clock tick.
|
||||
rxKickTick = curTick + cycles(1);
|
||||
}
|
||||
|
||||
next:
|
||||
switch(rxDmaState) {
|
||||
case dmaReadWaiting:
|
||||
if (doRxDmaRead())
|
||||
|
@ -1561,8 +1568,7 @@ NSGigE::rxKick()
|
|||
if (rxDmaState != dmaIdle)
|
||||
goto exit;
|
||||
|
||||
DPRINTF(EthernetDesc,
|
||||
"rxDescCache: addr=%08x read descriptor\n",
|
||||
DPRINTF(EthernetDesc, "rxDescCache: addr=%08x read descriptor\n",
|
||||
regs.rxdp & 0x3fffffff);
|
||||
DPRINTF(EthernetDesc,
|
||||
"rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
|
||||
|
@ -1783,7 +1789,6 @@ NSGigE::rxKick()
|
|||
|
||||
DPRINTF(EthernetSM, "entering next rxState=%s\n",
|
||||
NsRxStateStrings[rxState]);
|
||||
|
||||
goto next;
|
||||
|
||||
exit:
|
||||
|
@ -1792,6 +1797,9 @@ NSGigE::rxKick()
|
|||
*/
|
||||
DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n",
|
||||
NsRxStateStrings[rxState]);
|
||||
|
||||
if (clock && !rxKickEvent.scheduled())
|
||||
rxKickEvent.schedule(rxKickTick);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1954,13 +1962,18 @@ NSGigE::txKick()
|
|||
DPRINTF(EthernetSM, "transmit kick txState=%s\n",
|
||||
NsTxStateStrings[txState]);
|
||||
|
||||
if (txKickTick > curTick) {
|
||||
DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n",
|
||||
txKickTick);
|
||||
return;
|
||||
next:
|
||||
if (clock) {
|
||||
if (txKickTick > curTick) {
|
||||
DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n",
|
||||
txKickTick);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Go to the next state machine clock tick.
|
||||
txKickTick = curTick + cycles(1);
|
||||
}
|
||||
|
||||
next:
|
||||
switch(txDmaState) {
|
||||
case dmaReadWaiting:
|
||||
if (doTxDmaRead())
|
||||
|
@ -2022,6 +2035,8 @@ NSGigE::txKick()
|
|||
if (txDmaState != dmaIdle)
|
||||
goto exit;
|
||||
|
||||
DPRINTF(EthernetDesc, "txDescCache: addr=%08x read descriptor\n",
|
||||
regs.txdp & 0x3fffffff);
|
||||
DPRINTF(EthernetDesc,
|
||||
"txDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
|
||||
txDescCache.link, txDescCache.bufptr, txDescCache.cmdsts,
|
||||
|
@ -2186,7 +2201,12 @@ NSGigE::txKick()
|
|||
if (txDescCache.cmdsts & CMDSTS_INTR)
|
||||
devIntrPost(ISR_TXDESC);
|
||||
|
||||
txState = txAdvance;
|
||||
if (!txEnable) {
|
||||
DPRINTF(EthernetSM, "halting TX state machine\n");
|
||||
txState = txIdle;
|
||||
goto exit;
|
||||
} else
|
||||
txState = txAdvance;
|
||||
break;
|
||||
|
||||
case txAdvance:
|
||||
|
@ -2215,7 +2235,6 @@ NSGigE::txKick()
|
|||
|
||||
DPRINTF(EthernetSM, "entering next txState=%s\n",
|
||||
NsTxStateStrings[txState]);
|
||||
|
||||
goto next;
|
||||
|
||||
exit:
|
||||
|
@ -2224,6 +2243,9 @@ NSGigE::txKick()
|
|||
*/
|
||||
DPRINTF(EthernetSM, "tx state machine exited txState=%s\n",
|
||||
NsTxStateStrings[txState]);
|
||||
|
||||
if (clock && !txKickEvent.scheduled())
|
||||
txKickEvent.schedule(txKickTick);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2429,6 +2451,7 @@ NSGigE::serialize(ostream &os)
|
|||
SERIALIZE_SCALAR(rxDescCache.bufptr);
|
||||
SERIALIZE_SCALAR(rxDescCache.cmdsts);
|
||||
SERIALIZE_SCALAR(rxDescCache.extsts);
|
||||
SERIALIZE_SCALAR(extstsEnable);
|
||||
|
||||
/*
|
||||
* Serialize tx state machine
|
||||
|
@ -2441,6 +2464,7 @@ NSGigE::serialize(ostream &os)
|
|||
SERIALIZE_SCALAR(txDescCnt);
|
||||
int txDmaState = this->txDmaState;
|
||||
SERIALIZE_SCALAR(txDmaState);
|
||||
SERIALIZE_SCALAR(txKickTick);
|
||||
|
||||
/*
|
||||
* Serialize rx state machine
|
||||
|
@ -2454,8 +2478,7 @@ NSGigE::serialize(ostream &os)
|
|||
SERIALIZE_SCALAR(rxDescCnt);
|
||||
int rxDmaState = this->rxDmaState;
|
||||
SERIALIZE_SCALAR(rxDmaState);
|
||||
|
||||
SERIALIZE_SCALAR(extstsEnable);
|
||||
SERIALIZE_SCALAR(rxKickTick);
|
||||
|
||||
/*
|
||||
* If there's a pending transmit, store the time so we can
|
||||
|
@ -2575,6 +2598,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
UNSERIALIZE_SCALAR(rxDescCache.bufptr);
|
||||
UNSERIALIZE_SCALAR(rxDescCache.cmdsts);
|
||||
UNSERIALIZE_SCALAR(rxDescCache.extsts);
|
||||
UNSERIALIZE_SCALAR(extstsEnable);
|
||||
|
||||
/*
|
||||
* unserialize tx state machine
|
||||
|
@ -2589,6 +2613,9 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
int txDmaState;
|
||||
UNSERIALIZE_SCALAR(txDmaState);
|
||||
this->txDmaState = (DmaState) txDmaState;
|
||||
UNSERIALIZE_SCALAR(txKickTick);
|
||||
if (txKickTick)
|
||||
txKickEvent.schedule(txKickTick);
|
||||
|
||||
/*
|
||||
* unserialize rx state machine
|
||||
|
@ -2604,8 +2631,9 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
int rxDmaState;
|
||||
UNSERIALIZE_SCALAR(rxDmaState);
|
||||
this->rxDmaState = (DmaState) rxDmaState;
|
||||
|
||||
UNSERIALIZE_SCALAR(extstsEnable);
|
||||
UNSERIALIZE_SCALAR(rxKickTick);
|
||||
if (rxKickTick)
|
||||
rxKickEvent.schedule(rxKickTick);
|
||||
|
||||
/*
|
||||
* If there's a pending transmit, reschedule it now
|
||||
|
|
|
@ -266,11 +266,13 @@ class NSGigE : public PciDev
|
|||
Tick rxKickTick;
|
||||
typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
|
||||
friend void RxKickEvent::process();
|
||||
RxKickEvent rxKickEvent;
|
||||
|
||||
void txKick();
|
||||
Tick txKickTick;
|
||||
typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
|
||||
friend void TxKickEvent::process();
|
||||
TxKickEvent txKickEvent;
|
||||
|
||||
/**
|
||||
* Retransmit event
|
||||
|
|
|
@ -30,7 +30,7 @@ import os, os.path, re, sys
|
|||
|
||||
Import('env')
|
||||
|
||||
import m5scons
|
||||
import scons_helper
|
||||
|
||||
def WriteEmbeddedPyFile(target, source, path, name, ext, filename):
|
||||
if isinstance(source, str):
|
||||
|
@ -151,7 +151,7 @@ def MakeDefinesPyFile(target, source, env):
|
|||
f = file(str(target[0]), 'w')
|
||||
print >>f, "import __main__"
|
||||
print >>f, "__main__.m5_build_env = ",
|
||||
print >>f, m5scons.flatten_defines(env['CPPDEFINES'])
|
||||
print >>f, scons_helper.flatten_defines(env['CPPDEFINES'])
|
||||
f.close()
|
||||
|
||||
CFileCounter = 0
|
||||
|
|
|
@ -64,7 +64,7 @@ class NSGigE(PciDevice):
|
|||
hardware_address = Param.EthernetAddr(NextEthernetAddr,
|
||||
"Ethernet Hardware Address")
|
||||
|
||||
clock = Param.Clock('100MHz', "State machine processor frequency")
|
||||
clock = Param.Clock('0ns', "State machine processor frequency")
|
||||
|
||||
dma_data_free = Param.Bool(False, "DMA of Data is free")
|
||||
dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
|
||||
|
|
|
@ -147,7 +147,7 @@ System::System(Params *p)
|
|||
* Set the hardware reset parameter block system type and revision
|
||||
* information to Tsunami.
|
||||
*/
|
||||
if (consoleSymtab->findAddress("xxm_rpb", addr)) {
|
||||
if (consoleSymtab->findAddress("m5_rpb", addr)) {
|
||||
Addr paddr = vtophys(physmem, addr);
|
||||
char *hwrpb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
|
||||
|
||||
|
@ -180,6 +180,23 @@ System::~System()
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
System::setAlphaAccess(Addr access)
|
||||
{
|
||||
Addr addr = 0;
|
||||
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
||||
Addr paddr = vtophys(physmem, addr);
|
||||
uint64_t *m5AlphaAccess =
|
||||
(uint64_t *)physmem->dma_addr(paddr, sizeof(uint64_t));
|
||||
|
||||
if (!m5AlphaAccess)
|
||||
panic("could not translate m5AlphaAccess addr\n");
|
||||
|
||||
*m5AlphaAccess = htoa(EV5::Phys2K0Seg(access));
|
||||
} else
|
||||
panic("could not find m5AlphaAccess\n");
|
||||
}
|
||||
|
||||
bool
|
||||
System::breakpoint()
|
||||
{
|
||||
|
|
|
@ -127,6 +127,11 @@ class System : public SimObject
|
|||
void startup();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Set the m5AlphaAccess pointer in the console
|
||||
*/
|
||||
void setAlphaAccess(Addr access);
|
||||
|
||||
/**
|
||||
* Returns the addess the kernel starts at.
|
||||
* @return address the kernel starts at
|
||||
|
|
192
util/tap/tap.cc
192
util/tap/tap.cc
|
@ -173,7 +173,7 @@ Accept(int fd, bool nodelay)
|
|||
}
|
||||
|
||||
void
|
||||
Connect(int fd, const string &host, int port)
|
||||
Connect(int fd, const std::string &host, int port)
|
||||
{
|
||||
struct sockaddr_in sockaddr;
|
||||
if (::inet_aton(host.c_str(), &sockaddr.sin_addr) == 0) {
|
||||
|
@ -193,6 +193,133 @@ Connect(int fd, const string &host, int port)
|
|||
DPRINTF("connected to %s on port %d\n", host, port);
|
||||
}
|
||||
|
||||
class Ethernet
|
||||
{
|
||||
protected:
|
||||
int fd;
|
||||
|
||||
public:
|
||||
virtual ~Ethernet() {}
|
||||
|
||||
int getfd() const { return fd; }
|
||||
virtual bool read(const char *&data, int &len) = 0;
|
||||
virtual bool write(const char *data, int len) = 0;
|
||||
};
|
||||
|
||||
class Tap : public Ethernet
|
||||
{
|
||||
private:
|
||||
char buffer[65536];
|
||||
int fd;
|
||||
|
||||
public:
|
||||
Tap(char *device);
|
||||
~Tap();
|
||||
virtual bool read(const char *&data, int &len);
|
||||
virtual bool write(const char *data, int len);
|
||||
};
|
||||
|
||||
class PCap : public Ethernet
|
||||
{
|
||||
private:
|
||||
pcap_t *pcap;
|
||||
eth_t *ethernet;
|
||||
|
||||
public:
|
||||
PCap(char *device, char *filter = NULL);
|
||||
~PCap();
|
||||
virtual bool read(const char *&data, int &len);
|
||||
virtual bool write(const char *data, int len);
|
||||
};
|
||||
|
||||
PCap::PCap(char *device, char *filter)
|
||||
{
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
memset(errbuf, 0, sizeof errbuf);
|
||||
pcap = pcap_open_live(device, 1500, 1, -1, errbuf);
|
||||
if (pcap == NULL)
|
||||
panic("pcap_open_live failed: %s\n", errbuf);
|
||||
|
||||
if (filter) {
|
||||
bpf_program program;
|
||||
bpf_u_int32 localnet, netmask;
|
||||
if (pcap_lookupnet(device, &localnet, &netmask, errbuf) == -1) {
|
||||
DPRINTF("pcap_lookupnet failed: %s\n", errbuf);
|
||||
netmask = 0xffffff00;
|
||||
}
|
||||
|
||||
if (pcap_compile(pcap, &program, filter, 1, netmask) == -1)
|
||||
panic("pcap_compile failed, invalid filter:\n%s\n", filter);
|
||||
|
||||
if (pcap_setfilter(pcap, &program) == -1)
|
||||
panic("pcap_setfilter failed\n");
|
||||
}
|
||||
|
||||
ethernet = eth_open(device);
|
||||
if (!ethernet)
|
||||
panic("cannot open the ethernet device for writing\n");
|
||||
|
||||
fd = pcap_fileno(pcap);
|
||||
}
|
||||
|
||||
PCap::~PCap()
|
||||
{
|
||||
pcap_close(pcap);
|
||||
eth_close(ethernet);
|
||||
}
|
||||
|
||||
bool
|
||||
PCap::read(const char *&data, int &len)
|
||||
{
|
||||
pcap_pkthdr hdr;
|
||||
data = (const char *)pcap_next(pcap, &hdr);
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
len = hdr.len;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PCap::write(const char *data, int len)
|
||||
{
|
||||
eth_send(ethernet, data, len);
|
||||
}
|
||||
|
||||
Tap::Tap(char *device)
|
||||
{
|
||||
fd = open(device, O_RDWR, 0);
|
||||
if (fd < 0)
|
||||
panic("could not open %s: %s\n", device, strerror(errno));
|
||||
}
|
||||
|
||||
Tap::~Tap()
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
bool
|
||||
Tap::read(const char *&data, int &len)
|
||||
{
|
||||
DPRINTF("tap read!\n");
|
||||
data = buffer;
|
||||
len = ::read(fd, buffer, sizeof(buffer));
|
||||
if (len < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Tap::write(const char *data, int len)
|
||||
{
|
||||
int result = ::write(fd, data, len);
|
||||
if (result < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -201,13 +328,16 @@ main(int argc, char *argv[])
|
|||
bool listening = false;
|
||||
char *device = NULL;
|
||||
char *filter = NULL;
|
||||
Ethernet *tap = NULL;
|
||||
bool usetap = false;
|
||||
char c;
|
||||
int daemon = false;
|
||||
string host;
|
||||
std::string host;
|
||||
int devfd;
|
||||
|
||||
program = basename(argv[0]);
|
||||
|
||||
while ((c = getopt(argc, argv, "b:df:lp:v")) != -1) {
|
||||
while ((c = getopt(argc, argv, "b:df:lp:tv")) != -1) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
bufsize = atoi(optarg);
|
||||
|
@ -224,6 +354,9 @@ main(int argc, char *argv[])
|
|||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
usetap = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
@ -268,31 +401,14 @@ main(int argc, char *argv[])
|
|||
host = *argv;
|
||||
}
|
||||
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
memset(errbuf, 0, sizeof errbuf);
|
||||
pcap_t *pcap = pcap_open_live(device, 1500, 1, -1, errbuf);
|
||||
if (pcap == NULL)
|
||||
panic("pcap_open_live failed: %s\n", errbuf);
|
||||
|
||||
if (filter) {
|
||||
bpf_program program;
|
||||
bpf_u_int32 localnet, netmask;
|
||||
if (pcap_lookupnet(device, &localnet, &netmask, errbuf) == -1) {
|
||||
DPRINTF("pcap_lookupnet failed: %s\n", errbuf);
|
||||
netmask = 0xffffff00;
|
||||
}
|
||||
|
||||
if (pcap_compile(pcap, &program, filter, 1, netmask) == -1)
|
||||
panic("pcap_compile failed, invalid filter:\n%s\n", filter);
|
||||
|
||||
if (pcap_setfilter(pcap, &program) == -1)
|
||||
panic("pcap_setfilter failed\n");
|
||||
if (usetap) {
|
||||
if (filter)
|
||||
panic("-f parameter not valid with a tap device!");
|
||||
tap = new Tap(device);
|
||||
} else {
|
||||
tap = new PCap(device, filter);
|
||||
}
|
||||
|
||||
eth_t *ethernet = eth_open(device);
|
||||
if (!ethernet)
|
||||
panic("cannot open the ethernet device for writing\n");
|
||||
|
||||
pollfd pfds[3];
|
||||
pfds[0].fd = Socket(true);
|
||||
pfds[0].events = POLLIN;
|
||||
|
@ -303,7 +419,7 @@ main(int argc, char *argv[])
|
|||
else
|
||||
Connect(pfds[0].fd, host, port);
|
||||
|
||||
pfds[1].fd = pcap_fileno(pcap);
|
||||
pfds[1].fd = tap->getfd();
|
||||
pfds[1].events = POLLIN;
|
||||
pfds[1].revents = 0;
|
||||
|
||||
|
@ -341,16 +457,16 @@ main(int argc, char *argv[])
|
|||
listen_pfd->revents = 0;
|
||||
}
|
||||
|
||||
DPRINTF("tap events: %x\n", tap_pfd->revents);
|
||||
if (tap_pfd && tap_pfd->revents) {
|
||||
if (tap_pfd->revents & POLLIN) {
|
||||
pcap_pkthdr hdr;
|
||||
const u_char *data = pcap_next(pcap, &hdr);
|
||||
if (data && client_pfd) {
|
||||
DPRINTF("Received packet from ethernet len=%d\n", hdr.len);
|
||||
DDUMP(data, hdr.len);
|
||||
u_int32_t len = htonl(hdr.len);
|
||||
write(client_pfd->fd, &len, sizeof(len));
|
||||
write(client_pfd->fd, data, hdr.len);
|
||||
const char *data; int len;
|
||||
if (tap->read(data, len) && client_pfd) {
|
||||
DPRINTF("Received packet from ethernet len=%d\n", len);
|
||||
DDUMP(data, len);
|
||||
u_int32_t swaplen = htonl(len);
|
||||
write(client_pfd->fd, &swaplen, sizeof(swaplen));
|
||||
write(client_pfd->fd, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,7 +495,7 @@ main(int argc, char *argv[])
|
|||
while (data_len != 0 &&
|
||||
buffer_offset >= data_len + sizeof(u_int32_t)) {
|
||||
char *data = buffer + sizeof(u_int32_t);
|
||||
eth_send(ethernet, data, data_len);
|
||||
tap->write(data, data_len);
|
||||
DPRINTF("Sent packet to ethernet len = %d\n", data_len);
|
||||
DDUMP(data, data_len);
|
||||
|
||||
|
@ -412,8 +528,8 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
delete [] buffer;
|
||||
pcap_close(pcap);
|
||||
eth_close(ethernet);
|
||||
delete tap;
|
||||
|
||||
if (listen_pfd)
|
||||
close(listen_pfd->fd);
|
||||
|
||||
|
|
Loading…
Reference in a new issue