Source: ../../fea/rawsock4.hh


 
LOGO
 Annotated List  Files  Globals  Hierarchy  Index  Top
// -*- 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/rawsock4.hh,v 1.6 2005/03/25 02:53:14 pavlin Exp $

#ifndef __FEA_RAWSOCK4_HH__
#define __FEA_RAWSOCK4_HH__

#include <list>
#include <vector>

#include "libxorp/exceptions.hh"
#include "libxorp/ipv4.hh"
#include "libxorp/ipv6.hh"
#include "libxorp/eventloop.hh"

/** Exception class for RawSocket Constructors */
struct RawSocket4Exception : public XorpReasonedException {
    RawSocket4Exception(const char* file, size_t line,
		       const char* cmd, int error_no) :
	XorpReasonedException("RawSocket4Exception", file, line,
			      c_format("%s: %s", cmd, strerror(error_no))) {}
};

/**
 * Base class for raw sockets.  Supports write only.
 */

class RawSocket4 {
public:
    RawSocket4(uint32_t protocol) throw (RawSocket4Exception);

    virtual ~RawSocket4();

    inline uint32_t protocol() const { return _pf; }

    /**
     * Write data to raw socket.
     *
     * @param buf pointer to raw IPv4 packet.  Packet fields are expected to be
     * in network order.
     *
     * @param bufbytes number of bytes in packet pointed to by @ref buf.
     *
     * @return number of bytes written on success.  If return value is
     * negative check errno for system errors.  Invalid IPv4 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 uint8_t* buf, size_t bufbytes) const;

private:
    RawSocket4(const RawSocket4&);		// Not implemented.
    RawSocket4 operator=(const RawSocket4&);	// Not implemented.

protected:
    int32_t  _fd;
    uint32_t _pf;
};

/**
 * 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 IoRawSocket4 : public RawSocket4
{
public:
    IoRawSocket4(EventLoop& eventloop, uint32_t protocol, bool autohook = true)
	throw (RawSocket4Exception);

    ~IoRawSocket4();

protected:
    virtual void process_recv_data(const vector<uint8_t>& buf) = 0;

protected:
    void recv(int fd, SelectorMask m);

    bool eventloop_hook();

    void eventloop_unhook();

private:
    IoRawSocket4(const IoRawSocket4&);			// Not implemented.
    IoRawSocket4 operator=(const IoRawSocket4&);	// Not implemented.

private:
    enum { RECVBUF_BYTES = 65536 };
    EventLoop&		_eventloop;
    bool		_autohook;
    vector<uint8_t>	_recvbuf;
};

/**
 * A RawSocketClass that allows arbitrary filters to receive the data
 * associated with a raw socket.
 */
class FilterRawSocket4 : public IoRawSocket4
{
public:
    /**
     * Filter class.
     */
    class InputFilter {
    public:
	virtual ~InputFilter() {}
	/**
	 * Method invoked when data arrives on associated FilterRawSocket4
	 * instance.
	 */
	virtual void recv(const vector<uint8_t>& data) = 0;

	/**
	 * Method invoked by the destructor of the associated
	 * FilterRawSocket4 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
	 * FilterRawSocket4::remove_filter() since filter removal is
	 * automatically conducted.
	 */
	virtual void bye() = 0;
    };

public:
    FilterRawSocket4(EventLoop& eventloop, int protocol)
	throw (RawSocket4Exception);
    ~FilterRawSocket4();

    /** Add a filter to list of input filters.  The FilterRawSocket4 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 vector<uint8_t>& buf);

private:
    FilterRawSocket4(const FilterRawSocket4&);		 // Not implemented.
    FilterRawSocket4 operator=(const FilterRawSocket4&); // Not implemented.

protected:
    list<InputFilter*> _filters;
};

#endif // __FEA_RAWSOCK4_HH__

Generated by: pavlin on possum.icir.org on Wed Apr 13 21:53:05 2005, using kdoc $.