-rw-r--r-- | libopie2/opiecore/linux/.cvsignore | 6 | ||||
-rw-r--r-- | libopie2/opiecore/linux/linux.pro | 10 | ||||
-rw-r--r-- | libopie2/opiecore/linux/ofilenotify.cpp (renamed from libopie2/opiecore/ofilenotify.cpp) | 0 | ||||
-rw-r--r-- | libopie2/opiecore/linux/ofilenotify.h (renamed from libopie2/opiecore/ofilenotify.h) | 0 | ||||
-rw-r--r-- | libopie2/opiecore/linux/oinputsystem.cpp (renamed from libopie2/opiecore/oinputsystem.cpp) | 4 | ||||
-rw-r--r-- | libopie2/opiecore/linux/oinputsystem.h (renamed from libopie2/opiecore/oinputsystem.h) | 10 | ||||
-rw-r--r-- | libopie2/opiecore/linux/oinputsystemenums.h | 405 | ||||
-rw-r--r-- | libopie2/opiecore/linux/opcmciasystem.cpp | 142 | ||||
-rw-r--r-- | libopie2/opiecore/linux/opcmciasystem.h | 129 | ||||
-rw-r--r-- | libopie2/opiecore/opiecore.pro | 16 | ||||
-rw-r--r-- | libopie2/opiemm/osoundsystem.cpp | 12 | ||||
-rw-r--r-- | libopie2/opiemm/osoundsystem.h | 13 | ||||
-rw-r--r-- | libopie2/opienet/opcap.cpp | 2 | ||||
-rw-r--r-- | libopie2/opienet/opcap.h | 1 |
14 files changed, 718 insertions, 32 deletions
diff --git a/libopie2/opiecore/linux/.cvsignore b/libopie2/opiecore/linux/.cvsignore new file mode 100644 index 0000000..972e959 --- a/dev/null +++ b/libopie2/opiecore/linux/.cvsignore @@ -0,0 +1,6 @@ +Makefile* +moc* +*moc +*.o +~* +obj diff --git a/libopie2/opiecore/linux/linux.pro b/libopie2/opiecore/linux/linux.pro new file mode 100644 index 0000000..c396e59 --- a/dev/null +++ b/libopie2/opiecore/linux/linux.pro @@ -0,0 +1,10 @@ +HEADERS += \ + linux/ofilenotify.h \ + linux/oinputsystem.h \ + linux/opcmciasystem.h + +SOURCES += \ + linux/ofilenotify.cpp \ + linux/oinputsystem.cpp \ + linux/opcmciasystem.cpp + diff --git a/libopie2/opiecore/ofilenotify.cpp b/libopie2/opiecore/linux/ofilenotify.cpp index 36ec6bf..36ec6bf 100644 --- a/libopie2/opiecore/ofilenotify.cpp +++ b/libopie2/opiecore/linux/ofilenotify.cpp diff --git a/libopie2/opiecore/ofilenotify.h b/libopie2/opiecore/linux/ofilenotify.h index 05343b9..05343b9 100644 --- a/libopie2/opiecore/ofilenotify.h +++ b/libopie2/opiecore/linux/ofilenotify.h diff --git a/libopie2/opiecore/oinputsystem.cpp b/libopie2/opiecore/linux/oinputsystem.cpp index 7397814..bad27ed 100644 --- a/libopie2/opiecore/oinputsystem.cpp +++ b/libopie2/opiecore/linux/oinputsystem.cpp @@ -1,222 +1,222 @@ /* This file is part of the Opie Project =. (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - - . .-<_> .<> Foundation; either version 2 of the License, - ._= =} : or (at your option) any later version. + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "oinputsystem.h" using namespace Opie::Core; /* QT */ #include <qdir.h> #include <qfile.h> /* STD */ #include <errno.h> #include <string.h> #include <sys/fcntl.h> #include <sys/ioctl.h> #include <unistd.h> #define BUFSIZE 256 #define BIT_MASK( name, numbits ) \ unsigned short name[ ((numbits) - 1) / (sizeof( short ) * 8) + 1 ]; \ memset( name, 0, sizeof( name ) ) #define BIT_TEST( bitmask, bit ) \ ( bitmask[ (bit) / sizeof(short) / 8 ] & (1u << ( (bit) % (sizeof(short) * 8))) ) /*====================================================================================== * OInputSystem *======================================================================================*/ OInputSystem* OInputSystem::_instance = 0; OInputSystem::OInputSystem() : QObject() { qDebug( "OInputSystem::OInputSystem()" ); synchronize(); } void OInputSystem::synchronize() { qDebug( "OInputSystem::synchronize()" ); QDir devInput( "/dev/input/" ); if ( devInput.exists() ) { QStringList devInputFiles = devInput.entryList( QDir::System, QDir::Name ); for ( QStringList::Iterator it = devInputFiles.begin(); it != devInputFiles.end(); ++it ) { QString absPath = devInput.absFilePath( *it ); bool isValid = OInputDevice::isValid( absPath ); qDebug( "OInputSystem::synchronize() - checking if '%s' is a valid input system node... '%s' [%s]", (const char*) absPath, isValid ? "yes" : "no", isValid ? "(ok)" : strerror( errno ) ); if ( isValid ) _devices.insert( *it, new OInputDevice( this, absPath ) ); } } qDebug( "OInputSystem::synchronize() done" ); if ( !_devices.count() ) qWarning( "OInputSystem::no devices found" ); } OInputSystem::~OInputSystem() { qDebug( "OInputSystem::~OInputSystem()" ); } int OInputSystem::count() const { return _devices.count(); } OInputDevice* OInputSystem::device( const QString& device ) const { return _devices[device]; } OInputSystem* OInputSystem::instance() { if ( !_instance ) _instance = new OInputSystem(); return _instance; } OInputSystem::DeviceIterator OInputSystem::iterator() const { return OInputSystem::DeviceIterator( _devices ); } /*====================================================================================== * OInputDevice *======================================================================================*/ OInputDevice::OInputDevice( QObject* parent, const char* name ) : QObject( parent, name ) { qDebug( "OInputDevice::OInputDevice( '%s' )", name ); _fd = ::open( name, O_RDONLY ); if ( _fd == -1 ) { qDebug( "OInputDevice::OInputDevice() - Warning: couldn't open %s (%s)", name, strerror( errno ) ); } } OInputDevice::~OInputDevice() { qDebug( "OInputDevice::~OInputDevice()" ); } QString OInputDevice::identity() const { char buf[BUFSIZE] = "<unknown>"; ::ioctl( _fd, EVIOCGNAME(sizeof buf), buf ); return buf; } QString OInputDevice::path() const { char buf[BUFSIZE] = "<unknown>"; ::ioctl( _fd, EVIOCGPHYS(sizeof buf), buf ); return buf; } QString OInputDevice::uniq() const { char buf[BUFSIZE] = "<unknown>"; ::ioctl( _fd, EVIOCGUNIQ(sizeof buf), buf ); return buf; } bool OInputDevice::hasFeature( Feature bit ) const { BIT_MASK( features, EV_MAX ); if( ioctl( _fd, EVIOCGBIT( 0, EV_MAX ), features) < 0 ) { perror( "EVIOCGBIT" ); return false; } else return BIT_TEST( features, bit ); } bool OInputDevice::isHeld( Key bit ) const { BIT_MASK( keys, KEY_MAX ); if( ioctl( _fd, EVIOCGKEY( sizeof(keys) ), keys ) < 0 ) { perror( "EVIOCGKEY" ); return false; } else { return BIT_TEST( keys, bit ); } } QString OInputDevice::globalKeyMask() const { BIT_MASK( keys, KEY_MAX ); if( ioctl( _fd, EVIOCGKEY( sizeof(keys) ), keys ) < 0 ) { perror( "EVIOCGKEY" ); return QString::null; } else { QString keymask; for ( int i = 0; i < KEY_MAX; ++i ) { if ( BIT_TEST( keys, i ) ) keymask.append( QString().sprintf( "%0d, ", i ) ); } return keymask; } } bool OInputDevice::isValid( const QString& path ) { char buf[BUFSIZE] = "<unknown>"; int fd = ::open( (const char*) path, O_RDONLY ); if ( fd < 0 ) return false; int res = ::ioctl( fd, EVIOCGNAME(sizeof buf), buf ); ::close( fd ); return res >= 0; } diff --git a/libopie2/opiecore/oinputsystem.h b/libopie2/opiecore/linux/oinputsystem.h index 6f822a1..9676e73 100644 --- a/libopie2/opiecore/oinputsystem.h +++ b/libopie2/opiecore/linux/oinputsystem.h @@ -1,142 +1,142 @@ /* This file is part of the Opie Project =. (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - - . .-<_> .<> Foundation; either version 2 of the License, - ._= =} : or (at your option) any later version. + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OINPUTSYSTEM_H #define OINPUTSYSTEM_H #include "linux_input.h" /* QT */ #include <qobject.h> #include <qdict.h> namespace Opie { namespace Core { class OInputDevice; /** - * @brief A container class for all input devices + * @brief A container class for the Linux input device subsystem * - * This class provides access to all available input system devices of your computer. + * This class provides access to all available input system devices of your device. * - * @author Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> + * @author Michael 'Mickey' Lauer <mickey@Vanille.de> */ class OInputSystem : public QObject { public: typedef QDict<OInputDevice> DeviceMap; typedef QDictIterator<OInputDevice> DeviceIterator; /** * @returns the number of available input devices */ int count() const; /** * @returns a pointer to the (one and only) @ref OInputSystem instance. */ static OInputSystem* instance(); /** * @returns an iterator usable for iterating through all network interfaces. */ DeviceIterator iterator() const; /** * @returns a pointer to the @ref OAudioInterface object for the specified @a interface or 0, if not found * @see OAudioInterface */ OInputDevice* device( const QString& interface ) const; /** * @internal Rebuild the internal interface database * @note Sometimes it might be useful to call this from client code, */ void synchronize(); /** * @internal destructor */ ~OInputSystem(); protected: OInputSystem(); static OInputSystem* _instance; DeviceMap _devices; }; class OInputDevice : public QObject { public: OInputDevice( QObject* parent, const char* name = 0 ); ~OInputDevice(); #include "oinputsystemenums.h" public: /** * @returns the identity string of this input device */ QString identity() const; /** * @returns the path of this input device */ QString path() const; /** * @returns a unique identifier for this input device * @note Only a few devices support this */ QString uniq() const; /** * @returns whether a certain @a Feature is being supported by this device */ bool hasFeature( Feature ) const; /** * @returns whether a given @a Key or Button is being held at the moment */ bool isHeld( Key ) const; /** * @internal * @returns a string containing a printable form of the global keymask */ QString globalKeyMask() const; /** * @internal * @returns whether a certain @a path corresponds to an input device */ static bool isValid( const QString& path ); private: int _fd; input_id _id; }; } } #endif // OINPUTSYSTEM_H diff --git a/libopie2/opiecore/linux/oinputsystemenums.h b/libopie2/opiecore/linux/oinputsystemenums.h new file mode 100644 index 0000000..3461e5a --- a/dev/null +++ b/libopie2/opiecore/linux/oinputsystemenums.h @@ -0,0 +1,405 @@ + + enum Feature + { + Synchronous = EV_SYN, + Keys = EV_KEY, + Relative = EV_REL, + Absolute = EV_ABS, + Miscellaneous = EV_MSC, + Leds = EV_LED, + Sound = EV_SND, + AutoRepeat = EV_REP, + ForceFeedback = EV_FF, + PowerManagement = EV_PWR, + ForceFeedbackStatus = EV_FF_STATUS, + }; + + enum Bus + { + PCI = BUS_PCI, + ISAPNP = BUS_ISAPNP, + HIL = BUS_HIL, + BLUETOOTH = BUS_BLUETOOTH, + ISA = BUS_ISA, + I8042 = BUS_I8042, + XTKBD = BUS_XTKBD, + RS232 = BUS_RS232, + GAMEPORT = BUS_GAMEPORT, + PARPORT = BUS_PARPORT, + AMIGA = BUS_AMIGA, + ADB = BUS_ADB, + I2C = BUS_I2C, + HOST = BUS_HOST, + }; + + enum Key + { + Key_RESERVED = 0, + Key_ESC = 1, + Key_1 = 2, + Key_2 = 3, + Key_3 = 4, + Key_4 = 5, + Key_5 = 6, + Key_6 = 7, + Key_7 = 8, + Key_8 = 9, + Key_9 = 10, + Key_0 = 11, + Key_MINUS = 12, + Key_EQUAL = 13, + Key_BACKSPACE = 14, + Key_TAB = 15, + Key_Q = 16, + Key_W = 17, + Key_E = 18, + Key_R = 19, + Key_T = 20, + Key_Y = 21, + Key_U = 22, + Key_I = 23, + Key_O = 24, + Key_P = 25, + Key_LEFTBRACE = 26, + Key_RIGHTBRACE = 27, + Key_ENTER = 28, + Key_LEFTCTRL = 29, + Key_A = 30, + Key_S = 31, + Key_D = 32, + Key_F = 33, + Key_G = 34, + Key_H = 35, + Key_J = 36, + Key_K = 37, + Key_L = 38, + Key_SEMICOLON = 39, + Key_APOSTROPHE = 40, + Key_GRAVE = 41, + Key_LEFTSHIFT = 42, + Key_BACKSLASH = 43, + Key_Z = 44, + Key_X = 45, + Key_C = 46, + Key_V = 47, + Key_B = 48, + Key_N = 49, + Key_M = 50, + Key_COMMA = 51, + Key_DOT = 52, + Key_SLASH = 53, + Key_RIGHTSHIFT = 54, + Key_KPASTERISK = 55, + Key_LEFTALT = 56, + Key_SPACE = 57, + Key_CAPSLOCK = 58, + Key_F1 = 59, + Key_F2 = 60, + Key_F3 = 61, + Key_F4 = 62, + Key_F5 = 63, + Key_F6 = 64, + Key_F7 = 65, + Key_F8 = 66, + Key_F9 = 67, + Key_F10 = 68, + Key_NUMLOCK = 69, + Key_SCROLLLOCK = 70, + Key_KP7 = 71, + Key_KP8 = 72, + Key_KP9 = 73, + Key_KPMINUS = 74, + Key_KP4 = 75, + Key_KP5 = 76, + Key_KP6 = 77, + Key_KPPLUS = 78, + Key_KP1 = 79, + Key_KP2 = 80, + Key_KP3 = 81, + Key_KP0 = 82, + Key_KPDOT = 83, + + Key_ZENKAKUHANKAKU = 85, + Key_102ND = 86, + Key_F11 = 87, + Key_F12 = 88, + Key_RO = 89, + Key_KATAKANA = 90, + Key_HIRAGANA = 91, + Key_HENKAN = 92, + Key_KATAKANAHIRAGANA = 93, + Key_MUHENKAN = 94, + Key_KPJPCOMMA = 95, + Key_KPENTER = 96, + Key_RIGHTCTRL = 97, + Key_KPSLASH = 98, + Key_SYSRQ = 99, + Key_RIGHTALT = 100, + Key_LINEFEED = 101, + Key_HOME = 102, + Key_UP = 103, + Key_PAGEUP = 104, + Key_LEFT = 105, + Key_RIGHT = 106, + Key_END = 107, + Key_DOWN = 108, + Key_PAGEDOWN = 109, + Key_INSERT = 110, + Key_DELETE = 111, + Key_MACRO = 112, + Key_MUTE = 113, + Key_VOLUMEDOWN = 114, + Key_VOLUMEUP = 115, + Key_POWER = 116, + Key_KPEQUAL = 117, + Key_KPPLUSMINUS = 118, + Key_PAUSE = 119, + + Key_KPCOMMA = 121, + Key_HANGUEL = 122, + Key_HANJA = 123, + Key_YEN = 124, + Key_LEFTMETA = 125, + Key_RIGHTMETA = 126, + Key_COMPOSE = 127, + + Key_STOP = 128, + Key_AGAIN = 129, + Key_PROPS = 130, + Key_UNDO = 131, + Key_FRONT = 132, + Key_COPY = 133, + Key_OPEN = 134, + Key_PASTE = 135, + Key_FIND = 136, + Key_CUT = 137, + Key_HELP = 138, + Key_MENU = 139, + Key_CALC = 140, + Key_SETUP = 141, + Key_SLEEP = 142, + Key_WAKEUP = 143, + Key_FILE = 144, + Key_SENDFILE = 145, + Key_DELETEFILE = 146, + Key_XFER = 147, + Key_PROG1 = 148, + Key_PROG2 = 149, + Key_WWW = 150, + Key_MSDOS = 151, + Key_COFFEE = 152, + Key_DIRECTION = 153, + Key_CYCLEWINDOWS = 154, + Key_MAIL = 155, + Key_BOOKMARKS = 156, + Key_COMPUTER = 157, + Key_BACK = 158, + Key_FORWARD = 159, + Key_CLOSECD = 160, + Key_EJECTCD = 161, + Key_EJECTCLOSECD = 162, + Key_NEXTSONG = 163, + Key_PLAYPAUSE = 164, + Key_PREVIOUSSONG = 165, + Key_STOPCD = 166, + Key_RECORD = 167, + Key_REWIND = 168, + Key_PHONE = 169, + Key_ISO = 170, + Key_CONFIG = 171, + Key_HOMEPAGE = 172, + Key_REFRESH = 173, + Key_EXIT = 174, + Key_MOVE = 175, + Key_EDIT = 176, + Key_SCROLLUP = 177, + Key_SCROLLDOWN = 178, + Key_KPLEFTPAREN = 179, + Key_KPRIGHTPAREN = 180, + + Key_F13 = 183, + Key_F14 = 184, + Key_F15 = 185, + Key_F16 = 186, + Key_F17 = 187, + Key_F18 = 188, + Key_F19 = 189, + Key_F20 = 190, + Key_F21 = 191, + Key_F22 = 192, + Key_F23 = 193, + Key_F24 = 194, + + Key_PLAYCD = 200, + Key_PAUSECD = 201, + Key_PROG3 = 202, + Key_PROG4 = 203, + Key_SUSPEND = 205, + Key_CLOSE = 206, + Key_PLAY = 207, + Key_FASTFORWARD = 208, + Key_BASSBOOST = 209, + Key_PRINT = 210, + Key_HP = 211, + Key_CAMERA = 212, + Key_SOUND = 213, + Key_QUESTION = 214, + Key_EMAIL = 215, + Key_CHAT = 216, + Key_SEARCH = 217, + Key_CONNECT = 218, + Key_FINANCE = 219, + Key_SPORT = 220, + Key_SHOP = 221, + Key_ALTERASE = 222, + Key_CANCEL = 223, + Key_BRIGHTNESSDOWN = 224, + Key_BRIGHTNESSUP = 225, + Key_MEDIA = 226, + + Key_UNKNOWN = 240, + + Button_MISC = 0x100, + Button_0 = 0x100, + Button_1 = 0x101, + Button_2 = 0x102, + Button_3 = 0x103, + Button_4 = 0x104, + Button_5 = 0x105, + Button_6 = 0x106, + Button_7 = 0x107, + Button_8 = 0x108, + Button_9 = 0x109, + + Button_MOUSE = 0x110, + Button_LEFT = 0x110, + Button_RIGHT = 0x111, + Button_MIDDLE = 0x112, + Button_SIDE = 0x113, + Button_EXTRA = 0x114, + Button_FORWARD = 0x115, + Button_BACK = 0x116, + Button_TASK = 0x117, + + Button_JOYSTICK = 0x120, + Button_TRIGGER = 0x120, + Button_THUMB = 0x121, + Button_THUMB2 = 0x122, + Button_TOP = 0x123, + Button_TOP2 = 0x124, + Button_PINKIE = 0x125, + Button_BASE = 0x126, + Button_BASE2 = 0x127, + Button_BASE3 = 0x128, + Button_BASE4 = 0x129, + Button_BASE5 = 0x12a, + Button_BASE6 = 0x12b, + Button_DEAD = 0x12f, + + Button_GAMEPAD = 0x130, + Button_A = 0x130, + Button_B = 0x131, + Button_C = 0x132, + Button_X = 0x133, + Button_Y = 0x134, + Button_Z = 0x135, + Button_TL = 0x136, + Button_TR = 0x137, + Button_TL2 = 0x138, + Button_TR2 = 0x139, + Button_SELECT = 0x13a, + Button_START = 0x13b, + Button_MODE = 0x13c, + Button_THUMBL = 0x13d, + Button_THUMBR = 0x13e, + + Button_DIGI = 0x140, + Button_TOOL_PEN = 0x140, + Button_TOOL_RUBBER = 0x141, + Button_TOOL_BRUSH = 0x142, + Button_TOOL_PENCIL = 0x143, + Button_TOOL_AIRBRUSH = 0x144, + Button_TOOL_FINGER = 0x145, + Button_TOOL_MOUSE = 0x146, + Button_TOOL_LENS = 0x147, + Button_TOUCH = 0x14a, + Button_STYLUS = 0x14b, + Button_STYLUS2 = 0x14c, + Button_TOOL_DOUBLETAP = 0x14d, + Button_TOOL_TRIPLETAP = 0x14e, + + Button_WHEEL = 0x150, + Button_GEAR_DOWN = 0x150, + Button_GEAR_UP = 0x151, + + Key_OK = 0x160, + Key_SELECT = 0x161, + Key_GOTO = 0x162, + Key_CLEAR = 0x163, + Key_POWER2 = 0x164, + Key_OPTION = 0x165, + Key_INFO = 0x166, + Key_TIME = 0x167, + Key_VENDOR = 0x168, + Key_ARCHIVE = 0x169, + Key_PROGRAM = 0x16a, + Key_CHANNEL = 0x16b, + Key_FAVORITES = 0x16c, + Key_EPG = 0x16d, + Key_PVR = 0x16e, + Key_MHP = 0x16f, + Key_LANGUAGE = 0x170, + Key_TITLE = 0x171, + Key_SUBTITLE = 0x172, + Key_ANGLE = 0x173, + Key_ZOOM = 0x174, + Key_MODE = 0x175, + Key_KEYBOARD = 0x176, + Key_SCREEN = 0x177, + Key_PC = 0x178, + Key_TV = 0x179, + Key_TV2 = 0x17a, + Key_VCR = 0x17b, + Key_VCR2 = 0x17c, + Key_SAT = 0x17d, + Key_SAT2 = 0x17e, + Key_CD = 0x17f, + Key_TAPE = 0x180, + Key_RADIO = 0x181, + Key_TUNER = 0x182, + Key_PLAYER = 0x183, + Key_TEXT = 0x184, + Key_DVD = 0x185, + Key_AUX = 0x186, + Key_MP3 = 0x187, + Key_AUDIO = 0x188, + Key_VIDEO = 0x189, + Key_DIRECTORY = 0x18a, + Key_LIST = 0x18b, + Key_MEMO = 0x18c, + Key_CALENDAR = 0x18d, + Key_RED = 0x18e, + Key_GREEN = 0x18f, + Key_YELLOW = 0x190, + Key_BLUE = 0x191, + Key_CHANNELUP = 0x192, + Key_CHANNELDOWN = 0x193, + Key_FIRST = 0x194, + Key_LAST = 0x195, + Key_AB = 0x196, + Key_NEXT = 0x197, + Key_RESTART = 0x198, + Key_SLOW = 0x199, + Key_SHUFFLE = 0x19a, + Key_BREAK = 0x19b, + Key_PREVIOUS = 0x19c, + Key_DIGITS = 0x19d, + Key_TEEN = 0x19e, + Key_TWEN = 0x19f, + + Key_DEL_EOL = 0x1c0, + Key_DEL_EOS = 0x1c1, + Key_INS_LINE = 0x1c2, + Key_DEL_LINE = 0x1c3, + }; + diff --git a/libopie2/opiecore/linux/opcmciasystem.cpp b/libopie2/opiecore/linux/opcmciasystem.cpp new file mode 100644 index 0000000..a924696 --- a/dev/null +++ b/libopie2/opiecore/linux/opcmciasystem.cpp @@ -0,0 +1,142 @@ +/* + This file is part of the Opie Project + =. (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "opcmciasystem.h" +using namespace Opie::Core; + +/* OPIE */ +#include <opie2/odebug.h> + +/* QT */ +#include <qfile.h> +#include <qtextstream.h> + +/* STD */ +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> + +/*====================================================================================== + * OPcmciaSystem + *======================================================================================*/ + +OPcmciaSystem* OPcmciaSystem::_instance = 0; + +OPcmciaSystem::OPcmciaSystem() +{ + qDebug( "OPcmciaSystem::OPcmciaSystem()" ); + synchronize(); +} + +void OPcmciaSystem::synchronize() +{ + qDebug( "OPcmciaSystem::synchronize()" ); + _interfaces.clear(); + + //FIXME: Use cardmgr subsystem ioctls + + QString fileName; + if ( QFile::exists( "/var/run/stab" ) ) { fileName = "/var/run/stab"; } + else if ( QFile::exists( "/var/state/pcmcia/stab" ) ) { fileName = "/var/state/pcmcia/stab"; } + else { fileName = "/var/lib/pcmcia/stab"; } + QFile cardinfofile( fileName ); + if ( !cardinfofile.exists() || !cardinfofile.open( IO_ReadOnly ) ) + { + qWarning( "pcmcia info file not found or unaccessible" ); + return; + } + QTextStream cardinfo( &cardinfofile ); + while ( !cardinfo.atEnd() ) + { + QString line = cardinfo.readLine(); + if ( line.startsWith( "Socket" ) ) + { + int mid = line.find( ':' ); + QString name = line.right( line.length() - mid - 1 ); + QString id = line.right( line.length() - mid + 1 ); + if ( mid ) _interfaces.insert( name, new OPcmciaCard( this, (const char*) id ) ); + } + else + { + continue; + } + } +} + + +int OPcmciaSystem::count() const +{ + return _interfaces.count(); +} + + +OPcmciaCard* OPcmciaSystem::card( const QString& iface ) const +{ + return _interfaces[iface]; +} + + +OPcmciaSystem* OPcmciaSystem::instance() +{ + if ( !_instance ) _instance = new OPcmciaSystem(); + return _instance; +} + + +OPcmciaSystem::CardIterator OPcmciaSystem::iterator() const +{ + return OPcmciaSystem::CardIterator( _interfaces ); +} + + +/*====================================================================================== + * OPcmciaCard + *======================================================================================*/ + +OPcmciaCard::OPcmciaCard( QObject* parent, const char* name ) + :QObject( parent, name ) +{ + odebug << "OPcmciaCard::OPcmciaCard()" << oendl; + init(); +} + + +OPcmciaCard::~OPcmciaCard() +{ +} + + +void OPcmciaCard::init() +{ +} + + diff --git a/libopie2/opiecore/linux/opcmciasystem.h b/libopie2/opiecore/linux/opcmciasystem.h new file mode 100644 index 0000000..694bf16 --- a/dev/null +++ b/libopie2/opiecore/linux/opcmciasystem.h @@ -0,0 +1,129 @@ +/* + This file is part of the Opie Project + =. (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef OPCMCIASYSTEM_H +#define OPCMCIASYSTEM_H + +#include <qobject.h> +#include <qdict.h> +#include <qmap.h> + +namespace Opie { +namespace Core { + +class OPcmciaCard; + +/*====================================================================================== + * OPcmciaSystem + *======================================================================================*/ + +/** + * @brief A container class for the linux pcmcia subsystem + * + * This class provides access to all available pcmcia/cf cards on your device. + * + * @author Michael 'Mickey' Lauer <mickey@Vanille.de> + */ +class OPcmciaSystem : public QObject +{ + Q_OBJECT + + public: + typedef QDict<OPcmciaCard> CardMap; + typedef QDictIterator<OPcmciaCard> CardIterator; + + public: + /** + * @returns the number of available interfaces + */ + int count() const; + /** + * @returns a pointer to the (one and only) @ref OSystem instance. + */ + static OPcmciaSystem* instance(); + /** + * @returns an iterator usable for iterating through all sound cards. + */ + CardIterator iterator() const; + /** + * @returns a pointer to the @ref OAudioInterface object for the specified @a interface or 0, if not found + * @see OAudioInterface + */ + OPcmciaCard* card( const QString& interface ) const; + /** + * @internal Rebuild the internal interface database + * @note Sometimes it might be useful to call this from client code, + * e.g. after issuing a cardctl insert + */ + void synchronize(); + + protected: + OPcmciaSystem(); + + private: + static OPcmciaSystem* _instance; + CardMap _interfaces; + class Private; + Private *d; +}; + + +/*====================================================================================== + * OPcmciaCard + *======================================================================================*/ + +class OPcmciaCard : public QObject +{ + Q_OBJECT + + public: + /** + * Constructor. Normally you don't create @ref OPcmciaCard objects yourself, + * but access them via @ref OPcmciaSystem::card(). + */ + OPcmciaCard( QObject* parent, const char* name ); + /** + * Destructor. + */ + virtual ~OPcmciaCard(); + + protected: + + private: + void init(); + private: + class Private; + Private *d; +}; + + +} +} + +#endif // OPCMCIASYSTEM_H diff --git a/libopie2/opiecore/opiecore.pro b/libopie2/opiecore/opiecore.pro index 84f3343..cbb7e04 100644 --- a/libopie2/opiecore/opiecore.pro +++ b/libopie2/opiecore/opiecore.pro @@ -1,65 +1,59 @@ TEMPLATE = lib CONFIG += qt warn_on DESTDIR = $(OPIEDIR)/lib HEADERS = oapplication.h \ oconfig.h \ odebug.h \ oglobal.h \ oglobalsettings.h \ - oinputsystem.h \ okeyconfigmanager.h \ okeyfilter.h \ opluginloader.h \ oprocess.h \ oprocctrl.h \ oresource.h \ osharedpointer.h \ osmartpointer.h \ ostorageinfo.h \ xmltree.h SOURCES = oapplication.cpp \ oconfig.cpp \ odebug.cpp \ oglobal.cpp \ oglobalsettings.cpp \ - oinputsystem.cpp \ okeyconfigmanager.cpp \ okeyfilter.cpp \ opluginloader.cpp \ oprocess.cpp \ oprocctrl.cpp \ oresource.cpp \ osmartpointer.cpp \ ostorageinfo.cpp \ xmltree.cpp -# The following files are currently not compileable on mac ! -# Therfore I removed them from the build .. (eilers) - -CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX ) -!contains( CONFTEST, y ) { -HEADERS += ofilenotify.h -SOURCES += ofilenotify.cpp +# Disable Linux-only subsystems for MAC build +!contains( CONFIG_TARGET_MACOSX, y ) { +include ( linux/linux.pro ) } else { - message( "ofilenotify is not available in a mac build !" ) + message( "disabling linux-only subsystems for MAC build" ) } include( device/device.pro ) INTERFACES = TARGET = opiecore2 -VERSION = 1.9.3 +VERSION = 1.9.4 INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include !contains( platform, x11 ) { LIBS = -lqpe include( $(OPIEDIR)/include.pro ) } contains( platform, x11 ) { LIBS = -L$(OPIEDIR)/lib -Wl,-rpath,$(OPIEDIR)/lib } diff --git a/libopie2/opiemm/osoundsystem.cpp b/libopie2/opiemm/osoundsystem.cpp index 2956682..6f849cd 100644 --- a/libopie2/opiemm/osoundsystem.cpp +++ b/libopie2/opiemm/osoundsystem.cpp @@ -1,315 +1,317 @@ /* This file is part of the Opie Project - (C) 2003-2005 Michael 'Mickey' Lauer <mickey@Vanille.de> - =. + =. (C) 2003-2005 Michael 'Mickey' Lauer <mickey@Vanille.de> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <opie2/osoundsystem.h> +#include "osoundsystem.h" +using namespace Opie::MM; + +/* OPIE */ #include <opie2/odebug.h> +using namespace Opie::Core; +/* STD */ #include <errno.h> #include <fcntl.h> #include <string.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/soundcard.h> #include <sys/stat.h> static const char* device_label[] = SOUND_DEVICE_LABELS; static int max_device_nr = sizeof device_label / sizeof (const char*); -using namespace Opie::Core; -using namespace Opie::MM; /*====================================================================================== * OSoundSystem *======================================================================================*/ OSoundSystem* OSoundSystem::_instance = 0; OSoundSystem::OSoundSystem() { odebug << "OSoundSystem::OSoundSystem()" << oendl; synchronize(); } void OSoundSystem::synchronize() { _interfaces.clear(); _interfaces.insert( "soundcard", new OSoundCard( this, "soundcard" ) ); /* QString str; QFile f( "/dev/sound" ); bool hasFile = f.open( IO_ReadOnly ); if ( !hasFile ) { odebug << "OSoundSystem: /dev/sound not existing. No sound devices available" << oendl; return; } QTextStream s( &f ); s.readLine(); s.readLine(); while ( !s.atEnd() ) { s >> str; str.truncate( str.find( ':' ) ); odebug << "OSoundSystem: found interface '" << str << "'" << oendl; OAudioInterface* iface; iface = new OAudioInterface( this, (const char*) str ); _interfaces.insert( str, iface ); s.readLine(); } */ } int OSoundSystem::count() const { return _interfaces.count(); } OSoundCard* OSoundSystem::card( const QString& iface ) const { return _interfaces[iface]; } OSoundSystem* OSoundSystem::instance() { if ( !_instance ) _instance = new OSoundSystem(); return _instance; } OSoundSystem::CardIterator OSoundSystem::iterator() const { return OSoundSystem::CardIterator( _interfaces ); } /*====================================================================================== * OSoundCard *======================================================================================*/ OSoundCard::OSoundCard( QObject* parent, const char* name ) :QObject( parent, name ), _audio( 0 ), _mixer( 0 ) { odebug << "OSoundCard::OSoundCard()" << oendl; init(); } OSoundCard::~OSoundCard() { } void OSoundCard::init() { #ifdef QT_QWS_DEVFS _audio = new OAudioInterface( this, "/dev/sound/dsp" ); _mixer = new OMixerInterface( this, "/dev/sound/mixer" ); #else _audio = new OAudioInterface( this, "/dev/dsp" ); _mixer = new OMixerInterface( this, "/dev/mixer" ); #endif } /*====================================================================================== * OAudioInterface *======================================================================================*/ OAudioInterface::OAudioInterface( QObject* parent, const char* name ) :QObject( parent, name ), _sfd(0) { odebug << "OAudioInterface::OAudioInterface()" << oendl; init(); } OAudioInterface::~OAudioInterface() { } void OAudioInterface::init() { } /*====================================================================================== * OMixerInterface *======================================================================================*/ OMixerInterface::OMixerInterface( QObject* parent, const char* name ) :QObject( parent, name ), _devmask( 0 ), _recmask( 0 ), _stmask( 0 ) { odebug << "OMixerInterface::OMixerInterface()" << oendl; init(); } OMixerInterface::~OMixerInterface() { } void OMixerInterface::init() { // open the device _fd = ::open( name(), O_RDWR ); if ( _fd == -1 ) { owarn << "OMixerInterface::init(): Can't open mixer " << name() << oendl; return; } // construct the device capabilities if ( ioctl( _fd, SOUND_MIXER_READ_CAPS, &_capmask ) != -1 ) { odebug << "OMixerInterface::init() - capmask = " << _capmask << oendl; } if ( ioctl( _fd, SOUND_MIXER_READ_DEVMASK, &_devmask ) != -1 ) { odebug << "OMixerInterface::init() - devmask = " << _devmask << oendl; } if ( ioctl( _fd, SOUND_MIXER_READ_RECMASK, &_recmask ) != -1 ) { odebug << "OMixerInterface::init() - recmask = " << _recmask << oendl; } if ( ioctl( _fd, SOUND_MIXER_READ_STEREODEVS, &_stmask ) != -1 ) { odebug << "OMixerInterface::init() - stereomask = " << _stmask << oendl; } for ( int i = 0; i < max_device_nr; ++i ) { if ( _devmask & ( 1 << i ) ) { _channels.insert( QString( device_label[i] ).stripWhiteSpace(), i ); odebug << "OMixerInterface::init() - channel '" << device_label[i] << "'" << oendl; } } } QStringList OMixerInterface::allChannels() const { ChannelIterator it = _channels.begin(); QStringList channels; while ( it != _channels.end() ) { channels += it++.key(); } return channels; } QStringList OMixerInterface::recChannels() const { ChannelIterator it = _channels.begin(); QStringList channels; while ( it != _channels.end() ) { if ( _recmask & ( 1 << _channels[it.key()] ) ) channels += it++.key(); } return channels; } QStringList OMixerInterface::playChannels() const { return allChannels(); } bool OMixerInterface::hasMultipleRecording() const { return !( _capmask & SOUND_CAP_EXCL_INPUT ); } bool OMixerInterface::hasChannel( const QString& channel ) const { return _channels.contains( channel ); } bool OMixerInterface::isStereo( const QString& channel ) const { return _channels.contains( channel ) && ( _stmask & ( 1 << _channels[channel] ) ); } bool OMixerInterface::isRecordable( const QString& channel ) const { return _channels.contains( channel ) && ( _recmask & ( 1 << _channels[channel] ) ); } void OMixerInterface::setVolume( const QString& channel, int left, int right ) { int volume = left; volume |= ( right == -1 ) ? left << 8 : right << 8; if ( _channels.contains( channel ) ) { int result = ioctl( _fd, MIXER_WRITE( _channels[channel] ), &volume ); if ( result == -1 ) { owarn << "Can't set volume: " << strerror( errno ) << oendl; } else { if ( result & 0xff != left ) { owarn << "Device adjusted volume from " << left << " to " << (result & 0xff) << oendl; } } } } int OMixerInterface::volume( const QString& channel ) const { int volume; if ( _channels.contains( channel ) ) { if ( ioctl( _fd, MIXER_READ( _channels[channel] ), &volume ) == -1 ) { owarn << "Can't get volume: " << strerror( errno ) << oendl; } else return volume; } return -1; } diff --git a/libopie2/opiemm/osoundsystem.h b/libopie2/opiemm/osoundsystem.h index 5f6fb7a..1e48f5c 100644 --- a/libopie2/opiemm/osoundsystem.h +++ b/libopie2/opiemm/osoundsystem.h @@ -1,245 +1,244 @@ /* This file is part of the Opie Project - (C) 2003-2005 Michael 'Mickey' Lauer <mickey@Vanille.de> - =. + =. (C) 2003-2005 Michael 'Mickey' Lauer <mickey@Vanille.de> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - - . .-<_> .<> Foundation; either version 2 of the License, - ._= =} : or (at your option) any later version. + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OSOUNDSYSTEM_H #define OSOUNDSYSTEM_H #include <qobject.h> #include <qdict.h> #include <qmap.h> namespace Opie { namespace MM { class OAudioInterface; class OMixerInterface; class OSoundCard; /*====================================================================================== * OSoundSystem *======================================================================================*/ /** - * @brief A container class for all audio interfaces + * @brief A container class for the Linux OSS/ALSA audio subsystem * - * This class provides access to all available audio/midi/sequencer interfaces of your computer. + * This class provides access to all available audio/midi/sequencer interfaces of your device. * - * @author Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> + * @author Michael 'Mickey' Lauer <mickey@Vanille.de> */ class OSoundSystem : public QObject { Q_OBJECT public: typedef QDict<OSoundCard> CardMap; typedef QDictIterator<OSoundCard> CardIterator; public: /** * @returns the number of available interfaces */ int count() const; /** * @returns a pointer to the (one and only) @ref OSystem instance. */ static OSoundSystem* instance(); /** * @returns an iterator usable for iterating through all sound cards. */ CardIterator iterator() const; /** * @returns a pointer to the @ref OAudioInterface object for the specified @a interface or 0, if not found * @see OAudioInterface */ OSoundCard* card( const QString& interface ) const; /** * @internal Rebuild the internal interface database * @note Sometimes it might be useful to call this from client code, * e.g. after issuing a cardctl insert */ void synchronize(); protected: OSoundSystem(); private: static OSoundSystem* _instance; CardMap _interfaces; class Private; Private *d; }; /*====================================================================================== * OSoundCard *======================================================================================*/ class OSoundCard : public QObject { Q_OBJECT public: /** * Constructor. Normally you don't create @ref OSoundCard objects yourself, * but access them via @ref OSoundSystem::card(). */ OSoundCard( QObject* parent, const char* name ); /** * Destructor. */ virtual ~OSoundCard(); bool hasMixer() const { return _audio; }; bool hasAudio() const { return _mixer; }; OAudioInterface* audio() const { return _audio; }; OMixerInterface* mixer() const { return _mixer; }; protected: OAudioInterface* _audio; OMixerInterface* _mixer; private: void init(); private: class Private; Private *d; }; /*====================================================================================== * OAudioInterface *======================================================================================*/ class OAudioInterface : public QObject { Q_OBJECT public: /** * Constructor. Normally you don't create @ref OAudioInterface objects yourself, * but access them via the @ref OSoundCard interface. */ OAudioInterface( QObject* parent, const char* name ); /** * Destructor. */ virtual ~OAudioInterface(); protected: const int _sfd; private: void init(); private: class Private; Private *d; }; /*====================================================================================== * OMixerInterface *======================================================================================*/ class OMixerInterface : public QObject { Q_OBJECT public: typedef QMap<QString,int>::ConstIterator ChannelIterator; /** * Constructor. Normally you don't create @ref OMixerInterface objects yourself, * but access them via the @ref OSoundCard interface. */ OMixerInterface( QObject* parent, const char* name ); /** * Destructor. */ virtual ~OMixerInterface(); /** * @returns all available channels. */ QStringList allChannels() const; /** * @returns recordable channels. */ QStringList recChannels() const; /** * @returns playable channels. */ QStringList playChannels() const; /** * @returns true, if the device features multiple recording sources. */ bool hasMultipleRecording() const; /** * @returns true, if @a channel exists. */ bool hasChannel( const QString& channel ) const; /** * @returns true, if @a channel is stereo. */ bool isStereo( const QString& channel ) const; /** * @returns tru, if @a channel is a possible recording source. */ bool isRecordable( const QString& channel ) const; /** * Set the @a left and @a right volumes for @a channel. * If no value for right is given, the value for left is taken for that. */ void setVolume( const QString& channel, int left, int right = -1 ); /** * @returns the volume of @a channel or -1, if the channel doesn't exist. * @note You might want to use @ref hasChannel() to check if a channel exists. */ int volume( const QString& channel ) const; protected: int _fd; int _capmask; int _devmask; int _recmask; int _stmask; QMap<QString,int> _channels; private: void init(); private: class Private; Private *d; }; } } #endif // OSOUNDSYSTEM_H diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp index eafbeea..c548356 100644 --- a/libopie2/opienet/opcap.cpp +++ b/libopie2/opienet/opcap.cpp @@ -1,1368 +1,1368 @@ /* This file is part of the Opie Project Copyright (C) 2003-2004 by Michael 'Mickey' Lauer <mickey@Vanille.de> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; version 2 of the License. - ._= =} : + ._= =} : .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "udp_ports.h" #include "opcap.h" /* OPIE */ #include <opie2/odebug.h> using namespace Opie::Core; /* QT */ #include <qapplication.h> // don't use oapplication here (will decrease reusability in other projects) #include <qsocketnotifier.h> #include <qobjectlist.h> /* STD */ #include <sys/time.h> #include <sys/types.h> #include <assert.h> #include <unistd.h> #include <string.h> namespace Opie { namespace Net { /*====================================================================================== * OPacket *======================================================================================*/ OPacket::OPacket( int datalink, packetheaderstruct header, const unsigned char* data, QObject* parent ) :QObject( parent, "Generic" ), _hdr( header ), _data( 0 ) { _data = new unsigned char[ header.len ]; assert( _data ); memcpy( const_cast<unsigned char*>(_data), data, header.len ); // We have to copy the data structure here, because the 'data' pointer handed by libpcap // points to an internal region which is reused by lipcap. odebug << "OPacket: Length = " << header.len << ", Caplen = " << header.caplen << oendl; _end = (unsigned char*) _data + header.len; switch ( datalink ) { case DLT_EN10MB: odebug << "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" << oendl; new OEthernetPacket( _end, (const struct ether_header*) _data, this ); break; case DLT_IEEE802_11: odebug << "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" << oendl; new OWaveLanPacket( _end, (const struct ieee_802_11_header*) _data, this ); break; case DLT_PRISM_HEADER: odebug << "OPacket::OPacket(): Received Packet. Datalink = PRISM_HEADER" << oendl; new OPrismHeaderPacket( _end, (const struct prism_hdr*) (unsigned char*) _data, this ); break; default: owarn << "OPacket::OPacket(): Received Packet over unsupported datalink, type " << datalink << "!" << oendl; } } OPacket::~OPacket() { odebug << "~OPacket( " << name() << " )" << oendl; delete [] _data; } timevalstruct OPacket::timeval() const { return _hdr.ts; } int OPacket::caplen() const { return _hdr.caplen; } void OPacket::updateStats( QMap<QString,int>& stats, QObjectList* l ) { if (!l) return; QObject* o = l->first(); while ( o ) { stats[o->name()]++; updateStats( stats, const_cast<QObjectList*>( o->children() ) ); o = l->next(); } } QString OPacket::dumpStructure() const { return "[ |" + _dumpStructure( const_cast<QObjectList*>( this->children() ) ) + " ]"; } QString OPacket::_dumpStructure( QObjectList* l ) const { if (!l) return QString::null; QObject* o = l->first(); QString str(" "); while ( o ) { str.append( o->name() ); str.append( " |" ); str += _dumpStructure( const_cast<QObjectList*>( o->children() ) ); o = l->next(); } return str; } QString OPacket::dump( int bpl ) const { static int index = 0; index++; int len = _hdr.caplen; QString str( "000:" ); QString tmp; QString bytes; QString chars; for ( int i = 0; i < len; ++i ) { tmp.sprintf( "%02X ", _data[i] ); bytes.append( tmp ); if ( (_data[i] > 31) && (_data[i]<128) ) chars.append( _data[i] ); else chars.append( '.' ); if ( !((i+1) % bpl) ) { str.append( bytes ); str.append( ' ' ); str.append( chars ); str.append( '\n' ); tmp.sprintf( "%03X:", i+1 ); str.append( tmp ); bytes = ""; chars = ""; } } if ( (len % bpl) ) { str.append( bytes.leftJustify( 1 + 3*bpl ) ); str.append( chars ); } str.append( '\n' ); return str; } int OPacket::len() const { return _hdr.len; } QTextStream& operator<<( QTextStream& s, const OPacket& p ) { s << p.dumpStructure(); return s; } /*====================================================================================== * OEthernetPacket *======================================================================================*/ OEthernetPacket::OEthernetPacket( const unsigned char* end, const struct ether_header* data, QObject* parent ) :QObject( parent, "Ethernet" ), _ether( data ) { odebug << "Source = " << sourceAddress().toString() << oendl; odebug << "Destination = " << destinationAddress().toString() << oendl; if ( sourceAddress() == OMacAddress::broadcast ) odebug << "Source is broadcast address" << oendl; if ( destinationAddress() == OMacAddress::broadcast ) odebug << "Destination is broadcast address" << oendl; switch ( type() ) { case ETHERTYPE_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break; case ETHERTYPE_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break; case ETHERTYPE_REVARP: { odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = RARP" << oendl; break; } default: odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = UNKNOWN" << oendl; } } OEthernetPacket::~OEthernetPacket() { } OMacAddress OEthernetPacket::sourceAddress() const { return OMacAddress( _ether->ether_shost ); } OMacAddress OEthernetPacket::destinationAddress() const { return OMacAddress( _ether->ether_dhost ); } int OEthernetPacket::type() const { return ntohs( _ether->ether_type ); } /*====================================================================================== * OIPPacket *======================================================================================*/ OIPPacket::OIPPacket( const unsigned char* end, const struct iphdr* data, QObject* parent ) :QObject( parent, "IP" ), _iphdr( data ) { odebug << "OIPPacket::OIPPacket(): decoding IP header..." << oendl; odebug << "FromAddress = " << fromIPAddress().toString() << oendl; odebug << " toAddress = " << toIPAddress().toString() << oendl; switch ( protocol() ) { case IPPROTO_UDP: new OUDPPacket( end, (const struct udphdr*) (data+1), this ); break; case IPPROTO_TCP: new OTCPPacket( end, (const struct tcphdr*) (data+1), this ); break; default: odebug << "OIPPacket::OIPPacket(): unknown IP protocol, type = " << protocol() << oendl; } } OIPPacket::~OIPPacket() { } QHostAddress OIPPacket::fromIPAddress() const { return EXTRACT_32BITS( &_iphdr->saddr ); } QHostAddress OIPPacket::toIPAddress() const { return EXTRACT_32BITS( &_iphdr->saddr ); } int OIPPacket::tos() const { return _iphdr->tos; } int OIPPacket::len() const { return EXTRACT_16BITS( &_iphdr->tot_len ); } int OIPPacket::id() const { return EXTRACT_16BITS( &_iphdr->id ); } int OIPPacket::offset() const { return EXTRACT_16BITS( &_iphdr->frag_off ); } int OIPPacket::ttl() const { return _iphdr->ttl; } int OIPPacket::protocol() const { return _iphdr->protocol; } int OIPPacket::checksum() const { return EXTRACT_16BITS( &_iphdr->check ); } /*====================================================================================== * OARPPacket *======================================================================================*/ OARPPacket::OARPPacket( const unsigned char* /*end*/, const struct myarphdr* data, QObject* parent ) :QObject( parent, "ARP" ), _arphdr( data ) { odebug << "OARPPacket::OARPPacket(): decoding ARP header..." << oendl; odebug << "ARP type seems to be " << EXTRACT_16BITS( &_arphdr->ar_op ) << " = " << type() << oendl; odebug << "Sender: MAC " << senderMacAddress().toString() << " = IP " << senderIPV4Address().toString() << oendl; odebug << "Target: MAC " << targetMacAddress().toString() << " = IP " << targetIPV4Address().toString() << oendl; } OARPPacket::~OARPPacket() { } QString OARPPacket::type() const { switch ( EXTRACT_16BITS( &_arphdr->ar_op ) ) { case 1: return "REQUEST"; case 2: return "REPLY"; case 3: return "RREQUEST"; case 4: return "RREPLY"; case 8: return "InREQUEST"; case 9: return "InREPLY"; case 10: return "NAK"; default: owarn << "OARPPacket::type(): invalid ARP type!" << oendl; return "<unknown>"; } } QHostAddress OARPPacket::senderIPV4Address() const { return EXTRACT_32BITS( &_arphdr->ar_sip ); } QHostAddress OARPPacket::targetIPV4Address() const { return EXTRACT_32BITS( &_arphdr->ar_tip ); } OMacAddress OARPPacket::senderMacAddress() const { return OMacAddress( _arphdr->ar_sha ); } OMacAddress OARPPacket::targetMacAddress() const { return OMacAddress( _arphdr->ar_tha ); } /*====================================================================================== * OUDPPacket *======================================================================================*/ OUDPPacket::OUDPPacket( const unsigned char* end, const struct udphdr* data, QObject* parent ) :QObject( parent, "UDP" ), _udphdr( data ) { odebug << "OUDPPacket::OUDPPacket(): decoding UDP header..." << oendl; odebug << "fromPort = " << fromPort() << oendl; odebug << " toPort = " << toPort() << oendl; // TODO: Make this a case or a hash if we know more udp protocols if ( fromPort() == UDP_PORT_BOOTPS || fromPort() == UDP_PORT_BOOTPC || toPort() == UDP_PORT_BOOTPS || toPort() == UDP_PORT_BOOTPC ) { odebug << "seems to be part of a DHCP conversation => creating DHCP packet." << oendl; new ODHCPPacket( end, (const struct dhcp_packet*) (data+1), this ); } } OUDPPacket::~OUDPPacket() { } int OUDPPacket::fromPort() const { return EXTRACT_16BITS( &_udphdr->source ); } int OUDPPacket::toPort() const { return EXTRACT_16BITS( &_udphdr->dest ); } int OUDPPacket::length() const { return EXTRACT_16BITS( &_udphdr->len ); } int OUDPPacket::checksum() const { return EXTRACT_16BITS( &_udphdr->check ); } /*====================================================================================== * ODHCPPacket *======================================================================================*/ ODHCPPacket::ODHCPPacket( const unsigned char* end, const struct dhcp_packet* data, QObject* parent ) :QObject( parent, "DHCP" ), _dhcphdr( data ) { odebug << "ODHCPPacket::ODHCPPacket(): decoding DHCP information..." << oendl; odebug << "DHCP opcode seems to be " << _dhcphdr->op << ": " << ( isRequest() ? "REQUEST" : "REPLY" ) << oendl; odebug << "clientAddress = " << clientAddress().toString() << oendl; odebug << " yourAddress = " << yourAddress().toString() << oendl; odebug << "serverAddress = " << serverAddress().toString() << oendl; odebug << " relayAddress = " << relayAddress().toString() << oendl; odebug << "parsing DHCP options..." << oendl; _type = 0; const unsigned char* option = &_dhcphdr->options[4]; char tag = -1; char len = -1; while ( ( tag = *option++ ) != -1 /* end of option field */ ) { len = *option++; odebug << "recognized DHCP option #" << tag << ", length " << len << oendl; if ( tag == DHO_DHCP_MESSAGE_TYPE ) _type = *option; option += len; if ( option >= end ) { owarn << "DHCP parsing ERROR: sanity check says the packet is at its end!" << oendl; break; } } odebug << "DHCP type seems to be << " << type() << oendl; } ODHCPPacket::~ODHCPPacket() { } bool ODHCPPacket::isRequest() const { return ( _dhcphdr->op == 01 ); } bool ODHCPPacket::isReply() const { return ( _dhcphdr->op == 02 ); } QString ODHCPPacket::type() const { switch ( _type ) { case 1: return "DISCOVER"; case 2: return "OFFER"; case 3: return "REQUEST"; case 4: return "DECLINE"; case 5: return "ACK"; case 6: return "NAK"; case 7: return "RELEASE"; case 8: return "INFORM"; default: owarn << "ODHCPPacket::type(): invalid DHCP type " << _dhcphdr->op << oendl; return "<unknown>"; } } QHostAddress ODHCPPacket::clientAddress() const { return EXTRACT_32BITS( &_dhcphdr->ciaddr ); } QHostAddress ODHCPPacket::yourAddress() const { return EXTRACT_32BITS( &_dhcphdr->yiaddr ); } QHostAddress ODHCPPacket::serverAddress() const { return EXTRACT_32BITS( &_dhcphdr->siaddr ); } QHostAddress ODHCPPacket::relayAddress() const { return EXTRACT_32BITS( &_dhcphdr->giaddr ); } OMacAddress ODHCPPacket::clientMacAddress() const { return OMacAddress( _dhcphdr->chaddr ); } /*====================================================================================== * OTCPPacket *======================================================================================*/ OTCPPacket::OTCPPacket( const unsigned char* /*end*/, const struct tcphdr* data, QObject* parent ) :QObject( parent, "TCP" ), _tcphdr( data ) { odebug << "OTCPPacket::OTCPPacket(): decoding TCP header..." << oendl; } OTCPPacket::~OTCPPacket() { } int OTCPPacket::fromPort() const { return EXTRACT_16BITS( &_tcphdr->source ); } int OTCPPacket::toPort() const { return EXTRACT_16BITS( &_tcphdr->dest ); } int OTCPPacket::seq() const { return EXTRACT_16BITS( &_tcphdr->seq ); } int OTCPPacket::ack() const { return EXTRACT_16BITS( &_tcphdr->ack_seq ); } int OTCPPacket::window() const { return EXTRACT_16BITS( &_tcphdr->window ); } int OTCPPacket::checksum() const { return EXTRACT_16BITS( &_tcphdr->check ); } /*====================================================================================== * OPrismHeaderPacket *======================================================================================*/ OPrismHeaderPacket::OPrismHeaderPacket( const unsigned char* end, const struct prism_hdr* data, QObject* parent ) :QObject( parent, "Prism" ), _header( data ) { odebug << "OPrismHeaderPacket::OPrismHeaderPacket(): decoding PRISM header..." << oendl; odebug << "Signal Strength = " << data->signal.data << oendl; new OWaveLanPacket( end, (const struct ieee_802_11_header*) (data+1), this ); } OPrismHeaderPacket::~OPrismHeaderPacket() { } unsigned int OPrismHeaderPacket::signalStrength() const { return _header->signal.data; } /*====================================================================================== * OWaveLanPacket *======================================================================================*/ OWaveLanPacket::OWaveLanPacket( const unsigned char* end, const struct ieee_802_11_header* data, QObject* parent ) :QObject( parent, "802.11" ), _wlanhdr( data ) { odebug << "OWaveLanPacket::OWaveLanPacket(): decoding IEEE 802.11 header..." << oendl; odebug << "type = " << type() << oendl; odebug << "subType = " << subType() << oendl; odebug << "duration = " << duration() << oendl; odebug << "powermanagement = " << usesPowerManagement() << oendl; odebug << "payload is encrypted = " << ( usesWep() ? "yes" : "no" ) << oendl; odebug << "MAC1 = " << macAddress1().toString() << oendl; odebug << "MAC2 = " << macAddress2().toString() << oendl; odebug << "MAC3 = " << macAddress3().toString() << oendl; odebug << "MAC4 = " << macAddress4().toString() << oendl; switch ( type() ) { case T_MGMT: new OWaveLanManagementPacket( end, (const struct ieee_802_11_mgmt_header*) data, this ); break; case T_DATA: new OWaveLanDataPacket( end, (const struct ieee_802_11_data_header*) data, this ); break; case T_CTRL: new OWaveLanControlPacket( end, (const struct ieee_802_11_control_header*) data, this ); break; default: odebug << "OWaveLanPacket::OWaveLanPacket(): Warning: Unknown major type = " << type() << oendl; } } OWaveLanPacket::~OWaveLanPacket() { } int OWaveLanPacket::duration() const { return _wlanhdr->duration; } OMacAddress OWaveLanPacket::macAddress1() const { return OMacAddress( _wlanhdr->mac1 ); } OMacAddress OWaveLanPacket::macAddress2() const { return OMacAddress( _wlanhdr->mac2 ); } OMacAddress OWaveLanPacket::macAddress3() const { return OMacAddress( _wlanhdr->mac3 ); } OMacAddress OWaveLanPacket::macAddress4() const { return OMacAddress( _wlanhdr->mac4 ); } int OWaveLanPacket::subType() const { return FC_SUBTYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } int OWaveLanPacket::type() const { return FC_TYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } int OWaveLanPacket::version() const { return FC_VERSION( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::fromDS() const { return FC_FROM_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::toDS() const { return FC_TO_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::usesPowerManagement() const { return FC_POWER_MGMT( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::usesWep() const { return FC_WEP( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } /*====================================================================================== * OWaveLanManagementPacket *======================================================================================*/ OWaveLanManagementPacket::OWaveLanManagementPacket( const unsigned char* end, const struct ieee_802_11_mgmt_header* data, OWaveLanPacket* parent ) :QObject( parent, "802.11 Management" ), _header( data ), _body( (const struct ieee_802_11_mgmt_body*) (data+1) ) { odebug << "OWaveLanManagementPacket::OWaveLanManagementPacket(): decoding frame..." << oendl; odebug << "Detected subtype is " << managementType() << oendl; // Grab tagged values. // Beacons contain a 12 byte long fixed parameters set before the tagged parameters come, // Other management frames don't - which is why we have to inspect the subtype here. const unsigned char* ptr = managementType() == "Beacon" ? (const unsigned char*) (_body+1) : (const unsigned char*) (_header+1); while (ptr < end) { switch ( *ptr ) { case E_SSID: new OWaveLanManagementSSID( end, (struct ssid_t*) ptr, this ); break; case E_FH: new OWaveLanManagementFH( end, (struct fh_t*) ptr, this ); break; case E_DS: new OWaveLanManagementDS( end, (struct ds_t*) ptr, this ); break; case E_RATES: new OWaveLanManagementRates( end, (struct rates_t*) ptr, this ); break; case E_CF: new OWaveLanManagementCF( end, (struct cf_t*) ptr, this ); break; case E_TIM: new OWaveLanManagementTim( end, (struct tim_t*) ptr, this ); break; case E_IBSS: new OWaveLanManagementIBSS( end, (struct ibss_t*) ptr, this ); break; case E_CHALLENGE: new OWaveLanManagementChallenge( end, (struct challenge_t*) ptr, this ); break; } ptr+= ( ( struct ssid_t* ) ptr )->length; // skip length of tagged value ptr+= 2; // skip tag ID and length } } OWaveLanManagementPacket::~OWaveLanManagementPacket() { } QString OWaveLanManagementPacket::managementType() const { switch ( FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) ) { case ST_ASSOC_REQUEST: return "AssociationRequest"; break; case ST_ASSOC_RESPONSE: return "AssociationResponse"; break; case ST_REASSOC_REQUEST: return "ReassociationRequest"; break; case ST_REASSOC_RESPONSE: return "ReassociationResponse"; break; case ST_PROBE_REQUEST: return "ProbeRequest"; break; case ST_PROBE_RESPONSE: return "ProbeResponse"; break; case ST_BEACON: return "Beacon"; break; case ST_ATIM: return "Atim"; break; case ST_DISASSOC: return "Disassociation"; break; case ST_AUTH: return "Authentication"; break; case ST_DEAUTH: return "Deathentication"; break; default: owarn << "OWaveLanManagementPacket::managementType(): unhandled subtype " << FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) << oendl; return "Unknown"; } } int OWaveLanManagementPacket::beaconInterval() const { return EXTRACT_LE_16BITS( &_body->beacon_interval ); } int OWaveLanManagementPacket::capabilities() const { return EXTRACT_LE_16BITS( &_body->capability_info ); } bool OWaveLanManagementPacket::canESS() const { return CAPABILITY_ESS( EXTRACT_LE_16BITS( &_body->capability_info ) ); } bool OWaveLanManagementPacket::canIBSS() const { return CAPABILITY_IBSS( EXTRACT_LE_16BITS( &_body->capability_info ) ); } bool OWaveLanManagementPacket::canCFP() const { return CAPABILITY_CFP( EXTRACT_LE_16BITS( &_body->capability_info ) ); } bool OWaveLanManagementPacket::canCFP_REQ() const { return CAPABILITY_CFP_REQ( EXTRACT_LE_16BITS( &_body->capability_info ) ); } bool OWaveLanManagementPacket::canPrivacy() const { return CAPABILITY_PRIVACY( EXTRACT_LE_16BITS( &_body->capability_info ) ); } /*====================================================================================== * OWaveLanManagementSSID *======================================================================================*/ OWaveLanManagementSSID::OWaveLanManagementSSID( const unsigned char* /*end*/, const struct ssid_t* data, QObject* parent ) :QObject( parent, "802.11 SSID" ), _data( data ) { odebug << "OWaveLanManagementSSID()" << oendl; } OWaveLanManagementSSID::~OWaveLanManagementSSID() { } QString OWaveLanManagementSSID::ID( bool decloak ) const { int length = _data->length; if ( length > 32 ) length = 32; char essid[length+1]; memcpy( &essid, &_data->ssid, length ); essid[length] = 0x0; if ( !decloak || length < 2 || essid[0] != '\0' ) return essid; odebug << "OWaveLanManagementSSID:ID(): SSID is cloaked - decloaking..." << oendl; QString decloakedID; for ( int i = 1; i < length; ++i ) { if ( essid[i] >= 32 && essid[i] <= 126 ) decloakedID.append( essid[i] ); else decloakedID.append( '.' ); } return decloakedID; } /*====================================================================================== * OWaveLanManagementRates *======================================================================================*/ OWaveLanManagementRates::OWaveLanManagementRates( const unsigned char* /*end*/, const struct rates_t* data, QObject* parent ) :QObject( parent, "802.11 Rates" ), _data( data ) { odebug << "OWaveLanManagementRates()" << oendl; } OWaveLanManagementRates::~OWaveLanManagementRates() { } /*====================================================================================== * OWaveLanManagementCF *======================================================================================*/ OWaveLanManagementCF::OWaveLanManagementCF( const unsigned char* /*end*/, const struct cf_t* data, QObject* parent ) :QObject( parent, "802.11 CF" ), _data( data ) { odebug << "OWaveLanManagementCF()" << oendl; } OWaveLanManagementCF::~OWaveLanManagementCF() { } /*====================================================================================== * OWaveLanManagementFH *======================================================================================*/ OWaveLanManagementFH::OWaveLanManagementFH( const unsigned char* /*end*/, const struct fh_t* data, QObject* parent ) :QObject( parent, "802.11 FH" ), _data( data ) { odebug << "OWaveLanManagementFH()" << oendl; } OWaveLanManagementFH::~OWaveLanManagementFH() { } /*====================================================================================== * OWaveLanManagementDS *======================================================================================*/ OWaveLanManagementDS::OWaveLanManagementDS( const unsigned char* /*end*/, const struct ds_t* data, QObject* parent ) :QObject( parent, "802.11 DS" ), _data( data ) { odebug << "OWaveLanManagementDS()" << oendl; } OWaveLanManagementDS::~OWaveLanManagementDS() { } int OWaveLanManagementDS::channel() const { return _data->channel; } /*====================================================================================== * OWaveLanManagementTim *======================================================================================*/ OWaveLanManagementTim::OWaveLanManagementTim( const unsigned char* /*end*/, const struct tim_t* data, QObject* parent ) :QObject( parent, "802.11 Tim" ), _data( data ) { odebug << "OWaveLanManagementTim()" << oendl; } OWaveLanManagementTim::~OWaveLanManagementTim() { } /*====================================================================================== * OWaveLanManagementIBSS *======================================================================================*/ OWaveLanManagementIBSS::OWaveLanManagementIBSS( const unsigned char* /*end*/, const struct ibss_t* data, QObject* parent ) :QObject( parent, "802.11 IBSS" ), _data( data ) { odebug << "OWaveLanManagementIBSS()" << oendl; } OWaveLanManagementIBSS::~OWaveLanManagementIBSS() { } /*====================================================================================== * OWaveLanManagementChallenge *======================================================================================*/ OWaveLanManagementChallenge::OWaveLanManagementChallenge( const unsigned char* /*end*/, const struct challenge_t* data, QObject* parent ) :QObject( parent, "802.11 Challenge" ), _data( data ) { odebug << "OWaveLanManagementChallenge()" << oendl; } OWaveLanManagementChallenge::~OWaveLanManagementChallenge() { } /*====================================================================================== * OWaveLanDataPacket *======================================================================================*/ OWaveLanDataPacket::OWaveLanDataPacket( const unsigned char* end, const struct ieee_802_11_data_header* data, OWaveLanPacket* parent ) :QObject( parent, "802.11 Data" ), _header( data ) { odebug << "OWaveLanDataPacket::OWaveLanDataPacket(): decoding frame..." << oendl; const unsigned char* payload = (const unsigned char*) data + sizeof( struct ieee_802_11_data_header ); #warning The next line works for most cases, but can not be correct generally! if (!( ( (OWaveLanPacket*) this->parent())->duration() )) payload -= 6; // compensation for missing last address new OLLCPacket( end, (const struct ieee_802_11_802_2_header*) payload, this ); } OWaveLanDataPacket::~OWaveLanDataPacket() { } /*====================================================================================== * OLLCPacket *======================================================================================*/ OLLCPacket::OLLCPacket( const unsigned char* end, const struct ieee_802_11_802_2_header* data, QObject* parent ) :QObject( parent, "802.11 LLC" ), _header( data ) { odebug << "OLLCPacket::OLLCPacket(): decoding frame..." << oendl; if ( !(_header->oui[0] || _header->oui[1] || _header->oui[2]) ) { owarn << "OLLCPacket::OLLCPacket(): contains an encapsulated Ethernet frame (type = " << EXTRACT_16BITS( &_header->type ) << ")" << oendl; switch ( EXTRACT_16BITS( &_header->type ) ) // defined in linux/if_ether.h { case ETH_P_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break; case ETH_P_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break; default: owarn << "OLLCPacket::OLLCPacket(): Unknown Encapsulation type = " << EXTRACT_16BITS( &_header->type ) << oendl; } } } OLLCPacket::~OLLCPacket() { } /*====================================================================================== * OWaveLanControlPacket *======================================================================================*/ OWaveLanControlPacket::OWaveLanControlPacket( const unsigned char* /*end*/, const struct ieee_802_11_control_header* data, OWaveLanPacket* parent ) :QObject( parent, "802.11 Control" ), _header( data ) { odebug << "OWaveLanControlPacket::OWaveLanDataControl(): decoding frame..." << oendl; odebug << "Detected subtype is " << controlType() << oendl; } OWaveLanControlPacket::~OWaveLanControlPacket() { } QString OWaveLanControlPacket::controlType() const { switch ( FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) ) { case CTRL_PS_POLL: return "PowerSavePoll"; break; case CTRL_RTS: return "RequestToSend"; break; case CTRL_CTS: return "ClearToSend"; break; case CTRL_ACK: return "Acknowledge"; break; case CTRL_CF_END: return "ContentionFreeEnd"; break; case CTRL_END_ACK: return "AcknowledgeEnd"; break; default: owarn << "OWaveLanControlPacket::managementType(): unhandled subtype " << FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) << oendl; return "Unknown"; } } /*====================================================================================== * OPacketCapturer *======================================================================================*/ OPacketCapturer::OPacketCapturer( QObject* parent, const char* name ) :QObject( parent, name ), _name( QString::null ), _open( false ), _pch( 0 ), _pcd( 0 ), _sn( 0 ), _autodelete( true ) { } OPacketCapturer::~OPacketCapturer() { if ( _open ) { odebug << "OPacketCapturer::~OPacketCapturer(): pcap still open, autoclosing." << oendl; close(); } } void OPacketCapturer::setAutoDelete( bool b ) { _autodelete = b; } bool OPacketCapturer::autoDelete() const { return _autodelete; } void OPacketCapturer::setBlocking( bool b ) { if ( pcap_setnonblock( _pch, 1-b, _errbuf ) != -1 ) { odebug << "OPacketCapturer::setBlocking(): blocking mode changed successfully." << oendl; } else { odebug << "OPacketCapturer::setBlocking(): can't change blocking mode: " << _errbuf << oendl; } } bool OPacketCapturer::blocking() const { int b = pcap_getnonblock( _pch, _errbuf ); if ( b == -1 ) { odebug << "OPacketCapturer::blocking(): can't get blocking mode: " << _errbuf << oendl; return -1; } return !b; } void OPacketCapturer::closeDumpFile() { if ( _pcd ) { pcap_dump_close( _pcd ); _pcd = 0; } pcap_close( _pch ); } void OPacketCapturer::close() { if ( _open ) { if ( _sn ) { _sn->disconnect( SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); delete _sn; } closeDumpFile(); _open = false; } odebug << "OPacketCapturer::close() --- dumping capturing statistics..." << oendl; odebug << "--------------------------------------------------" << oendl; for( QMap<QString,int>::Iterator it = _stats.begin(); it != _stats.end(); ++it ) odebug << it.key() << " = " << it.data() << oendl; odebug << "--------------------------------------------------" << oendl; } int OPacketCapturer::dataLink() const { return pcap_datalink( _pch ); } void OPacketCapturer::dump( OPacket* p ) { if ( !_pcd ) { owarn << "OPacketCapturer::dump() - cannot dump without open capture file!" << oendl; return; } pcap_dump( (u_char*) _pcd, &p->_hdr, p->_data ); } int OPacketCapturer::fileno() const { if ( _open ) { return pcap_fileno( _pch ); } else { return -1; } } OPacket* OPacketCapturer::next( int time ) { fd_set fds; struct timeval tv; FD_ZERO( &fds ); FD_SET( pcap_fileno( _pch ), &fds ); tv.tv_sec = time / 1000; tv.tv_usec = time % 1000; int retval = select( pcap_fileno( _pch )+1, &fds, NULL, NULL, &tv); if ( retval > 0 ) // clear to read! return next(); else return 0; } OPacket* OPacketCapturer::next() { packetheaderstruct header; odebug << "==> OPacketCapturer::next()" << oendl; const unsigned char* pdata = pcap_next( _pch, &header ); odebug << "<== OPacketCapturer::next()" << oendl; if ( pdata && header.len ) { OPacket* p = new OPacket( dataLink(), header, pdata, 0 ); // packets shouldn't be inserted in the QObject child-parent hierarchy, // because due to memory constraints they will be deleted as soon // as possible - that is right after they have been processed // by emit() [ see below ] //TODO: make gathering statistics optional, because it takes time p->updateStats( _stats, const_cast<QObjectList*>( p->children() ) ); odebug << "OPacket::dumpStructure: " << p->dumpStructure() << oendl; return p; } else { owarn << "OPacketCapturer::next() - no packet received!" << oendl; return 0; } } bool OPacketCapturer::open( const QString& name ) { if ( _open ) { if ( name == _name ) // ignore opening an already openend device { return true; } else // close the last opened device { close(); } } _name = name; // open libpcap pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] ); if ( !handle ) { owarn << "OPacketCapturer::open(): can't open libpcap with '" << name << "': " << _errbuf << oendl; return false; } odebug << "OPacketCapturer::open(): libpcap [" << name << "] opened successfully." << oendl; _pch = handle; _open = true; _stats.clear(); // in case we have an application object, create a socket notifier if ( qApp ) //TODO: I don't like this here... { _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read ); connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); } return true; } bool OPacketCapturer::openDumpFile( const QString& filename ) { pcap_dumper_t* dump = pcap_dump_open( _pch, const_cast<char*>( (const char*) filename ) ); if ( !dump ) { owarn << "OPacketCapturer::open(): can't open dump with '" << filename << "': " << _errbuf << oendl; return false; } odebug << "OPacketCapturer::open(): dump [" << filename << "] opened successfully." << oendl; _pcd = dump; return true; } bool OPacketCapturer::openCaptureFile( const QString& name ) { if ( _open ) { close(); if ( name == _name ) // ignore opening an already openend device { return true; } else // close the last opened device { close(); } } _name = name; pcap_t* handle = pcap_open_offline( const_cast<char*>( (const char*) name ), &_errbuf[0] ); if ( handle ) { odebug << "OPacketCapturer::open(): libpcap opened successfully." << oendl; _pch = handle; _open = true; // in case we have an application object, create a socket notifier if ( qApp ) { _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read ); connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); } return true; } else { odebug << "OPacketCapturer::open(): can't open libpcap with '" << name << "': " << _errbuf << oendl; return false; } } bool OPacketCapturer::isOpen() const { return _open; } void OPacketCapturer::readyToReceive() { odebug << "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(p)'" << oendl; OPacket* p = next(); emit receivedPacket( p ); // emit is synchronous - packet has been dealt with, now it's safe to delete (if enabled) if ( _autodelete ) delete p; } const QMap<QString,int>& OPacketCapturer::statistics() const { return _stats; } int OPacketCapturer::snapShot() const { return pcap_snapshot( _pch ); } bool OPacketCapturer::swapped() const { return pcap_is_swapped( _pch ); } QString OPacketCapturer::version() const { return QString().sprintf( "%d.%d", pcap_major_version( _pch ), pcap_minor_version( _pch ) ); } } } diff --git a/libopie2/opienet/opcap.h b/libopie2/opienet/opcap.h index 149e573..8b415a2 100644 --- a/libopie2/opienet/opcap.h +++ b/libopie2/opienet/opcap.h @@ -1,733 +1,732 @@ /* This file is part of the Opie Project Copyright (C) 2003 by Michael 'Mickey' Lauer <mickey@Vanille.de> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; version 2 of the License. ._= =} : .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OPCAP_H #define OPCAP_H /* OPIE */ #include <opie2/onetutils.h> /* QT */ #include <qevent.h> #include <qfile.h> #include <qhostaddress.h> #include <qobject.h> #include <qstring.h> #include <qtextstream.h> #include <qmap.h> /* STD */ extern "C" // work around a bpf/pcap conflict in recent headers { #include <pcap.h> } #include <netinet/ether.h> #include <netinet/ip.h> #include <netinet/udp.h> #include <netinet/tcp.h> #include <time.h> /* Custom Network Includes (must go here, don't reorder!) */ #include "802_11_user.h" #include "dhcp.h" - /* TYPEDEFS */ typedef struct timeval timevalstruct; typedef struct pcap_pkthdr packetheaderstruct; /* FORWARDS */ class QSocketNotifier; namespace Opie { namespace Net { class OPacketCapturer; /*====================================================================================== * OPacket - A frame on the wire *======================================================================================*/ /** @brief A class representing a data frame on the wire. * * The whole family of the packet classes are used when capturing frames from a network. * Most standard network protocols in use share a common architecture, which mostly is * a packet header and then the packet payload. In layered architectures, each lower layer * encapsulates data from its upper layer - that is it * treats the data from its upper layer as payload and prepends an own header to the packet, * which - again - is treated as the payload for the layer below. The figure below is an * example for how such a data frame is composed out of packets, e.g. when sending a mail. * * <pre> * | User Data | == Mail Data * | SMTP Header | User Data | == SMTP * | TCP Header | SMTP Header | User Data | == TCP * | IP Header | TCP Header | SMTP Header | User Data | == IP * | MAC Header | IP Header | TCP Header | SMTP Header | User Data | == MAC * * </pre> * * The example is trimmed for simplicity, because the MAC (Medium Access Control) layer * also contains a few more levels of encapsulation. * Since the type of the payload is more or less independent from the encapsulating protocol, * the header must be inspected before attempting to decode the payload. Hence, the * encapsulation level varies and can't be deduced without actually looking into the packets. * * For actually working with captured frames, it's useful to identify the packets via names and * insert them into a parent/child - relationship based on the encapsulation. This is why * all packet classes derive from QObject. The amount of overhead caused by the QObject is * not a problem in this case, because we're talking about a theoratical maximum of about * 10 packets per captured frame. We need to stuff them into a searchable list anyway and the * QObject also cares about destroying the sub-, (child-) packets. * * This enables us to perform a simple look for packets of a certain type: * @code * OPacketCapturer* pcap = new OPacketCapturer(); * pcap->open( "eth0" ); * OPacket* p = pcap->next(); * OIPPacket* ip = (OIPPacket*) p->child( "IP" ); // returns 0, if no such child exists * odebug << "got ip packet from " << ip->fromIPAddress().toString() << " to " << ip->toIPAddress().toString() << oendl; * */ class OPacket : public QObject { Q_OBJECT friend class OPacketCapturer; friend QTextStream& operator<<( QTextStream& s, const OPacket& p ); public: OPacket( int datalink, packetheaderstruct, const unsigned char*, QObject* parent ); virtual ~OPacket(); timevalstruct timeval() const; int caplen() const; int len() const; QString dump( int = 32 ) const; //FIXME: remove that void updateStats( QMap<QString,int>&, QObjectList* ); //FIXME: Revise QString dumpStructure() const; //FIXME: Revise private: QString _dumpStructure( QObjectList* ) const; //FIXME: Revise private: const packetheaderstruct _hdr; // pcap packet header const unsigned char* _data; // pcap packet data const unsigned char* _end; // end of pcap packet data private: class Private; Private *d; }; QTextStream& operator<<( QTextStream& s, const OPacket& p ); //FIXME: Revise /*====================================================================================== * OEthernetPacket - DLT_EN10MB frame *======================================================================================*/ class OEthernetPacket : public QObject { Q_OBJECT public: OEthernetPacket( const unsigned char*, const struct ether_header*, QObject* parent = 0 ); virtual ~OEthernetPacket(); OMacAddress sourceAddress() const; OMacAddress destinationAddress() const; int type() const; private: const struct ether_header* _ether; private: class Private; Private *d; }; /*====================================================================================== * OPrismHeaderPacket - DLT_PRISM_HEADER frame *======================================================================================*/ class OPrismHeaderPacket : public QObject { Q_OBJECT public: OPrismHeaderPacket( const unsigned char*, const struct prism_hdr*, QObject* parent = 0 ); virtual ~OPrismHeaderPacket(); unsigned int signalStrength() const; private: const struct prism_hdr* _header; class Private; Private *d; }; /*====================================================================================== * OWaveLanPacket - DLT_IEEE802_11 frame *======================================================================================*/ class OWaveLanPacket : public QObject { Q_OBJECT public: OWaveLanPacket( const unsigned char*, const struct ieee_802_11_header*, QObject* parent = 0 ); virtual ~OWaveLanPacket(); int duration() const; bool fromDS() const; bool toDS() const; virtual OMacAddress macAddress1() const; virtual OMacAddress macAddress2() const; virtual OMacAddress macAddress3() const; virtual OMacAddress macAddress4() const; bool usesPowerManagement() const; int type() const; int subType() const; int version() const; bool usesWep() const; private: const struct ieee_802_11_header* _wlanhdr; class Private; Private *d; }; /*====================================================================================== * OWaveLanManagementPacket - type: management (T_MGMT) *======================================================================================*/ class OWaveLanManagementPacket : public QObject { Q_OBJECT public: OWaveLanManagementPacket( const unsigned char*, const struct ieee_802_11_mgmt_header*, OWaveLanPacket* parent = 0 ); virtual ~OWaveLanManagementPacket(); QString managementType() const; int beaconInterval() const; int capabilities() const; // generic bool canESS() const; bool canIBSS() const; bool canCFP() const; bool canCFP_REQ() const; bool canPrivacy() const; private: const struct ieee_802_11_mgmt_header* _header; const struct ieee_802_11_mgmt_body* _body; class Private; Private *d; }; /*====================================================================================== * OWaveLanManagementSSID *======================================================================================*/ class OWaveLanManagementSSID : public QObject { Q_OBJECT public: OWaveLanManagementSSID( const unsigned char*, const struct ssid_t*, QObject* parent = 0 ); virtual ~OWaveLanManagementSSID(); QString ID( bool decloak = false ) const; private: const struct ssid_t* _data; class Private; Private *d; }; /*====================================================================================== * OWaveLanManagementRates *======================================================================================*/ class OWaveLanManagementRates : public QObject { Q_OBJECT public: OWaveLanManagementRates( const unsigned char*, const struct rates_t*, QObject* parent = 0 ); virtual ~OWaveLanManagementRates(); private: const struct rates_t* _data; class Private; Private *d; }; /*====================================================================================== * OWaveLanManagementCF *======================================================================================*/ class OWaveLanManagementCF : public QObject { Q_OBJECT public: OWaveLanManagementCF( const unsigned char*, const struct cf_t*, QObject* parent = 0 ); virtual ~OWaveLanManagementCF(); private: const struct cf_t* _data; class Private; Private *d; }; /*====================================================================================== * OWaveLanManagementFH *======================================================================================*/ class OWaveLanManagementFH : public QObject { Q_OBJECT public: OWaveLanManagementFH( const unsigned char*, const struct fh_t*, QObject* parent = 0 ); virtual ~OWaveLanManagementFH(); private: const struct fh_t* _data; class Private; Private *d; }; /*====================================================================================== * OWaveLanManagementDS *======================================================================================*/ class OWaveLanManagementDS : public QObject { Q_OBJECT public: OWaveLanManagementDS( const unsigned char*, const struct ds_t*, QObject* parent = 0 ); virtual ~OWaveLanManagementDS(); int channel() const; private: const struct ds_t* _data; class Private; Private *d; }; /*====================================================================================== * OWaveLanManagementTim *======================================================================================*/ class OWaveLanManagementTim : public QObject { Q_OBJECT public: OWaveLanManagementTim( const unsigned char*, const struct tim_t*, QObject* parent = 0 ); virtual ~OWaveLanManagementTim(); private: const struct tim_t* _data; class Private; Private *d; }; /*====================================================================================== * OWaveLanManagementIBSS *======================================================================================*/ class OWaveLanManagementIBSS : public QObject { Q_OBJECT public: OWaveLanManagementIBSS( const unsigned char*, const struct ibss_t*, QObject* parent = 0 ); virtual ~OWaveLanManagementIBSS(); private: const struct ibss_t* _data; class Private; Private *d; }; /*====================================================================================== * OWaveLanManagementChallenge *======================================================================================*/ class OWaveLanManagementChallenge : public QObject { Q_OBJECT public: OWaveLanManagementChallenge( const unsigned char*, const struct challenge_t*, QObject* parent = 0 ); virtual ~OWaveLanManagementChallenge(); private: const struct challenge_t* _data; class Private; Private *d; }; /*====================================================================================== * OWaveLanDataPacket - type: data (T_DATA) *======================================================================================*/ class OWaveLanDataPacket : public QObject { Q_OBJECT public: OWaveLanDataPacket( const unsigned char*, const struct ieee_802_11_data_header*, OWaveLanPacket* parent = 0 ); virtual ~OWaveLanDataPacket(); private: const struct ieee_802_11_data_header* _header; class Private; Private *d; }; /*====================================================================================== * OWaveLanControlPacket - type: control (T_CTRL) *======================================================================================*/ class OWaveLanControlPacket : public QObject { Q_OBJECT public: OWaveLanControlPacket( const unsigned char*, const struct ieee_802_11_control_header*, OWaveLanPacket* parent = 0 ); virtual ~OWaveLanControlPacket(); QString controlType() const; private: const struct ieee_802_11_control_header* _header; class Private; Private *d; }; /*====================================================================================== * OLLCPacket - IEEE 802.2 Link Level Control *======================================================================================*/ class OLLCPacket : public QObject { Q_OBJECT public: OLLCPacket( const unsigned char*, const struct ieee_802_11_802_2_header* data, QObject* parent = 0 ); virtual ~OLLCPacket(); private: const struct ieee_802_11_802_2_header* _header; class Private; Private *d; }; /*====================================================================================== * OIPPacket *======================================================================================*/ class OIPPacket : public QObject { Q_OBJECT public: OIPPacket( const unsigned char*, const struct iphdr*, QObject* parent = 0 ); virtual ~OIPPacket(); QHostAddress fromIPAddress() const; QHostAddress toIPAddress() const; int tos() const; int len() const; int id() const; int offset() const; int ttl() const; int protocol() const; int checksum() const; private: const struct iphdr* _iphdr; class Private; Private *d; }; /*====================================================================================== * OARPPacket *======================================================================================*/ class OARPPacket : public QObject { Q_OBJECT public: OARPPacket( const unsigned char*, const struct myarphdr*, QObject* parent = 0 ); virtual ~OARPPacket(); QHostAddress senderIPV4Address() const; OMacAddress senderMacAddress() const; QHostAddress targetIPV4Address() const; OMacAddress targetMacAddress() const; //int type() const; QString type() const; private: const struct myarphdr* _arphdr; class Private; Private *d; }; /*====================================================================================== * OUDPPacket *======================================================================================*/ class OUDPPacket : public QObject { Q_OBJECT public: OUDPPacket( const unsigned char*, const struct udphdr*, QObject* parent = 0 ); virtual ~OUDPPacket(); int fromPort() const; int toPort() const; int length() const; int checksum() const; private: const struct udphdr* _udphdr; class Private; Private *d; }; /*====================================================================================== * ODHCPPacket *======================================================================================*/ class ODHCPPacket : public QObject { Q_OBJECT public: ODHCPPacket( const unsigned char*, const struct dhcp_packet*, QObject* parent = 0 ); virtual ~ODHCPPacket(); QHostAddress clientAddress() const; QHostAddress yourAddress() const; QHostAddress serverAddress() const; QHostAddress relayAddress() const; OMacAddress clientMacAddress() const; bool isRequest() const; bool isReply() const; QString type() const; private: const struct dhcp_packet* _dhcphdr; unsigned char _type; class Private; Private *d; }; /*====================================================================================== * OTCPPacket *======================================================================================*/ class OTCPPacket : public QObject { Q_OBJECT public: OTCPPacket( const unsigned char*, const struct tcphdr*, QObject* parent = 0 ); virtual ~OTCPPacket(); int fromPort() const; int toPort() const; int seq() const; int ack() const; int window() const; int checksum() const; private: const struct tcphdr* _tcphdr; class Private; Private *d; }; /*====================================================================================== * OPacketCapturer *======================================================================================*/ /** * @brief A class based wrapper for network packet capturing. * * This class is the base of a high-level interface to the well known packet capturing * library libpcap. * @see http://tcpdump.org */ class OPacketCapturer : public QObject { Q_OBJECT public: /** * Constructor. */ OPacketCapturer( QObject* parent = 0, const char* name = 0 ); /** * Destructor. */ ~OPacketCapturer(); /** * Set the packet capturer to use blocking or non-blocking IO. This can be useful when * not using the socket notifier, e.g. without an application object. */ void setBlocking( bool ); /** * @returns true if the packet capturer uses blocking IO calls. */ bool blocking() const; /** * Close the packet capturer. This is automatically done in the destructor. */ void close(); /** * Close the output capture file. */ void closeDumpFile(); /** * @returns the data link type. * @see <pcap.h> for possible values. */ int dataLink() const; /** * Dump a packet to the output capture file. */ void dump( OPacket* ); /** * @returns the file descriptor of the packet capturer. This is only useful, if * not using the socket notifier, e.g. without an application object. */ int fileno() const; /** * @returns the next @ref OPacket from the packet capturer. * @note If blocking mode is true then this call might block. */ OPacket* next(); /** * @returns the next @ref OPacket from the packet capturer, if * one arrives within @a time milliseconds. */ OPacket* next( int time ); /** * Open the packet capturer to capture packets in live-mode from @a interface. */ bool open( const QString& interface ); /** * Open the packet capturer to capture packets in offline-mode from @a filename. */ bool openCaptureFile( const QString& filename ); /** * Open a prerecorded tcpdump compatible capture file for use with @ref dump() */ bool openDumpFile( const QString& filename ); /** * @returns true if the packet capturer is open */ bool isOpen() const; /** * @returns the snapshot length of this packet capturer */ int snapShot() const; /** * @returns true if the input capture file has a different byte-order * than the byte-order of the running system. */ bool swapped() const; /** * @returns the libpcap version string used to write the input capture file. */ QString version() const; /** * @returns the packet statistic database. * @see QMap */ const QMap<QString,int>& statistics() const; /** * Enable or disable the auto-delete option. * If auto-delete is enabled, then the packet capturer will delete a packet right * after it has been emit'ted. This is the default, which is useful if the packet * capturer has the only reference to the packets. If you pass the packet for adding * into a collection or do processing after the SLOT, the auto delete must be disabled. */ void setAutoDelete( bool enable ); /** * @returns the auto-delete value. */ bool autoDelete() const; signals: /** * This signal is emitted, when a packet has been received. */ void receivedPacket( Opie::Net::OPacket* ); protected slots: void readyToReceive(); protected: QString _name; // devicename bool _open; // check this before doing pcap calls pcap_t* _pch; // pcap library handle pcap_dumper_t* _pcd; // pcap dumper handle QSocketNotifier* _sn; // socket notifier for main loop mutable char _errbuf[PCAP_ERRBUF_SIZE]; // holds error strings from libpcap QMap<QString, int> _stats; // statistics; bool _autodelete; // if we auto delete packets after emit class Private; // Private Forward declaration Private *d; // if we need to add data }; } } #endif // OPCAP_H |