Source: ../../fea/rawsock6.hh
|
|
|
|
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// Copyright (c) 2001-2005 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.
// $XORP: xorp/fea/rawsock6.hh,v 1.7 2005/03/25 02:53:14 pavlin Exp $
#ifndef __FEA_RAWSOCK6_HH__
#define __FEA_RAWSOCK6_HH__
#include <list>
#include <vector>
#include "libxorp/exceptions.hh"
#include "libxorp/ipv6.hh"
#include "libxorp/eventloop.hh"
/** Exception class for RawSocket Constructors */
struct RawSocket6Exception : public XorpReasonedException {
RawSocket6Exception(const char* file, size_t line,
const char* cmd, int error_no) :
XorpReasonedException("RawSocket6Exception", file, line,
c_format("%s: %s", cmd, strerror(error_no))) {}
};
/**
* Base class for raw sockets. Supports write only.
*/
class RawSocket6 {
public:
RawSocket6(uint32_t protocol) throw (RawSocket6Exception);
virtual ~RawSocket6();
inline uint32_t protocol() const { return _pf; }
/**
* Write data to raw socket.
*
* @param src source IPv6 address.
* @param dst destination IPv6 address.
* @param payload pointer to IPv6 packet payload.
* @param len length of payload in bytes.
*
* @return number of bytes written on success. If return value is
* negative check errno for system errors. Invalid IPv6 fields
* may cause packet to be rejected before being passed to system,
* in which case errno will not indicate an error. The error is
* recorded in the xlog.
*/
ssize_t write(const IPv6& src, const IPv6& dst, const uint8_t* payload,
size_t len) const;
private:
RawSocket6(const RawSocket6&); // Not implemented.
RawSocket6 operator=(const RawSocket6&); // Not implemented.
protected:
int32_t _fd;
uint32_t _pf;
};
/**
* Simple structure used to cache commonly passed IPv6 header information
* which comes from socket control message headers. This is used when
* reading from the kernel, so we use C types, rather than XORP C++ Class
* Library types.
*/
struct IPv6HeaderInfo {
IPv6 src;
IPv6 dst;
uint32_t rcvifindex;
uint32_t tclass;
uint32_t hoplimit;
};
/**
* Raw socket class supporting input and output. Output is handled
* with write() and writev() methods inherited from RawSocket. Reads
* are handled asynchronously. When data arrives on the underlying
* socket, recv is called and reads it into a per instance buffer.
* The abstract method process_recv_data is then called with a
* reference to a buffer containing the data.
*/
class IoRawSocket6 : public RawSocket6
{
public:
IoRawSocket6(EventLoop& eventloop, uint32_t protocol, bool autohook = true)
throw (RawSocket6Exception);
~IoRawSocket6();
protected:
virtual void process_recv_data(const struct IPv6HeaderInfo& hdrinfo,
const vector<uint8_t>& hopopts,
const vector<uint8_t>& payload) = 0;
protected:
void recv(int fd, SelectorMask m);
bool eventloop_hook();
void eventloop_unhook();
private:
IoRawSocket6(const IoRawSocket6&); // Not implemented.
IoRawSocket6 operator=(const IoRawSocket6&); // Not implemented.
private:
EventLoop& _eventloop;
bool _autohook;
// Cached properties of most recently received datagram.
struct IPv6HeaderInfo _hdrinfo;
enum { CMSGBUF_BYTES = 10240 };
enum { OPTBUF_BYTES = 1024 };
enum { RECVBUF_BYTES = 131072 };
vector<uint8_t> _cmsgbuf;
vector<uint8_t> _hoptbuf;
vector<uint8_t> _recvbuf;
};
/**
* A RawSocketClass that allows arbitrary filters to receive the data
* associated with a raw socket.
*/
class FilterRawSocket6 : public IoRawSocket6
{
public:
/**
* Filter class.
*/
class InputFilter {
public:
virtual ~InputFilter() {}
/**
* Method invoked when data arrives on associated FilterRawSocket6
* instance.
*/
virtual void recv(const struct IPv6HeaderInfo& hdrinfo,
const vector<uint8_t>& hopopts,
const vector<uint8_t>& payload) = 0;
/**
* Method invoked by the destructor of the associated
* FilterRawSocket6 instance. This method provides the
* InputFilter with the opportunity to delete itself or update
* it's state. The input filter does not need to call
* FilterRawSocket6::remove_filter() since filter removal is
* automatically conducted.
*/
virtual void bye() = 0;
};
public:
FilterRawSocket6(EventLoop& eventloop, int protocol)
throw (RawSocket6Exception);
~FilterRawSocket6();
/** Add a filter to list of input filters. The FilterRawSocket6 class
* assumes that the callee will be responsible for managing the memory
* associated with the filter and will call remove_filter() if the
* filter is deleted or goes out of scope.
*/
bool add_filter(InputFilter* filter);
/** Remove filter from list of input filters. */
bool remove_filter(InputFilter* filter);
/** @return true if there are no filters associated with this instance. */
bool empty() const { return _filters.empty(); }
protected:
void process_recv_data(const struct IPv6HeaderInfo& hdrinfo,
const vector<uint8_t>& hopopts,
const vector<uint8_t>& payload);
private:
FilterRawSocket6(const FilterRawSocket6&); // Not implemented.
FilterRawSocket6 operator=(const FilterRawSocket6&); // Not implemented.
protected:
list<InputFilter*> _filters;
};
#endif // __FEA_RAWSOCK6_HH__
Generated by: pavlin on possum.icir.org on Wed Apr 13 21:53:05 2005, using kdoc $.