21 #include <linux/if_packet.h> 22 #include <linux/net_tstamp.h> 24 #include <sys/types.h> 25 #include <sys/socket.h> 31 #ifndef PACKET_TX_HAS_OFF 32 #define PACKET_TX_HAS_OFF 19 34 #ifndef PACKET_QDISC_BYPASS 35 #define PACKET_QDISC_BYPASS 20 52 unsigned txqlen,
unsigned reserve,
bool qDiscBypass)
55 ::memset(&
qi_, 0,
sizeof(
qi_));
56 qi_.frameSize = frameSize;
59 ::socklen_t l =
sizeof(int);
60 if (getsockopt(
fd(), SOL_PACKET, PACKET_HDRLEN, (
char *)&v, &l) != 0)
62 qi_.hdrlen = TPACKET_ALIGN(v);
65 if (setsockopt(
fd(), SOL_PACKET, PACKET_VERSION, (
char *)&v,
sizeof(v)) != 0 )
70 struct ::tpacket_req req;
71 ::memset(&req, 0,
sizeof(req));
75 if (setsockopt(
fd(), SOL_PACKET, PACKET_LOSS, (
char *)&v,
sizeof(v)) != 0)
82 && setsockopt(
fd(), SOL_PACKET, PACKET_RESERVE, (
char *)&reserve,
sizeof(reserve)) == 0)
83 qi_.reserveSize = reserve;
84 req.tp_frame_nr = rxqlen;
85 req.tp_frame_size = frameSize;
86 req.tp_block_size = req.tp_frame_nr * req.tp_frame_size;
88 if (setsockopt(
fd(), SOL_PACKET, PACKET_RX_RING,
89 reinterpret_cast<char *>(&req),
sizeof(req)) != 0 )
91 size += req.tp_block_size;
95 req.tp_frame_nr = txqlen;
96 req.tp_frame_size = frameSize;
97 req.tp_block_size = req.tp_frame_nr * req.tp_frame_size;
99 if (setsockopt(
fd(), SOL_PACKET, PACKET_TX_RING,
100 reinterpret_cast<char *>(&req),
sizeof(req)) != 0 )
102 #ifdef SENF_ENABLE_TPACKET_OFFSET 107 size += req.tp_block_size;
110 unsigned char * map (static_cast<unsigned char *>(
111 ::mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
fd(), 0)));
112 if (map == MAP_FAILED)
116 qi_.init(rxqlen, txqlen);
133 if (::munmap(
qi_.map, (
qi_.rx.end -
qi_.rx.begin) + (
qi_.tx.end -
qi_.tx.begin)) < 0)
135 ::memset(&
qi_, 0,
sizeof(
qi_));
143 ::munmap(
qi_.map, (
qi_.rx.end -
qi_.rx.begin) + (
qi_.tx.end -
qi_.tx.begin));
144 ::memset(&
qi_, 0,
sizeof(
qi_));
150 detail::QueueInfo::TxStats
txStats (
qi_.txStats);
151 ::memset(&
qi_.txStats, 0,
sizeof(
qi_.txStats));
158 detail::QueueInfo::RxStats
rxStats (
qi_.rxStats);
159 ::memset(&
qi_.rxStats, 0,
sizeof(
qi_.rxStats));
174 bool rtn (
qi_.interfaceDead());
175 ::memset(&
qi_.txStats, 0,
sizeof(
qi_.txStats));
176 ::memset(&
qi_.rxStats, 0,
sizeof(
qi_.rxStats));
182 if (setsockopt(
fd(), SOL_PACKET, PACKET_TIMESTAMP, (
char*)&sofFlags,
sizeof(sofFlags)) != 0)
#define SENF_THROW_SYSTEM_EXCEPTION(desc)
#define PACKET_TX_HAS_OFF
detail::QueueInfo::TxStats txStats() const
int fd() const
Get file descriptor.
#define PACKET_QDISC_BYPASS
void close()
Close socket.
void timestamping(int sofFlags)
bool interfaceDead() const
FileHandle fh() const
Get a FileHandle for this instance.
void terminate() const
Forcibly close socket.
MMapSocketProtocol public header.
void terminate_mmap() const
virtual void close()
Close socket.
unsigned available() const
Return (maximum) number of bytes available for reading without < blocking.
void init_mmap(unsigned frameSize, unsigned rxqlen, unsigned txqlen, unsigned reserve=0, bool qDiscBypass=false) const
virtual void terminate() const
Forcibly close socket.
static void * extraPtr(FileHandle const &fh)
detail::QueueInfo::RxStats rxStats() const