// -*- c-basic-offset: 4 -*- #ifndef CLICK_FROMHOST_HH #define CLICK_FROMHOST_HH #include #include #include #include #include CLICK_DECLS /* * =title FromHost.u * * =c * * FromHost(DEVNAME, ADDR/MASK [, GATEWAY, HEADROOM] [, I]) * * =s comm * * interface to /dev/tap or ethertap (user-level) * * =d * * Reads packets from and writes packets through the universal TUN/TAP * module in linux (the /dev/net/tun device). This allows a * user-level Click to hand packets to the virtual ethernet * device. FromHost will also transfer packets from the virtual * ethernet device. * * To use this element you must have * CONFIG_TUN * CONFIG_ETHERTAP * included in your kernel config (ie. the tun.o module is available). * Either modules or compiled in should work. * * * FromHost allocates a /dev/net/tun device (this might fail) and * runs ifconfig(8) to set the interface's local (i.e., kernel) * address to ADDR and the netmask to MASK. If a nonzero GATEWAY IP * address (which must be on the same network as the tun) is * specified, then FromHost tries to set up a default route through * that host. HEADROOM is the number of bytes left empty before the * packet data (to leave room for additional encapsulation * headers). Default HEADROOM is 0. * * Keyword arguments are: * * =over 8 * * =item ETHER * * Ethernet address. Specifies the fake device's Ethernet address. Default is * 00:a01:02:03:04:05. * * =back * * =n * * Linux will send ARP queries to the fake device. You must respond to these * queries in order to receive any IP packets, but you can obviously respond * with any Ethernet address you'd like. Here is one common idiom: * * tap0 :: FromHost(fake, 192.0.0.1/8) * -> fromhost_cl :: Classifier(12/0806, 12/0800); * fromhost_cl[0] -> ARPResponder(0.0.0.0/0 1:1:1:1:1:1) -> tap0; * fromhost_cl[1] -> ... // IP packets * * =e * * FromHost(fake, 192.0.0.1/8) -> ...; * * An error like "could not allocate a /dev/tap* device : No such file or * directory" usually means that you have not enabled /dev/tap* in your * kernel. * * =h dev_name read-only * Returns the name of the device that this element is using. * * =a * * ToHost.u, ifconfig(8) * */ class FromHost : public Element { public: enum ConfigurePhase { CONFIGURE_PHASE_FROMHOST = CONFIGURE_PHASE_DEFAULT, CONFIGURE_PHASE_TOHOST = CONFIGURE_PHASE_FROMHOST + 1 }; FromHost(); ~FromHost(); const char *class_name() const { return "FromHost"; } const char *port_count() const { return PORTS_0_1; } const char *processing() const { return PUSH; } int configure_phase() const { return CONFIGURE_PHASE_FROMHOST; } int configure(Vector &, ErrorHandler *); int initialize(ErrorHandler *); void cleanup(CleanupStage); void add_handlers(); void selected(int fd); bool run_task(); int fd() { return _fd; } String dev_name() { return _dev_name; } static String read_param(Element *, void *); private: enum { DEFAULT_MTU = 2048 }; int _fd; int _mtu_in; int _mtu_out; String _dev_name; IPAddress _near; IPAddress _mask; int _headroom; EtherAddress _macaddr; int try_linux_universal(ErrorHandler *); int try_tun(const String &, ErrorHandler *); int alloc_tun(ErrorHandler *); int setup_tun(struct in_addr near, struct in_addr mask, ErrorHandler *); void dealloc_tun(); Task _task; NotifierSignal _nonfull_signal; }; CLICK_ENDDECLS #endif