diff options
Diffstat (limited to 'ksim/monitors/snmp')
50 files changed, 6539 insertions, 0 deletions
diff --git a/ksim/monitors/snmp/Makefile.am b/ksim/monitors/snmp/Makefile.am new file mode 100644 index 0000000..0c922c9 --- /dev/null +++ b/ksim/monitors/snmp/Makefile.am @@ -0,0 +1,16 @@ +kde_module_LTLIBRARIES = ksim_snmp.la +ksim_snmp_la_SOURCES = plugin.cpp view.cpp configpage.cpp configwidget.ui snmp.cpp hostdialogbase.ui hostdialog.cpp value.cpp monitor.cpp \ + monitordialogbase.ui monitordialog.cpp labelmonitor.cpp chartmonitor.cpp \ + identifier.cpp monitorconfig.cpp hostconfig.cpp session.cpp probedialog.cpp snmplib.cpp \ + pdu.cpp proberesultdialogbase.ui proberesultdialog.cpp browsedialogbase.ui browsedialog.cpp \ + walker.cpp + +ksim_snmp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_snmp_la_LIBADD = ../../library/libksimcore.la $(LIB_KIO) $(LIBSNMP) + +INCLUDES= -I$(top_srcdir)/ksim/library $(all_includes) + +METASOURCES = AUTO + +mon_DATA = Snmp.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/snmp/Snmp.desktop b/ksim/monitors/snmp/Snmp.desktop new file mode 100644 index 0000000..b6ceb4c --- /dev/null +++ b/ksim/monitors/snmp/Snmp.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Comment=Snmp Status Monitor +Comment[ar]=مراقب حالة Snmp +Comment[bg]=Мониторинг на Snmp +Comment[bs]=Nadzor SNMP statusa +Comment[ca]=Monitor d'estat snmp +Comment[cs]=Monitor stavu SNMP +Comment[cy]=Monitr Cyflwr Snmp +Comment[da]=Snmp statusovervågning +Comment[de]=Statusanzeige für SNMP +Comment[el]=Επόπτης κατάστασης snmp +Comment[eo]=Monitoro por la Snmp-stato +Comment[es]=Monitor de estado de Snmp +Comment[et]=Snmp oleku monitooring +Comment[eu]=Snmp Egoera Begiralea +Comment[fa]=نمایشگر وضعیت Snmp +Comment[fi]=SNPP-tilavalvoja +Comment[fr]=Indicateur d'état snmp +Comment[ga]=Monatóir Stádais SNMP +Comment[hi]=एसएनएमपी स्थिति मॉनीटर +Comment[hu]=Snmp állapotmonitor +Comment[is]=Snmp eftirlitstól +Comment[it]=Controllo di stato SNMP +Comment[ja]=Snmp ステータスモニタ +Comment[ka]=Snmp სტატუსის მონიტორი +Comment[kk]=SNMP күйін бақылау +Comment[km]=កម្មវិធីត្រួតពិនិត្យស្ថានភាព Snmp +Comment[lt]=Snmp būsenos stebėtojas +Comment[mk]=Монитор за статусот на Snmp +Comment[nb]=Overvåkning av status via SNMP +Comment[nds]=SNMP-Statuskieker +Comment[ne]=Snmp स्थिति मोनिटर +Comment[nl]=Snmp Statusbewaking +Comment[nn]=Overvaking av status via SNMP +Comment[pa]=Snmp ਹਾਲਤ ਨਿਗਰਾਨ +Comment[pl]=Monitor statusu Snmp +Comment[pt]=Monitor de Estado do SNMP +Comment[pt_BR]=Monitor de estado do SNMP +Comment[ro]=Monitor stare SNMP +Comment[ru]=Монитор состояния SNMP +Comment[sk]=Monitor stavu SNMP +Comment[sl]=Nadzornik stanja Snmp +Comment[sr]=Надгледање статуса Snmp-а +Comment[sr@Latn]=Nadgledanje statusa Snmp-a +Comment[sv]=Övervakar SNMP-status +Comment[ta]=Snmp நிலை கண்காணி +Comment[tg]=Дидабони Ҳолати Snmp +Comment[tr]=Snmp Durum Monitörü +Comment[uk]=Монітор стану мережі (snmp протокол) +Comment[wa]=Corwaitoe di l' estat snmp +Comment[zh_CN]=Snmp 状态监视器 +Comment[zh_TW]=Snmp 狀態監視器 +Icon=network +Name=Snmp +Name[cs]=SNMP +Name[de]=SNMP +Name[ga]=SNMP +Name[hi]=एसएनएमपी +Name[it]=SNMP +Name[kk]=SNMP +Name[nds]=SNMP +Name[ro]=SNMP +Name[sk]=SNMP +Name[sv]=SNMP +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=snmp +X-KSIM-COPYRIGHT=(C) 2003 Simon Hausmann +X-KSIM-EMAIL=hausmann@kde.org +X-KSIM-PREFS=Snmp +X-KSIM-AUTHOR=Simon Hausmann diff --git a/ksim/monitors/snmp/browsedialog.cpp b/ksim/monitors/snmp/browsedialog.cpp new file mode 100644 index 0000000..d196ec8 --- /dev/null +++ b/ksim/monitors/snmp/browsedialog.cpp @@ -0,0 +1,147 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "browsedialog.h" + +#include <qlabel.h> + +#include <klistview.h> +#include <kguiitem.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <klineedit.h> + +using namespace KSim::Snmp; + +BrowseDialog::BrowseDialog( const HostConfig &hostConfig, const QString ¤tOid, QWidget *parent, const char *name ) + : BrowseDialogBase( parent, name ), m_host( hostConfig ) +{ + stop->setGuiItem( KGuiItem( i18n( "&Stop" ), "stop" ) ); + + browserContents->setSorting( -1 ); + + selectedObject->setText( currentOid ); + + m_walker = 0; + + baseOids << "1.3.6.1.2" << "1.3.6.1.4"; + nextWalk(); +} + +QString BrowseDialog::selectedObjectIdentifier() const +{ + return selectedObject->text(); +} + +void BrowseDialog::stopAllWalks() +{ + baseOids.clear(); + stopWalker(); +} + +void BrowseDialog::insertBrowseItem( const Walker::Result &result ) +{ + if ( !result.success || + result.data.type() == Value::EndOfMIBView || + result.data.type() == Value::NoSuchInstance || + result.data.type() == Value::NoSuchObject ) { + + nextWalk(); + return; + } + + QListViewItem *i = new QListViewItem( browserContents, browserContents->lastItem(), result.identifierString, result.dataString ); + applyFilter( i ); +} + +void BrowseDialog::applyFilter() +{ + for ( QListViewItem *i = browserContents->firstChild(); + i; i = i->nextSibling() ) + applyFilter( i ); +} + +void BrowseDialog::nextWalk() +{ + stopWalker(); + + if ( baseOids.isEmpty() ) + return; + + QString baseOidString = baseOids.pop(); + Identifier id = Identifier::fromString( baseOidString ); + if ( id.isNull() ) + return; + startWalk( id ); +} + +void BrowseDialog::startWalk( const Identifier &startOid ) +{ + stopWalker(); + + m_walker = new Walker( m_host, startOid, this ); + connect( m_walker, SIGNAL( resultReady( const Walker::Result & ) ), + this, SLOT( insertBrowseItem( const Walker::Result & ) ) ); + connect( m_walker, SIGNAL( finished() ), + this, SLOT( nextWalk() ) ); + + stop->setEnabled( true ); +} + +void BrowseDialog::stopWalker() +{ + if ( !m_walker ) + return; + + disconnect( m_walker, SIGNAL( resultReady( const Walker::Result & ) ), + this, SLOT( insertBrowseItem( const Walker::Result & ) ) ); + disconnect( m_walker, SIGNAL( finished() ), + this, SLOT( nextWalk() ) ); + + m_walker->deleteLater(); + m_walker = 0; + + stop->setEnabled( false ); +} + +void BrowseDialog::objectSelected( QListViewItem *item ) +{ + selectedObject->setText( item->text( 0 ) ); +} + +void BrowseDialog::applyFilter( QListViewItem *item ) +{ + QString filterText = filter->text(); + + if ( filterText.isEmpty() ) { + item->setVisible( true ); + return; + } + + if ( item->text( 0 ).find( filterText, 0 /*index*/, false /*case sensitive*/ ) == -1 ) { + item->setVisible( false ); + return; + } + + item->setVisible( true ); +} + +#include "browsedialog.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/browsedialog.h b/ksim/monitors/snmp/browsedialog.h new file mode 100644 index 0000000..cb6466a --- /dev/null +++ b/ksim/monitors/snmp/browsedialog.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef BROWSEDIALOG_H +#define BROWSEDIALOG_H + +#include "browsedialogbase.h" + +#include "hostconfig.h" +#include "identifier.h" +#include "value.h" +#include "snmp.h" +#include "walker.h" + +#include <qvaluestack.h> + +namespace KSim +{ + +namespace Snmp +{ + +class BrowseDialog : public BrowseDialogBase +{ + Q_OBJECT +public: + BrowseDialog( const HostConfig &hostConfig, const QString ¤tOid, QWidget *parent, const char *name = 0 ); + + QString selectedObjectIdentifier() const; + +protected: + virtual void stopAllWalks(); + virtual void applyFilter(); + virtual void objectSelected( QListViewItem *item ); + +private slots: + void insertBrowseItem( const Walker::Result &browseResult ); + void nextWalk(); + +private: + void applyFilter( QListViewItem *item ); + void startWalk( const Identifier &startOid ); + void stopWalker(); + + HostConfig m_host; + Walker *m_walker; + QValueStack<QString> baseOids; +}; + +} +} + +#endif // BROWSEDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/browsedialogbase.ui b/ksim/monitors/snmp/browsedialogbase.ui new file mode 100644 index 0000000..17459f8 --- /dev/null +++ b/ksim/monitors/snmp/browsedialogbase.ui @@ -0,0 +1,262 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::BrowseDialogBase</class> +<widget class="KDialog"> + <property name="name"> + <cstring>MyDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>650</width> + <height>532</height> + </rect> + </property> + <property name="caption"> + <string>Browse</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Filter:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>filter</cstring> + </property> + </widget> + <widget class="Line"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>VLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>stop</cstring> + </property> + <property name="text"> + <string>Stop</string> + </property> + </widget> + </hbox> + </widget> + <widget class="KListView" row="1" column="0"> + <column> + <property name="text"> + <string>Object</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>browserContents</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>blah</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Selected object:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>selectedObject</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>textLabel1</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>71</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>MyDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>MyDialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>stop</sender> + <signal>clicked()</signal> + <receiver>MyDialog</receiver> + <slot>stopAllWalks()</slot> + </connection> + <connection> + <sender>filter</sender> + <signal>textChanged(const QString&)</signal> + <receiver>MyDialog</receiver> + <slot>applyFilter()</slot> + </connection> + <connection> + <sender>browserContents</sender> + <signal>executed(QListViewItem*)</signal> + <receiver>MyDialog</receiver> + <slot>objectSelected(QListViewItem*)</slot> + </connection> +</connections> +<slots> + <slot access="protected">stopAllWalks()</slot> + <slot access="protected">applyFilter()</slot> + <slot access="protected">objectSelected(QListViewItem *)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdialog.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/chartmonitor.cpp b/ksim/monitors/snmp/chartmonitor.cpp new file mode 100644 index 0000000..1a32086 --- /dev/null +++ b/ksim/monitors/snmp/chartmonitor.cpp @@ -0,0 +1,83 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include "chartmonitor.h" + +#include <kio/global.h> + +using namespace KSim::Snmp; + +ChartMonitor::ChartMonitor( const MonitorConfig &config, QWidget *parent, const char *name ) + : KSim::Chart( true /* displayMeter */, 0, QString::null, parent, name ), + m_lastValue( 0 ), m_config( config ), m_firstSampleReceived( false ) +{ + setTitle( m_config.name ); + disableAutomaticUpdates(); +} + +void ChartMonitor::setData( const Value &data ) +{ + Q_UINT64 currentValue = convertToInt( data ); + + if ( data.isCounterType() ) { + int diff = currentValue - m_lastValue; + + if ( !m_firstSampleReceived ) { + diff = 0; + m_firstSampleReceived = true; + } + + m_lastValue = currentValue; + currentValue = diff; + } + + // move the graph and add the new sample then + updateDisplay(); + setValue( currentValue ); + if ( m_config.displayCurrentValueInline ) { + Q_UINT64 bytesPerSec = currentValue / ( m_config.refreshInterval.seconds + m_config.refreshInterval.minutes * 60 ); + setText( KIO::convertSize( bytesPerSec ), 0 ); + } +} + +Q_UINT64 ChartMonitor::convertToInt( const Value &data ) +{ + switch ( data.type() ) { + case Value::TimeTicks: + case Value::Int: return data.toInt(); + case Value::Gauge: + case Value::Counter: + case Value::UInt: return data.toUInt(); + case Value::Counter64: return data.toCounter64(); + case Value::Double: // ### not sure what to do here... + case Value::ByteArray: + case Value::Oid: // ### could treat this as a sort of hyperlink... hmm + case Value::IpAddress: + case Value::NoSuchObject: + case Value::NoSuchInstance: + case Value::EndOfMIBView: + case Value::Invalid: + case Value::Null: return 0; + } + return 0; +} + +#include "chartmonitor.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/chartmonitor.h b/ksim/monitors/snmp/chartmonitor.h new file mode 100644 index 0000000..30a58ad --- /dev/null +++ b/ksim/monitors/snmp/chartmonitor.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef CHARTMONITOR_H +#define CHARTMONITOR_H + +#include "chart.h" +#include "monitor.h" + +namespace KSim +{ + +namespace Snmp +{ + +class ChartMonitor : public KSim::Chart +{ + Q_OBJECT +public: + ChartMonitor( const MonitorConfig &config, QWidget *parent, const char *name = 0 ); + +public slots: + void setData( const Value &data ); + +private: + Q_UINT64 m_lastValue; + MonitorConfig m_config; + bool m_firstSampleReceived; + + static Q_UINT64 convertToInt( const Value &data ); +}; + +} + +} + +#endif // CHARTMONITOR_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/configpage.cpp b/ksim/monitors/snmp/configpage.cpp new file mode 100644 index 0000000..d15d606 --- /dev/null +++ b/ksim/monitors/snmp/configpage.cpp @@ -0,0 +1,313 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "configpage.h" +#include "plugin.h" + +#include "configwidget.h" +#include "hostdialog.h" +#include "monitordialog.h" + +#include <qlayout.h> +#include <qgroupbox.h> +#include <qpushbutton.h> + +#include <kconfig.h> +#include <klistview.h> +#include <kmessagebox.h> +#include <klocale.h> + +using namespace KSim::Snmp; + +static bool listViewHasSelection( QListView *lv ) +{ + for ( QListViewItem *i = lv->firstChild(); i; i = i->itemBelow() ) + if ( i->isSelected() ) + return true; + return false; +} + +ConfigPage::ConfigPage( Plugin *parent, const char *name ) + : KSim::PluginPage( parent, name ) +{ + ( new QVBoxLayout( this ) )->setAutoAdd( true ); + + m_page = new ConfigWidget( this ); + + connect( m_page->addHost, SIGNAL( clicked() ), + this, SLOT( addNewHost() ) ); + connect( m_page->modifyHost, SIGNAL( clicked() ), + this, SLOT( modifyHost() ) ); + connect( m_page->removeHost, SIGNAL( clicked() ), + this, SLOT( removeHost() ) ); + + connect( m_page->addMonitor, SIGNAL( clicked() ), + this, SLOT( addNewMonitor() ) ); + connect( m_page->modifyMonitor, SIGNAL( clicked() ), + this, SLOT( modifyMonitor() ) ); + connect( m_page->removeMonitor, SIGNAL( clicked() ), + this, SLOT( removeMonitor() ) ); + + connect( m_page->hosts, SIGNAL( selectionChanged() ), + this, SLOT( disableOrEnableSomeWidgets() ) ); + connect( m_page->monitors, SIGNAL( selectionChanged() ), + this, SLOT( disableOrEnableSomeWidgets() ) ); +} + +ConfigPage::~ConfigPage() +{ +} + +void ConfigPage::saveConfig() +{ + KConfig &cfg = *config(); + + // collect garbage + removeAllHostGroups(); + removeAllMonitorGroups(); + + QStringList hosts = m_hosts.save( cfg ); + QStringList monitors = m_monitors.save( cfg ); + + cfg.setGroup( "General" ); + cfg.writeEntry( "Hosts", hosts ); + cfg.writeEntry( "Monitors", monitors ); +} + +void ConfigPage::readConfig() +{ + KConfig &cfg = *config(); + + cfg.setGroup( "General" ); + QStringList hosts = cfg.readListEntry( "Hosts" ); + QStringList monitors = cfg.readListEntry( "Monitors" ); + + m_hosts.load( cfg, hosts ); + m_monitors.load( cfg, monitors, m_hosts ); + + fillGui(); +} + +void ConfigPage::addNewHost() +{ + HostDialog dlg( this ); + if ( dlg.exec() ) { + HostConfig src = dlg.settings(); + m_hosts.insert( src.name, src ); + + ( void )new HostItem( m_page->hosts, src ); + } + + disableOrEnableSomeWidgets(); +} + +void ConfigPage::modifyHost() +{ + HostItem *currentItem = dynamic_cast<HostItem *>( m_page->hosts->currentItem() ); + if ( !currentItem ) + return; + + HostConfigMap::Iterator hostIt = m_hosts.find( currentItem->text( 0 ) ); + if ( hostIt == m_hosts.end() ) + return; + + HostDialog dlg( *hostIt, this ); + if ( dlg.exec() ) { + HostConfig newHost = dlg.settings(); + + if ( newHost.name != hostIt.key() ) { + m_hosts.remove( hostIt ); + hostIt = m_hosts.insert( newHost.name, newHost ); + } else + *hostIt = newHost; + + currentItem->setFromHostConfig( newHost ); + } +} + +void ConfigPage::removeHost() +{ + HostItem *currentItem = dynamic_cast<HostItem *>( m_page->hosts->currentItem() ); + if ( !currentItem ) + return; + + HostConfigMap::Iterator hostIt = m_hosts.find( currentItem->text( 0 ) ); + if ( hostIt == m_hosts.end() ) + return; + + QStringList monitors = monitorsForHost( *hostIt ); + if ( !monitors.isEmpty() ) { + int answer = KMessageBox::warningContinueCancelList( + this, + i18n( "This host has the following monitor associated. Do you really want to delete this host entry?", + "This host has the following %n monitors associated. Do you really want to delete this host entry?", + monitors.count() ), + monitors, + i18n( "Delete Host Entry" ), + i18n( "Delete" ) ); + + if ( answer != KMessageBox::Continue ) + return; + + removeMonitors( monitors ); + } + + m_hosts.remove( hostIt ); + delete currentItem; + + disableOrEnableSomeWidgets(); +} + +void ConfigPage::addNewMonitor() +{ + MonitorDialog dlg( m_hosts, this ); + if ( dlg.exec() ) { + MonitorConfig monitor = dlg.monitorConfig(); + m_monitors.insert( monitor.name, monitor ); + + ( void )new MonitorItem( m_page->monitors, monitor ); + } +} + +void ConfigPage::modifyMonitor() +{ + MonitorItem *currentItem = dynamic_cast<MonitorItem *>( m_page->monitors->currentItem() ); + if ( !currentItem ) + return; + + MonitorConfigMap::Iterator monitorIt = m_monitors.find( currentItem->text( 0 ) ); + if ( monitorIt == m_monitors.end() ) + return; + + MonitorDialog dlg( *monitorIt, m_hosts, this ); + if ( dlg.exec() ) { + MonitorConfig newMonitor = dlg.monitorConfig(); + + if ( newMonitor.name != monitorIt.key() ) { + m_monitors.remove( monitorIt ); + monitorIt = m_monitors.insert( newMonitor.name, newMonitor ); + } else + *monitorIt = newMonitor; + + currentItem->setFromMonitor( newMonitor ); + } +} + +void ConfigPage::removeMonitor() +{ + MonitorItem *currentItem = dynamic_cast<MonitorItem *>( m_page->monitors->currentItem() ); + if ( !currentItem ) + return; + + MonitorConfigMap::Iterator monitorIt = m_monitors.find( currentItem->text( 0 ) ); + if ( monitorIt == m_monitors.end() ) + return; + + m_monitors.remove( monitorIt ); + delete currentItem; +} + +void ConfigPage::disableOrEnableSomeWidgets() +{ + bool hostSelected = listViewHasSelection( m_page->hosts ); + bool monitorSelected = listViewHasSelection( m_page->monitors ); + + m_page->modifyHost->setEnabled( hostSelected ); + m_page->removeHost->setEnabled( hostSelected ); + + m_page->modifyMonitor->setEnabled( monitorSelected ); + m_page->removeMonitor->setEnabled( monitorSelected ); + + m_page->monitorGroup->setEnabled( !m_hosts.isEmpty() ); +} + +void ConfigPage::removeMonitors( QStringList monitors ) +{ + for ( QStringList::ConstIterator it = monitors.begin(); + it != monitors.end(); ++it ) + m_monitors.remove( *it ); + + QListViewItem *item = m_page->monitors->firstChild(); + while ( item ) { + QListViewItem *nextItem = item->itemBelow(); + + for ( QStringList::Iterator it = monitors.begin(); + it != monitors.end(); ++it ) + if ( item->text( 0 ) == *it ) { + + monitors.remove( it ); + + delete item; + + break; + } + + item = nextItem; + } +} + +void ConfigPage::removeAllHostGroups() +{ + removeConfigGroups( "Host " ); +} + +void ConfigPage::removeAllMonitorGroups() +{ + removeConfigGroups( "Monitor " ); +} + +void ConfigPage::removeConfigGroups( const QString &prefix ) +{ + KConfig &cfg = *config(); + + QStringList groups = cfg.groupList(); + for ( QStringList::ConstIterator it = groups.begin(); it != groups.end(); ++it ) + if ( ( *it ).startsWith( prefix ) ) + cfg.deleteGroup( *it, true /* deep */ ); +} + +void ConfigPage::fillGui() +{ + m_page->hosts->clear(); + m_page->monitors->clear(); + + for ( HostConfigMap::ConstIterator it = m_hosts.begin(); it != m_hosts.end(); ++it ) + ( void )new HostItem( m_page->hosts, *it ); + + for ( MonitorConfigMap::ConstIterator it = m_monitors.begin(); it != m_monitors.end(); ++it ) + ( void )new MonitorItem( m_page->monitors, *it ); + + disableOrEnableSomeWidgets(); +} + +QStringList ConfigPage::monitorsForHost( const HostConfig &host ) const +{ + QStringList monitors; + + for ( MonitorConfigMap::ConstIterator it = m_monitors.begin(); + it != m_monitors.end(); ++it ) + if ( ( *it ).host == host ) + monitors << ( *it ).name; + + return monitors; +} + +#include "configpage.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/configpage.h b/ksim/monitors/snmp/configpage.h new file mode 100644 index 0000000..42c7579 --- /dev/null +++ b/ksim/monitors/snmp/configpage.h @@ -0,0 +1,120 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef CONFIGPAGE_H +#define CONFIGPAGE_H + +#include <pluginmodule.h> +#include <klistview.h> + +#include "monitorconfig.h" +#include "hostconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +class HostItem : public QListViewItem +{ +public: + HostItem( QListView *parent, const KSim::Snmp::HostConfig &src ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + { + setFromHostConfig( src ); + } + + HostItem( QListView *parent ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + {} + + void setFromHostConfig( const KSim::Snmp::HostConfig &src ) + { + setText( 0, src.name ); + setText( 1, QString::number( src.port ) ); + setText( 2, snmpVersionToString( src.version ) ); + } +}; + +class MonitorItem : public QListViewItem +{ +public: + MonitorItem( QListView *parent, const KSim::Snmp::MonitorConfig &monitor ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + { + setFromMonitor( monitor ); + } + + MonitorItem( QListView *parent ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + {} + + void setFromMonitor( const KSim::Snmp::MonitorConfig &monitor ) + { + setText( 0, monitor.name ); + setText( 1, monitorDisplayTypeToString( monitor.display ) ); + } +}; + +class ConfigWidget; +class Plugin; + +class ConfigPage : public KSim::PluginPage +{ + Q_OBJECT +public: + ConfigPage( Plugin *parent, const char *name ); + ~ConfigPage(); + + virtual void saveConfig(); + virtual void readConfig(); + +private slots: + void addNewHost(); + void modifyHost(); + void removeHost(); + void addNewMonitor(); + void modifyMonitor(); + void removeMonitor(); + + void disableOrEnableSomeWidgets(); + +private: + void removeMonitors( QStringList monitors ); + + void removeAllHostGroups(); + void removeAllMonitorGroups(); + void removeConfigGroups( const QString &prefix ); + void fillGui(); + + QStringList monitorsForHost( const HostConfig &host ) const; + + ConfigWidget *m_page; + KSim::Snmp::HostConfigMap m_hosts; + KSim::Snmp::MonitorConfigMap m_monitors; +}; + +} + +} + +#endif // CONFIGPAGE_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/configure.in.in b/ksim/monitors/snmp/configure.in.in new file mode 100644 index 0000000..2d266d7 --- /dev/null +++ b/ksim/monitors/snmp/configure.in.in @@ -0,0 +1,40 @@ +AC_ARG_WITH(snmp, + [AC_HELP_STRING(--with-snmp, + [enable support for SNMP @<:@default=check@:>@])], + [], with_snmp=check) + +enable_snmp=no +if test "x$with_snmp" != xno; then + KDE_CHECK_HEADER( net-snmp/library/snmp_api.h, + [ have_netsnmp_h=yes ], [ have_netsnmp_h=no ], + [ #include <net-snmp/net-snmp-config.h> + #include <net-snmp/types.h> + ] + ) + + if test "$have_netsnmp_h" = yes; then + KDE_CHECK_LIB( netsnmp, snmp_sess_init, [ + AC_SUBST( LIBSNMP, "-lnetsnmp" ) + enable_snmp=yes + ], [], [] ) + fi + + if test "$enable_snmp" != yes; then + AC_MSG_CHECKING([if libnetsnmp needs -lcrypto]) + + dnl use a different symbol to prevent autoconf from caching + KDE_CHECK_LIB( netsnmp, snmp_open, [ + AC_SUBST( LIBSNMP, "-lnetsnmp -lcrypto" ) + enable_snmp=yes + AC_MSG_RESULT(yes) + ], [ + AC_MSG_RESULT(no) + ], [-lcrypto] ) + fi + + if test "x$with_snmp" != xcheck && test "x$enable_snmp" != xyes; then + AC_MSG_ERROR([--with-snmp was given, but test for net-snmp failed]) + fi +fi + +AM_CONDITIONAL(include_ksim_monitors_snmp, test "x$enable_snmp" = xyes) diff --git a/ksim/monitors/snmp/configwidget.ui b/ksim/monitors/snmp/configwidget.ui new file mode 100644 index 0000000..c121184 --- /dev/null +++ b/ksim/monitors/snmp/configwidget.ui @@ -0,0 +1,215 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::ConfigWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ConfigWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>740</width> + <height>597</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>hostGroup</cstring> + </property> + <property name="title"> + <string>SNMP Hosts</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>removeHost</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>modifyHost</cstring> + </property> + <property name="text"> + <string>Modify...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>addHost</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="KListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Host</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Port</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Version</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>hosts</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>141</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>monitorGroup</cstring> + </property> + <property name="title"> + <string>SNMP Monitors</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>addMonitor</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>modifyMonitor</cstring> + </property> + <property name="text"> + <string>Modify...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>removeMonitor</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>121</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>monitors</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </vbox> +</widget> +<tabstops> + <tabstop>hosts</tabstop> + <tabstop>addHost</tabstop> + <tabstop>modifyHost</tabstop> + <tabstop>removeHost</tabstop> + <tabstop>monitors</tabstop> + <tabstop>addMonitor</tabstop> + <tabstop>modifyMonitor</tabstop> + <tabstop>removeMonitor</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/hostconfig.cpp b/ksim/monitors/snmp/hostconfig.cpp new file mode 100644 index 0000000..1b96541 --- /dev/null +++ b/ksim/monitors/snmp/hostconfig.cpp @@ -0,0 +1,152 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "hostconfig.h" + +#include <kstringhandler.h> + +#include <netdb.h> + +using namespace KSim::Snmp; + +static int defaultSnmpPort() +{ + servent *ent = getservbyname( "snmp", 0 ); + if ( !ent ) + return 161; + return ent->s_port; +} + +bool HostConfig::load( KConfigBase &config ) +{ + name = config.readEntry( "Host" ); + if ( name.isEmpty() ) + return false; + + port = config.readNumEntry( "Port", defaultSnmpPort() ); + + bool ok = false; + version = stringToSnmpVersion( config.readEntry( "Version" ), &ok ); + if ( !ok ) + return false; + + if ( version != SnmpVersion3 ) { + community = config.readEntry( "Community" ); + return true; + } + + securityName = config.readEntry( "SecurityName" ); + + securityLevel = stringToSecurityLevel( config.readEntry( "SecurityLevel" ), &ok ); + if ( !ok ) + return false; + + if ( securityLevel == NoAuthPriv ) + return true; + + authentication.protocol = stringToAuthenticationProtocol( config.readEntry( "AuthType" ), &ok ); + if ( !ok ) + return false; + authentication.key = KStringHandler::obscure( config.readEntry( "AuthPassphrase" ) ); + + if ( securityLevel == AuthNoPriv ) + return true; + + privacy.protocol = stringToPrivacyProtocol( config.readEntry( "PrivType" ), &ok ); + if ( !ok ) + return false; + privacy.key = KStringHandler::obscure( config.readEntry( "PrivPassphrase" ) ); + + return true; +} + +void HostConfig::save( KConfigBase &config ) const +{ + if ( isNull() ) + return; + + config.writeEntry( "Host", name ); + if ( port != 0 ) + config.writeEntry( "Port", port ); + + config.writeEntry( "Version", snmpVersionToString( version ) ); + + if ( version != SnmpVersion3 ) { + writeIfNotEmpty( config, "Community", community ); + return; + } + + writeIfNotEmpty( config, "SecurityName", securityName ); + + config.writeEntry( "SecurityLevel", securityLevelToString( securityLevel ) ); + + if ( securityLevel == NoAuthPriv ) + return; + + writeIfNotEmpty( config, "AuthType", authenticationProtocolToString( authentication.protocol ) ); + writeIfNotEmpty( config, "AuthPassphrase", KStringHandler::obscure( authentication.key ) ); + + if ( securityLevel == AuthNoPriv ) + return; + + writeIfNotEmpty( config, "PrivType", privacyProtocolToString( privacy.protocol ) ); + writeIfNotEmpty( config, "PrivPassphrase", KStringHandler::obscure( privacy.key ) ); +} + +void HostConfig::writeIfNotEmpty( KConfigBase &config, const QString &name, const QString &value ) +{ + if ( value.isEmpty() ) + return; + + config.writeEntry( name, value ); +} + +void HostConfigMap::load( KConfigBase &config, const QStringList &hosts ) +{ + clear(); + + for ( QStringList::ConstIterator it = hosts.begin(); it != hosts.end(); ++it ) { + config.setGroup( "Host " + *it ); + + HostConfig src; + if ( !src.load( config ) ) + continue; + + insert( *it, src ); + } +} + +QStringList HostConfigMap::save( KConfigBase &config ) const +{ + QStringList hostList; + + for ( ConstIterator it = begin(); it != end(); ++it ) { + QString host = it.key(); + + hostList << host; + + config.setGroup( "Host " + host ); + ( *it ).save( config ); + } + + return hostList; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostconfig.h b/ksim/monitors/snmp/hostconfig.h new file mode 100644 index 0000000..d19de9b --- /dev/null +++ b/ksim/monitors/snmp/hostconfig.h @@ -0,0 +1,86 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HOSTCONFIG_H +#define HOSTCONFIG_H + +#include "snmp.h" + +namespace KSim +{ + +namespace Snmp +{ + +struct HostConfig +{ + HostConfig() {} + HostConfig( KConfigBase &config ) + { load( config ); } + + QString name; // hostname + ushort port; + + SnmpVersion version; + + QString community; + + QString securityName; + + SecurityLevel securityLevel; + + struct + { + AuthenticationProtocol protocol; + QString key; + } authentication; + struct + { + PrivacyProtocol protocol; + QString key; + } privacy; + + bool load( KConfigBase &config ); + void save( KConfigBase &config ) const; + + bool isNull() const { return name.isEmpty(); } + + bool operator==( const HostConfig &rhs ) const + { return name == rhs.name; } + +private: + static void writeIfNotEmpty( KConfigBase &config, const QString &name, const QString &value ); +}; + +struct HostConfigMap : public QMap< QString, HostConfig > +{ + HostConfigMap() {} + HostConfigMap( const QMap< QString, HostConfig > &rhs ) + : QMap< QString, HostConfig >( rhs ) {} + + void load( KConfigBase &config, const QStringList &hosts ); + QStringList save( KConfigBase &config ) const; +}; + +} +} + +#endif // HOSTCONFIG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostdialog.cpp b/ksim/monitors/snmp/hostdialog.cpp new file mode 100644 index 0000000..a1ccdc3 --- /dev/null +++ b/ksim/monitors/snmp/hostdialog.cpp @@ -0,0 +1,193 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "hostdialog.h" +#include "probedialog.h" +#include "proberesultdialog.h" + +#include <qcombobox.h> +#include <qwidgetstack.h> +#include <klineedit.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qspinbox.h> + +#include <klocale.h> +#include <kmessagebox.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +HostDialog::HostDialog( QWidget *parent, const char *name ) + : HostDialogBase( parent, name ) +{ + init(); + port->setValue( 161 ); +} + +HostDialog::HostDialog( const HostConfig &src, QWidget *parent, const char *name ) + : HostDialogBase( parent, name ) +{ + init( src ); +} + +HostConfig HostDialog::settings() const +{ + HostConfig result; + + result.name = hostName->text(); + result.port = port->value(); + + result.version = stringToSnmpVersion( snmpVersion->currentText() ); + if ( result.version != SnmpVersion3 ) { + result.community = communityString->text(); + } + + result.securityName = securityName->text(); + + result.securityLevel = stringToSecurityLevel( securityLevel->currentText() ); + + if ( result.securityLevel == NoAuthPriv ) + return result; + + result.authentication.protocol = stringToAuthenticationProtocol( authenticationType->currentText() ); + result.authentication.key = authenticationPassphrase->text(); + + if ( result.securityLevel == AuthNoPriv ) + return result; + + result.privacy.protocol = stringToPrivacyProtocol( privacyType->currentText() ); + result.privacy.key = privacyPassphrase->text(); + + return result; +} + +void HostDialog::showSnmpAuthenticationDetailsForVersion( const QString &versionStr ) +{ + bool ok = false; + SnmpVersion version = stringToSnmpVersion( versionStr, &ok ); + assert( ok ); + + authenticationDetails->raiseWidget( version == SnmpVersion3 ? snmpV3Page : snmpV1Page ); +} + +void HostDialog::enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel( const QString &levelStr ) +{ + bool ok = false; + SecurityLevel level = stringToSecurityLevel( levelStr, &ok ); + assert( ok ); + + bool enableAuthentication = level != NoAuthPriv; + bool enablePrivacy = level == AuthPriv; + + authenticationTypeLabel->setEnabled( enableAuthentication ); + authenticationType->setEnabled( enableAuthentication ); + authenticationPassphraseLabel->setEnabled( enableAuthentication ); + authenticationPassphrase->setEnabled( enableAuthentication ); + + privacyTypeLabel->setEnabled( enablePrivacy ); + privacyType->setEnabled( enablePrivacy ); + privacyPassphraseLabel->setEnabled( enablePrivacy ); + privacyPassphrase->setEnabled( enablePrivacy ); +} + +void HostDialog::checkValidity() +{ + bool enableOk = true; + bool ok = false; + SnmpVersion version = stringToSnmpVersion( snmpVersion->currentText(), &ok ); + assert( ok ); + + enableOk &= !hostName->text().isEmpty(); + + if ( version == SnmpVersion3 ) + enableOk &= !securityName->text().isEmpty(); + else + enableOk &= !communityString->text().isEmpty(); + + buttonOk->setEnabled( enableOk ); + testHostButton->setEnabled( enableOk ); +} + +void HostDialog::testHost() +{ + ProbeDialog dlg( settings(), this ); + if ( dlg.exec() ) { + ProbeDialog::ProbeResultList results = dlg.probeResults(); + + ProbeResultDialog resultDlg( settings(), results, this ); + resultDlg.exec(); + } +} + +void HostDialog::init( const HostConfig &src ) +{ + // hide these, there's nothing to choose right now. might be that + // net-snmp will support different privacy types in the future, but + // apparently not now. + privacyTypeLabel->hide(); + privacyType->hide(); + + snmpVersion->insertStringList( allSnmpVersions() ); + securityLevel->insertStringList( allSecurityLevels() ); + authenticationType->insertStringList( allAuthenticationProtocols() ); + privacyType->insertStringList( allPrivacyProtocols() ); + + if ( !src.isNull() ) + loadSettingsFromHostConfig( src ); + + showSnmpAuthenticationDetailsForVersion( snmpVersion->currentText() ); + enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel( securityLevel->currentText() ); + checkValidity(); +} + +void HostDialog::loadSettingsFromHostConfig( const HostConfig &src ) +{ + hostName->setText( src.name ); + port->setValue( src.port ); + + snmpVersion->setCurrentItem( allSnmpVersions().findIndex( snmpVersionToString( src.version ) ) ); + + if ( src.version != SnmpVersion3 ) { + communityString->setText( src.community ); + return; + } + + securityName->setText( src.securityName ); + + securityLevel->setCurrentItem( allSecurityLevels().findIndex( securityLevelToString( src.securityLevel ) ) ); + + if ( src.securityLevel == NoAuthPriv ) + return; + + authenticationType->setCurrentItem( allAuthenticationProtocols().findIndex( authenticationProtocolToString( src.authentication.protocol ) ) ); + authenticationPassphrase->setText( src.authentication.key ); + + if ( src.securityLevel == AuthNoPriv ) + return; + + privacyType->setCurrentItem( allPrivacyProtocols().findIndex( privacyProtocolToString( src.privacy.protocol ) ) ); + privacyPassphrase->setText( src.privacy.key ); +} + +#include "hostdialog.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostdialog.h b/ksim/monitors/snmp/hostdialog.h new file mode 100644 index 0000000..e296b7b --- /dev/null +++ b/ksim/monitors/snmp/hostdialog.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HOSTDIALOG_H +#define HOSTDIALOG_H + +#include "hostdialogbase.h" +#include "hostconfig.h" +#include "probedialog.h" + +namespace KSim +{ + +namespace Snmp +{ + +class HostDialog : public HostDialogBase +{ + Q_OBJECT +public: + HostDialog( QWidget *parent, const char *name = 0 ); + HostDialog( const HostConfig &src, QWidget *parent, const char *name = 0 ); + + HostConfig settings() const; + +private slots: + void showSnmpAuthenticationDetailsForVersion( const QString &versionStr ); + void enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel( const QString &levelStr ); + void checkValidity(); + void testHost(); + +private: + void init( const HostConfig &src = HostConfig() ); + void loadSettingsFromHostConfig( const HostConfig &src ); +}; + +} + +} + +#endif // HOSTDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostdialogbase.ui b/ksim/monitors/snmp/hostdialogbase.ui new file mode 100644 index 0000000..1ee9ee4 --- /dev/null +++ b/ksim/monitors/snmp/hostdialogbase.ui @@ -0,0 +1,526 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::HostDialogBase</class> +<comment>Much thanks to Frerich for hints/advice on the GUI design</comment> +<author>Simon Hausmann</author> +<widget class="KDialog"> + <property name="name"> + <cstring>HostDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>559</width> + <height>454</height> + </rect> + </property> + <property name="caption"> + <string>Configure Host</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="text"> + <string>&Hostname:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>hostName</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>hostName</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>&Port:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>port</cstring> + </property> + </widget> + <widget class="QSpinBox" row="0" column="3"> + <property name="name"> + <cstring>port</cstring> + </property> + <property name="maxValue"> + <number>65535</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <spacer row="0" column="4"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>91</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QButtonGroup" row="1" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>buttonGroup2</cstring> + </property> + <property name="title"> + <string>Authentication Details</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QWidgetStack" row="2" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>authenticationDetails</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>snmpV1Page</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>&Community String:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>communityString</cstring> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>41</height> + </size> + </property> + </spacer> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>160</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>communityString</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>snmpV3Page</cstring> + </property> + <attribute name="id"> + <number>1</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel6</cstring> + </property> + <property name="text"> + <string>S&ecurity name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>securityName</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel7</cstring> + </property> + <property name="text"> + <string>Security &level:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>securityLevel</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>authenticationTypeLabel</cstring> + </property> + <property name="text"> + <string>&Authentication type:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>authenticationType</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>privacyTypeLabel</cstring> + </property> + <property name="text"> + <string>P&rivacy type:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>privacyType</cstring> + </property> + </widget> + <widget class="QLabel" row="5" column="0"> + <property name="name"> + <cstring>privacyPassphraseLabel</cstring> + </property> + <property name="text"> + <string>Priva&cy passphrase:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>privacyPassphrase</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>authenticationPassphraseLabel</cstring> + </property> + <property name="text"> + <string>Authentication &passphrase:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>authenticationPassphrase</cstring> + </property> + </widget> + <spacer row="3" column="2"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>71</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>securityName</cstring> + </property> + </widget> + <widget class="QComboBox" row="4" column="1"> + <property name="name"> + <cstring>privacyType</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + <widget class="KLineEdit" row="5" column="1"> + <property name="name"> + <cstring>privacyPassphrase</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>securityLevel</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <property name="name"> + <cstring>authenticationType</cstring> + </property> + </widget> + <widget class="KLineEdit" row="3" column="1"> + <property name="name"> + <cstring>authenticationPassphrase</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + <spacer row="6" column="1"> + <property name="name"> + <cstring>spacer7</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + <widget class="Line" row="1" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>line3</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>&SNMP version:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>snmpVersion</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>snmpVersion</cstring> + </property> + </widget> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>351</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="Line" row="2" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>line2</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>testHostButton</cstring> + </property> + <property name="text"> + <string>Test Host...</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>220</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>HostDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>HostDialogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>snmpVersion</sender> + <signal>activated(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>showSnmpAuthenticationDetailsForVersion(const QString&)</slot> + </connection> + <connection> + <sender>securityLevel</sender> + <signal>activated(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel(const QString&)</slot> + </connection> + <connection> + <sender>hostName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>checkValidity()</slot> + </connection> + <connection> + <sender>securityName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>checkValidity()</slot> + </connection> + <connection> + <sender>communityString</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>checkValidity()</slot> + </connection> + <connection> + <sender>testHostButton</sender> + <signal>clicked()</signal> + <receiver>HostDialogBase</receiver> + <slot>testHost()</slot> + </connection> +</connections> +<tabstops> + <tabstop>hostName</tabstop> + <tabstop>port</tabstop> + <tabstop>snmpVersion</tabstop> + <tabstop>securityName</tabstop> + <tabstop>securityLevel</tabstop> + <tabstop>authenticationType</tabstop> + <tabstop>authenticationPassphrase</tabstop> + <tabstop>privacyType</tabstop> + <tabstop>privacyPassphrase</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>communityString</tabstop> +</tabstops> +<slots> + <slot access="private">showSnmpAuthenticationDetailsForVersion(const QString &)</slot> + <slot>enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel(const QString &)</slot> + <slot>checkValidity()</slot> + <slot access="protected">testHost()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdialog.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/identifier.cpp b/ksim/monitors/snmp/identifier.cpp new file mode 100644 index 0000000..25c188e --- /dev/null +++ b/ksim/monitors/snmp/identifier.cpp @@ -0,0 +1,129 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "identifier.h" +#include "snmp_p.h" +#include "snmplib.h" + +#include <assert.h> + +using namespace KSim::Snmp; + +Identifier::Data::Data( const oid *d, size_t length ) +{ + memcpy( data, d, length * sizeof( oid ) ); + this->length = length; +} + +Identifier::Identifier() + : d( new Data ) +{ +} + +Identifier::Identifier( Data *data ) + : d( data ) +{ + assert( d ); +} + +Identifier::Identifier( const Identifier &rhs ) + : d( new Data( *rhs.d ) ) +{ +} + +Identifier &Identifier::operator=( const Identifier &rhs ) +{ + if ( d == rhs.d ) + return *this; + + *d = *rhs.d; + + return *this; +} + +Identifier::~Identifier() +{ + delete d; +} + +Identifier Identifier::fromString( const QString &name, bool *ok ) +{ + Identifier res; + res.d->length = MAX_OID_LEN; + // if ( !get_node( name.ascii(), res.d->data, &res.d->length ) ) { + if ( name.isEmpty() || !SnmpLib::self()->snmp_parse_oid( name.ascii(), res.d->data, &res.d->length ) ) { + if ( ok ) + *ok = false; + return Identifier(); + } + + if ( ok ) + *ok = true; + + return res; +} + +QString Identifier::toString( PrintFlags flags ) const +{ + size_t buflen = 256; + size_t outlen = 0; + int overflow = 0; + + u_char *buf = ( u_char* )calloc( buflen, 1 ); + if ( !buf ) + return QString::null; + + int oldOutpuFormat = SnmpLib::self()->netsnmp_ds_get_int( NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT ); + SnmpLib::self()->netsnmp_ds_set_int( NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + flags == PrintAscii ? NETSNMP_OID_OUTPUT_MODULE : NETSNMP_OID_OUTPUT_NUMERIC ); + + SnmpLib::self()->netsnmp_sprint_realloc_objid_tree( &buf, &buflen, &outlen, 1 /* alloc realloc */, + &overflow, d->data, d->length ); + + SnmpLib::self()->netsnmp_ds_set_int( NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, oldOutpuFormat ); + + if ( overflow ) { + free( buf ); + return QString::null; + } + + QString result = QString::fromAscii( ( char* )buf ); + + free( buf ); + + return result; +} + +bool Identifier::operator==( const Identifier &rhs ) const +{ + return SnmpLib::self()->netsnmp_oid_equals( d->data, d->length, rhs.d->data, rhs.d->length ) == 0; +} + +bool Identifier::operator<( const Identifier &rhs ) const +{ + return SnmpLib::self()->snmp_oid_compare( d->data, d->length, rhs.d->data, rhs.d->length ) < 0; +} + +bool Identifier::isNull() const +{ + return d->length == 0; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/identifier.h b/ksim/monitors/snmp/identifier.h new file mode 100644 index 0000000..7da54dd --- /dev/null +++ b/ksim/monitors/snmp/identifier.h @@ -0,0 +1,72 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef IDENTIFIER_H +#define IDENTIFIER_H + +#include <qstring.h> +#include <qvaluelist.h> +#include <qmap.h> + +#include "value.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Identifier +{ +public: + friend class PDU; + struct Data; + + enum PrintFlags { PrintAscii, PrintNumeric }; + + Identifier(); + Identifier( Data *data ); + Identifier( const Identifier &rhs ); + Identifier &operator=( const Identifier &rhs ); + ~Identifier(); + + static Identifier fromString( const QString &name, bool *ok = 0 ); + + QString toString( PrintFlags flags = PrintAscii ) const; + + bool isNull() const; + + bool operator==( const Identifier &rhs ) const; + bool operator!=( const Identifier &rhs ) const + { return !operator==( rhs ); } + bool operator<( const Identifier &rhs ) const; + +private: + Data *d; +}; + +typedef QValueList<Identifier> IdentifierList; +typedef QMap<Identifier, Value> ValueMap; + +} +} + +#endif // IDENTIFIER_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/labelmonitor.cpp b/ksim/monitors/snmp/labelmonitor.cpp new file mode 100644 index 0000000..24e48c7 --- /dev/null +++ b/ksim/monitors/snmp/labelmonitor.cpp @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "labelmonitor.h" + +using namespace KSim::Snmp; + +LabelMonitor::LabelMonitor( const MonitorConfig &config, QWidget *parent, const char *name ) + : KSim::Label( parent, name ), m_config( config ) +{ +} + +void LabelMonitor::setData( const Value &data ) +{ + QString dataString = data.toString( m_config.refreshInterval.minutes == 0 ? Value::TimeTicksWithSeconds : 0 ); + + if ( m_config.useCustomFormatString ) { + QString text = m_config.customFormatString; + text.replace( "%n", m_config.name ); + text.replace( "%s", dataString ); + setText( text ); + } else + setText( m_config.name + ": " + dataString ); +} + +#include "labelmonitor.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/labelmonitor.h b/ksim/monitors/snmp/labelmonitor.h new file mode 100644 index 0000000..3e92c69 --- /dev/null +++ b/ksim/monitors/snmp/labelmonitor.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef LABELMONITOR_H +#define LABELMONITOR_H + +#include "label.h" +#include "value.h" +#include "monitorconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +class LabelMonitor : public KSim::Label +{ + Q_OBJECT +public: + LabelMonitor( const MonitorConfig &config, QWidget *parent, const char *name = 0 ); + +public slots: + void setData( const Value &data ); + +private: + MonitorConfig m_config; +}; + +} + +} + +#endif // LABELMONITOR_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitor.cpp b/ksim/monitors/snmp/monitor.cpp new file mode 100644 index 0000000..7a97825 --- /dev/null +++ b/ksim/monitors/snmp/monitor.cpp @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "monitor.h" + +#include <qtimer.h> +#include <qapplication.h> + +using namespace KSim::Snmp; + +Monitor::Monitor( const HostConfig &host, const Identifier &oid, int refresh, QObject *parent, const char *name ) + : QObject( parent, name ), m_oid( oid ), m_session( host ) +{ + if ( refresh > 0 ) + m_timerId = startTimer( refresh ); + else + m_timerId = -1; + + QTimer::singleShot( 0, this, SLOT( performSnmpRequest() ) ); +} + +Monitor::~Monitor() +{ + if ( QThread::running() ) + QThread::wait(); +} + +void Monitor::run() +{ + AsyncSnmpQueryResult *result = new AsyncSnmpQueryResult; + + result->oid = m_oid; + result->success = performSyncSnmpRequest( result->data, &result->error ); + + QCustomEvent *ev = new QCustomEvent( QEvent::User, result ); + QApplication::postEvent( this, ev ); +} + +void Monitor::customEvent( QCustomEvent *ev ) +{ + if ( ev->type() != QEvent::User ) + return; + + AsyncSnmpQueryResult *result = reinterpret_cast<AsyncSnmpQueryResult *>( ev->data() ); + if ( result->success ) { + emit newData( result->data ); + emit newData( result->oid, result->data ); + } else { + emit error( result->error ); + emit error( result->oid, result->error ); + } + + delete result; +} + +void Monitor::timerEvent( QTimerEvent *ev ) +{ + if ( ev->timerId() != m_timerId ) + return; + + performSnmpRequest(); +} + +void Monitor::performSnmpRequest() +{ + if ( QThread::running() ) + return; + + start(); +} + +bool Monitor::performSyncSnmpRequest( Value &data, ErrorInfo *errorInfo ) +{ + return m_session.snmpGet( m_oid, data, errorInfo ); +} + +#include "monitor.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitor.h b/ksim/monitors/snmp/monitor.h new file mode 100644 index 0000000..cd3dedc --- /dev/null +++ b/ksim/monitors/snmp/monitor.h @@ -0,0 +1,77 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MONITOR_H +#define MONITOR_H + +#include "monitorconfig.h" +#include "session.h" + +#include <qthread.h> + +namespace KSim +{ + +namespace Snmp +{ + +class Monitor : public QObject, public QThread +{ + Q_OBJECT +public: + Monitor( const HostConfig &host, const Identifier &oid, int refresh, QObject *parent = 0, const char *name = 0 ); + virtual ~Monitor(); + +signals: + void newData( const Value &data ); + void newData( const Identifier &oid, const Value &data ); + void error( const ErrorInfo &errorInfo ); + void error( const Identifier &oid, const ErrorInfo &errorInfo ); + +protected: + virtual void run(); + virtual void customEvent( QCustomEvent *ev ); + virtual void timerEvent( QTimerEvent *ev ); + +private slots: + void performSnmpRequest(); + bool performSyncSnmpRequest( Value &data, ErrorInfo *errorInfo = 0 ); + +private: + struct AsyncSnmpQueryResult + { + AsyncSnmpQueryResult() : success( false ) {} + Identifier oid; + Value data; + ErrorInfo error; + bool success; + }; + + const Identifier m_oid; + int m_timerId; + Session m_session; +}; + +} + +} + +#endif // MONITOR_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitorconfig.cpp b/ksim/monitors/snmp/monitorconfig.cpp new file mode 100644 index 0000000..6b3b27e --- /dev/null +++ b/ksim/monitors/snmp/monitorconfig.cpp @@ -0,0 +1,183 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "monitorconfig.h" +#include "labelmonitor.h" +#include "chartmonitor.h" + +#include <assert.h> + +using namespace KSim::Snmp; + +MonitorConfig::MonitorConfig() +{ + display = Label; + refreshInterval.minutes = refreshInterval.seconds = 0; + useCustomFormatString = false; + displayCurrentValueInline = false; +} + +bool MonitorConfig::load( KConfigBase &config, const HostConfigMap &hosts ) +{ + QString hostName = config.readEntry( "Host" ); + if ( hostName.isEmpty() ) + return false; + + HostConfigMap::ConstIterator hostIt = hosts.find( hostName ); + if ( hostIt == hosts.end() ) + return false; + + host = *hostIt; + + name = config.readEntry( "MonitorName" ); + if ( name.isEmpty() ) + return false; + + oid = config.readEntry( "ObjectIdentifier" ); + if ( Identifier::fromString( oid ).isNull() ) + return false; + + bool ok = false; + display = stringToMonitorDisplayType( config.readEntry( "DisplayType" ), &ok ); + if ( !ok ) + return false; + + refreshInterval.minutes = config.readUnsignedNumEntry( "RefreshIntervalMinutes" ); + refreshInterval.seconds = config.readUnsignedNumEntry( "RefreshIntervalSeconds" ); + + if ( refreshInterval.minutes == 0 && refreshInterval.seconds == 0 ) + return false; + + if ( display == Label ) { + useCustomFormatString = config.readBoolEntry( "UseCustomFormatString", useCustomFormatString ); + if ( useCustomFormatString ) + customFormatString = config.readEntry( "CustomFormatString" ); + } else + displayCurrentValueInline = config.readBoolEntry( "DisplayCurrentValueInline", displayCurrentValueInline ); + + return true; +} + +void MonitorConfig::save( KConfigBase &config ) const +{ + if ( isNull() ) + return; + + config.writeEntry( "Host", host.name ); + config.writeEntry( "MonitorName", name ); + config.writeEntry( "ObjectIdentifier", oid ); + config.writeEntry( "DisplayType", monitorDisplayTypeToString( display ) ); + config.writeEntry( "RefreshIntervalMinutes", refreshInterval.minutes ); + config.writeEntry( "RefreshIntervalSeconds", refreshInterval.seconds ); + if ( display == Label ) { + config.writeEntry( "UseCustomFormatString", useCustomFormatString ); + if ( useCustomFormatString ) + config.writeEntry( "CustomFormatString", customFormatString ); + } else + config.writeEntry( "DisplayCurrentValueInline", displayCurrentValueInline ); +} + +QWidget *MonitorConfig::createMonitorWidget( QWidget *parent, const char *name ) +{ + QWidget *w; + + int refresh = refreshInterval.seconds * 1000 + refreshInterval.minutes * 60 * 1000; + Identifier id = Identifier::fromString( oid ); + if ( id.isNull() ) + return 0; + + if ( display == Label ) + w = new LabelMonitor( *this, parent, name ); + else + w = new ChartMonitor( *this, parent, name ); + + Monitor *monitor = new Monitor( host, id, refresh, w ); + QObject::connect( monitor, SIGNAL( newData( const Value & ) ), + w, SLOT( setData( const Value & ) ) ); + return w; +} + +QString KSim::Snmp::monitorDisplayTypeToString( MonitorConfig::DisplayType type ) +{ + switch ( type ) + { + case MonitorConfig::Label: return QString::fromLatin1( "Label" ); + case MonitorConfig::Chart: return QString::fromLatin1( "Chart" ); + default: assert( false ); + }; + return QString::null; +} + +MonitorConfig::DisplayType KSim::Snmp::stringToMonitorDisplayType( QString string, bool *ok ) +{ + string = string.lower(); + if ( string == "chart" ) { + if ( ok ) + *ok = true; + return MonitorConfig::Chart; + } + if ( string == "label" ) { + if ( ok ) + *ok = true; + return MonitorConfig::Label; + } + if ( ok ) + *ok = false; + return MonitorConfig::Chart; +} + +QStringList KSim::Snmp::allDisplayTypes() +{ + // !!! keep order with enum + return QStringList() << "Label" << "Chart"; +} + +void MonitorConfigMap::load( KConfigBase &config, const QStringList &names, const HostConfigMap &hosts ) +{ + clear(); + + for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) { + config.setGroup( "Monitor " + *it ); + + MonitorConfig monitor; + if ( !monitor.load( config, hosts ) ) + continue; + + insert( *it, monitor ); + } +} + +QStringList MonitorConfigMap::save( KConfigBase &config ) const +{ + QStringList names; + + for ( ConstIterator it = begin(); it != end(); ++it ) { + QString name = it.key(); + + names << name; + + config.setGroup( "Monitor " + name ); + ( *it ).save( config ); + } + + return names; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitorconfig.h b/ksim/monitors/snmp/monitorconfig.h new file mode 100644 index 0000000..bbc8674 --- /dev/null +++ b/ksim/monitors/snmp/monitorconfig.h @@ -0,0 +1,84 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MONITORCONFIG_H +#define MONITORCONFIG_H + +#include "hostconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +struct MonitorConfig +{ + enum DisplayType { Label = 0, Chart }; + + MonitorConfig(); + MonitorConfig( KConfigBase &config, const HostConfigMap &hosts ) + { load( config, hosts ); } + + bool load( KConfigBase &config, const HostConfigMap &hosts ); + void save( KConfigBase &config ) const; + + bool isNull() const { return name.isEmpty() || host.isNull(); } + + QWidget *createMonitorWidget( QWidget *parent, const char *name = 0 ); + + HostConfig host; + QString name; + QString oid; + struct + { + uint minutes; + uint seconds; + } refreshInterval; + DisplayType display; + + bool useCustomFormatString; + QString customFormatString; + + bool displayCurrentValueInline; +}; + +struct MonitorConfigMap : public QMap< QString, MonitorConfig > +{ + MonitorConfigMap() {} + MonitorConfigMap( const QMap< QString, MonitorConfig > &rhs ) + : QMap< QString, MonitorConfig >( rhs ) {} + + void load( KConfigBase &config, const QStringList &names, const HostConfigMap &hosts ); + QStringList save( KConfigBase &config ) const; +}; + +typedef QValueList<MonitorConfig> MonitorConfigList; + +QString monitorDisplayTypeToString( MonitorConfig::DisplayType type ); +MonitorConfig::DisplayType stringToMonitorDisplayType( QString string, bool *ok = 0 ); +QStringList allDisplayTypes(); + +} + +} + +#endif // MONITORCONFIG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitordialog.cpp b/ksim/monitors/snmp/monitordialog.cpp new file mode 100644 index 0000000..615a1aa --- /dev/null +++ b/ksim/monitors/snmp/monitordialog.cpp @@ -0,0 +1,178 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "monitordialog.h" +#include "identifier.h" +#include "browsedialog.h" + +#include <qcombobox.h> +#include <qlineedit.h> +#include <qspinbox.h> +#include <qpushbutton.h> +#include <qradiobutton.h> +#include <qbuttongroup.h> +#include <qcheckbox.h> +#include <qlabel.h> + +#include <klocale.h> +#include <kpushbutton.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +MonitorDialog::MonitorDialog( const HostConfigMap &hosts, QWidget *parent, const char *name ) + : MonitorDialogBase( parent, name ), m_hosts( hosts ) +{ + init(); +} + +MonitorDialog::MonitorDialog( const MonitorConfig &monitor, const HostConfigMap &hosts, QWidget *parent, const char *name ) + : MonitorDialogBase( parent, name ), m_hosts( hosts ) +{ + init( monitor ); +} + +MonitorConfig MonitorDialog::monitorConfig() const +{ + MonitorConfig result; + + result.host = currentHost(); + if ( result.host.isNull() ) + return MonitorConfig(); + + result.name = monitorName->text(); + if ( result.name.isEmpty() ) + return MonitorConfig(); + + result.oid = oid->text(); + if ( Identifier::fromString( result.oid ).isNull() ) + return MonitorConfig(); + + result.refreshInterval.minutes = updateIntervalMinutes->value(); + result.refreshInterval.seconds = updateIntervalSeconds->value(); + + result.display = stringToMonitorDisplayType( displayType->currentText() ); + + if ( result.display == MonitorConfig::Label ) { + result.useCustomFormatString = customFormatStringCheckBox->isChecked(); + if ( result.useCustomFormatString ) + result.customFormatString = customFormatString->text(); + } else + result.displayCurrentValueInline = displayCurrentValueInline->isChecked(); + + return result; +} + +void MonitorDialog::checkValues() +{ + bool currentDisplayTypeIsLabel = stringToMonitorDisplayType( displayType->currentText() ) == MonitorConfig::Label; + labelOptions->setEnabled( currentDisplayTypeIsLabel ); + chartOptions->setEnabled( !currentDisplayTypeIsLabel ); + + QString statusText; + + if ( monitorName->text().isEmpty() ) + statusText = i18n( "Please enter a name for this monitor" ); + + if ( statusText.isEmpty() && Identifier::fromString( oid->text() ).isNull() ) + statusText = i18n( "Please enter a valid name for the object identifier" ); + + if ( statusText.isEmpty() ) + statusText = " "; // a space to keep the height + + status->setText( statusText ); + + buttonOk->setEnabled( !monitorConfig().isNull() ); +} + +void MonitorDialog::testObject() +{ + // ### FIXME +} + +void MonitorDialog::browse() +{ + HostConfig host = currentHost(); + if ( host.isNull() ) + return; + + BrowseDialog dlg( host, oid->text(), this ); + if ( dlg.exec() ) + oid->setText( dlg.selectedObjectIdentifier() ); +} + +void MonitorDialog::init( const MonitorConfig &monitor ) +{ + customFormatString->setText( "%s" ); + + status->setText( " " ); + + host->clear(); + + QStringList allHosts; + for ( HostConfigMap::ConstIterator it = m_hosts.begin(); it != m_hosts.end(); ++it ) + allHosts << it.key(); + + host->insertStringList( allHosts ); + + displayType->clear(); + displayType->insertStringList( allDisplayTypes() ); + + if ( monitor.isNull() ) { + checkValues(); + return; + } + + monitorName->setText( monitor.name ); + + assert( allHosts.findIndex( monitor.host.name ) != -1 ); + + host->setCurrentItem( allHosts.findIndex( monitor.host.name ) ); + + oid->setText( monitor.oid ); + + updateIntervalMinutes->setValue( monitor.refreshInterval.minutes ); + updateIntervalSeconds->setValue( monitor.refreshInterval.seconds ); + + displayType->setCurrentItem( allDisplayTypes().findIndex( monitorDisplayTypeToString( monitor.display ) ) ); + + customFormatStringCheckBox->setChecked( monitor.useCustomFormatString ); + customFormatString->setEnabled( monitor.useCustomFormatString ); + + if ( monitor.useCustomFormatString ) + customFormatString->setText( monitor.customFormatString ); + + displayCurrentValueInline->setChecked( monitor.displayCurrentValueInline ); + + checkValues(); +} + +HostConfig MonitorDialog::currentHost() const +{ + HostConfigMap::ConstIterator hostIt = m_hosts.find( host->currentText() ); + if ( hostIt == m_hosts.end() ) + return HostConfig(); + + return *hostIt; +} + +#include "monitordialog.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitordialog.h b/ksim/monitors/snmp/monitordialog.h new file mode 100644 index 0000000..0f22d33 --- /dev/null +++ b/ksim/monitors/snmp/monitordialog.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MONITORDIALOG_H +#define MONITORDIALOG_H + +#include "monitordialogbase.h" +#include "monitorconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +class MonitorDialog : public MonitorDialogBase +{ + Q_OBJECT +public: + MonitorDialog( const HostConfigMap &hosts, QWidget *parent, const char *name = 0 ); + MonitorDialog( const MonitorConfig &monitor, const HostConfigMap &hosts, QWidget *parent, const char *name = 0 ); + + MonitorConfig monitorConfig() const; + +protected: + virtual void checkValues(); + virtual void testObject(); + virtual void browse(); + +private: + void init( const MonitorConfig &monitor = MonitorConfig() ); + + HostConfig currentHost() const; + + HostConfigMap m_hosts; +}; + +} + +} + +#endif // MONITORDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitordialogbase.ui b/ksim/monitors/snmp/monitordialogbase.ui new file mode 100644 index 0000000..13d6b06 --- /dev/null +++ b/ksim/monitors/snmp/monitordialogbase.ui @@ -0,0 +1,440 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::MonitorDialogBase</class> +<widget class="KDialog"> + <property name="name"> + <cstring>MonitorDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>725</width> + <height>597</height> + </rect> + </property> + <property name="caption"> + <string>Configure Monitor</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>Display type:</string> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Update interval:</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Object identifier:</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Name:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="text"> + <string>Host:</string> + </property> + </widget> + <widget class="QGroupBox" row="5" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>labelOptions</cstring> + </property> + <property name="title"> + <string>Options for Label</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>customFormatStringCheckBox</cstring> + </property> + <property name="text"> + <string>Use custom format string:</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>customFormatString</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>The text in the edit box is what is displayed except that any occurrence of <b>%s</b> will be replaced with the snmp object value and any occurrence of <b>%n</b> will be replaced with the name of this monitor (see Name input field) .</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget" row="3" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSpinBox"> + <property name="name"> + <cstring>updateIntervalMinutes</cstring> + </property> + <property name="maxValue"> + <number>60</number> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>minutes</string> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>updateIntervalSeconds</cstring> + </property> + <property name="maxValue"> + <number>59</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>seconds</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>141</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Chart</string> + </property> + </item> + <item> + <property name="text"> + <string>Text Label</string> + </property> + </item> + <property name="name"> + <cstring>displayType</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>271</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <spacer row="0" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>244</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>monitorName</cstring> + </property> + </widget> + <spacer row="1" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>210</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>host</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="9" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="Line" row="8" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLabel" row="7" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>status</cstring> + </property> + <property name="text"> + <string>blehStatus</string> + </property> + </widget> + <widget class="QGroupBox" row="6" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>chartOptions</cstring> + </property> + <property name="title"> + <string>Options for Chart</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>displayCurrentValueInline</cstring> + </property> + <property name="text"> + <string>Treat data as byte transfer rate and display the current value inline</string> + </property> + </widget> + </hbox> + </widget> + <widget class="KPushButton" row="2" column="3"> + <property name="name"> + <cstring>browseButton</cstring> + </property> + <property name="text"> + <string>Browse...</string> + </property> + </widget> + <widget class="QLineEdit" row="2" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>oid</cstring> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>MonitorDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>MonitorDialogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>monitorName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>MonitorDialogBase</receiver> + <slot>checkValues()</slot> + </connection> + <connection> + <sender>oid</sender> + <signal>textChanged(const QString&)</signal> + <receiver>MonitorDialogBase</receiver> + <slot>checkValues()</slot> + </connection> + <connection> + <sender>displayType</sender> + <signal>activated(const QString&)</signal> + <receiver>MonitorDialogBase</receiver> + <slot>checkValues()</slot> + </connection> + <connection> + <sender>customFormatStringCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>customFormatString</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>browseButton</sender> + <signal>clicked()</signal> + <receiver>MonitorDialogBase</receiver> + <slot>browse()</slot> + </connection> +</connections> +<tabstops> + <tabstop>monitorName</tabstop> + <tabstop>host</tabstop> + <tabstop>oid</tabstop> + <tabstop>updateIntervalMinutes</tabstop> + <tabstop>updateIntervalSeconds</tabstop> + <tabstop>displayType</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<slots> + <slot access="protected">checkValues()</slot> + <slot access="protected">browse()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdialog.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/pdu.cpp b/ksim/monitors/snmp/pdu.cpp new file mode 100644 index 0000000..1619086 --- /dev/null +++ b/ksim/monitors/snmp/pdu.cpp @@ -0,0 +1,98 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "pdu.h" +#include "snmp_p.h" +#include "value_p.h" + +#include <algorithm> +#include <functional> + +#include <assert.h> + +using namespace KSim::Snmp; + +PDU::PDU() + : d( 0 ) +{ +} + +PDU::PDU( int requestType ) +{ + d = SnmpLib::self()->snmp_pdu_create( requestType ); +} + +PDU::~PDU() +{ + if ( d ) + SnmpLib::self()->snmp_free_pdu( d ); +} + +void PDU::addNullVariables( const IdentifierList &oids ) +{ + std::for_each( oids.begin(), oids.end(), + std::bind1st( std::mem_fun( &PDU::addNullVariable ), this ) ); +} + +void PDU::addNullVariable( Identifier oid ) +{ + assert( d ); + SnmpLib::self()->snmp_add_null_var( d, oid.d->data, oid.d->length ); +} + +netsnmp_pdu *PDU::release() +{ + netsnmp_pdu *res = d; + d = 0; + return res; +} + +bool PDU::hasError() const +{ + if ( !d ) + return false; + + return d->errstat != SNMP_ERR_NOERROR; +} + +int PDU::errorCode() const +{ + return d->errstat; +} + +ValueMap PDU::variables() const +{ + if ( !d ) + return ValueMap(); + + ValueMap result; + + for ( variable_list *var = d->variables; var; var = var->next_variable ) { + Identifier oid( new Identifier::Data( var->name, var->name_length ) ); + Value value( new ValueImpl( var ) ); + + result.insert( oid, value ); + } + + return result; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/pdu.h b/ksim/monitors/snmp/pdu.h new file mode 100644 index 0000000..2e648d4 --- /dev/null +++ b/ksim/monitors/snmp/pdu.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PDU_H +#define PDU_H + +#include "identifier.h" +#include "snmplib.h" + +namespace KSim +{ + +namespace Snmp +{ + +class PDU +{ +public: + PDU(); + PDU( int requestType ); + ~PDU(); + + void addNullVariables( const IdentifierList &oids ); + void addNullVariable( Identifier oid ); + + netsnmp_pdu **operator&() { return &d; } + + netsnmp_pdu *release(); + + bool hasError() const; + int errorCode() const; + + ValueMap variables() const; + +private: + netsnmp_pdu *d; +}; + +} +} + +#endif // PDU_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/plugin.cpp b/ksim/monitors/snmp/plugin.cpp new file mode 100644 index 0000000..90683a2 --- /dev/null +++ b/ksim/monitors/snmp/plugin.cpp @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "plugin.h" +#include "view.h" +#include "configpage.h" + +using namespace KSim::Snmp; + +KSIM_INIT_PLUGIN( Plugin ); + +Plugin::Plugin( const char *name ) + : KSim::PluginObject( name ) +{ +} + +Plugin::~Plugin() +{ +} + +KSim::PluginView *Plugin::createView( const char *name ) +{ + return new View( this, name ); +} + +KSim::PluginPage *Plugin::createConfigPage( const char *name ) +{ + return new ConfigPage( this, name ); +} + +void Plugin::showAbout() +{ +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/plugin.h b/ksim/monitors/snmp/plugin.h new file mode 100644 index 0000000..3e0fb66 --- /dev/null +++ b/ksim/monitors/snmp/plugin.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSIM_PLUGIN_H +#define KSIM_PLUGIN_H + +#include <pluginmodule.h> + +namespace KSim +{ + +namespace Snmp +{ + +class Plugin : public KSim::PluginObject +{ +public: + Plugin( const char *name ); + ~Plugin(); + + virtual KSim::PluginView *createView( const char *name ); + virtual KSim::PluginPage *createConfigPage( const char *name ); + + virtual void showAbout(); +}; + +} + +} + +#endif // KSIM_PLUGIN_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/probedialog.cpp b/ksim/monitors/snmp/probedialog.cpp new file mode 100644 index 0000000..d45db6b --- /dev/null +++ b/ksim/monitors/snmp/probedialog.cpp @@ -0,0 +1,117 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "probedialog.h" +#include "monitor.h" + +#include <qtimer.h> + +#include <klocale.h> +#include <kdebug.h> + +using namespace KSim::Snmp; + +static const char * const probeIdentifiers[] = +{ + "system.sysDescr.0", + "system.sysName.0", + "system.sysUpTime.0", + "system.sysContact.0", + "system.sysObjectID.0", + ".1.3.6.1.2.1.25.1.1.0", + 0 +}; + +ProbeDialog::ProbeDialog( const HostConfig &hostConfig, QWidget *parent, const char *name ) + : KProgressDialog( parent, name, i18n( "SNMP Host Probe" ), QString::null, true /* modal */ ), + m_host( hostConfig ), m_currentMonitor( 0 ), m_canceled( false ) +{ + setLabel( i18n( "Probing for common object identifiers..." ) ); + + for ( uint i = 0; probeIdentifiers[ i ]; ++i ) { + Identifier id = Identifier::fromString( probeIdentifiers[ i ] ); + if ( !id.isNull() ) + m_probeOIDs << id; + } + + progressBar()->setTotalSteps( m_probeOIDs.count() ); + + setAutoClose( false ); + + nextProbe(); +} + +void ProbeDialog::done( int code ) +{ + if ( code == QDialog::Rejected && m_currentMonitor ) { + setLabel( "Probe aborted. Waiting for job to finish..." ); + m_canceled = true; + return; + } + KProgressDialog::done( code ); +} + +void ProbeDialog::probeOne() +{ + if ( m_probeOIDs.isEmpty() ) { + accept(); + return; + } + + Identifier oid = m_probeOIDs.pop(); + + delete m_currentMonitor; + m_currentMonitor = new Monitor( m_host, oid, 0 /* no refresh */, this ); + + connect( m_currentMonitor, SIGNAL( newData( const Identifier &, const Value & ) ), + this, SLOT( probeResult( const Identifier &, const Value & ) ) ); + connect( m_currentMonitor, SIGNAL( error( const Identifier &, const ErrorInfo & ) ), + this, SLOT( probeError( const Identifier &, const ErrorInfo & ) ) ); +} + +void ProbeDialog::probeResult( const Identifier &oid, const Value &value ) +{ + if ( !m_canceled ) + m_results << ProbeResult( oid, value ); + + nextProbe(); +} + +void ProbeDialog::probeError( const Identifier &oid, const ErrorInfo &errorInfo ) +{ + if ( !m_canceled ) + m_results << ProbeResult( oid, errorInfo ); + + nextProbe(); +} + +void ProbeDialog::nextProbe() +{ + progressBar()->setProgress( progressBar()->totalSteps() - m_probeOIDs.count() ); + + if ( m_canceled ) + KProgressDialog::done( QDialog::Rejected ); + else + QTimer::singleShot( 0, this, SLOT( probeOne() ) ); +} + +#include "probedialog.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/probedialog.h b/ksim/monitors/snmp/probedialog.h new file mode 100644 index 0000000..47a5fb0 --- /dev/null +++ b/ksim/monitors/snmp/probedialog.h @@ -0,0 +1,87 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PROBEDIALOG_H +#define PROBEDIALOG_H + +#include <qvaluestack.h> + +#include <kprogress.h> + +#include "hostconfig.h" +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Monitor; + +class ProbeDialog : public KProgressDialog +{ + Q_OBJECT +public: + ProbeDialog( const HostConfig &hostConfig, QWidget *parent, const char *name = 0 ); + + struct ProbeResult + { + ProbeResult() : success( false ) {} + ProbeResult( const Identifier &_oid, const Value &_value ) + : oid( _oid ), value( _value ), success( true ) + {} + ProbeResult( const Identifier &_oid, const ErrorInfo &_errorInfo ) + : oid( _oid ), success( false ), errorInfo( _errorInfo ) + {} + + Identifier oid; + Value value; + bool success; + ErrorInfo errorInfo; + }; + typedef QValueList<ProbeResult> ProbeResultList; + + ProbeResultList probeResults() const { return m_results; } + +protected: + virtual void done( int code ); + +private slots: + void probeOne(); + void probeResult( const Identifier &oid, const Value &value ); + void probeError( const Identifier &oid, const ErrorInfo &errorInfo ); + +private: + void nextProbe(); + + HostConfig m_host; + QValueStack<Identifier> m_probeOIDs; + Monitor *m_currentMonitor; + + ProbeResultList m_results; + bool m_canceled; +}; + +} +} + +#endif // PROBEDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/proberesultdialog.cpp b/ksim/monitors/snmp/proberesultdialog.cpp new file mode 100644 index 0000000..641f12e --- /dev/null +++ b/ksim/monitors/snmp/proberesultdialog.cpp @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "proberesultdialog.h" + +#include <qlabel.h> + +#include <klocale.h> +#include <klistview.h> + +using namespace KSim::Snmp; + +ProbeResultDialog::ProbeResultDialog( const HostConfig &hostConfig, const ProbeDialog::ProbeResultList &probeResults, + QWidget *parent, const char *name ) + : ProbeResultDialogBase( parent, name ) +{ + info->setText( i18n( "Results of scanning host %1:" ).arg( hostConfig.name ) ); + + for ( ProbeDialog::ProbeResultList::ConstIterator it = probeResults.begin(); + it != probeResults.end(); ++it ) + addResultItem( *it ); +} + +void ProbeResultDialog::addResultItem( const ProbeDialog::ProbeResult &result ) +{ + QListViewItem *item = new QListViewItem( probeResultView ); + + item->setText( 0, result.oid.toString() ); + + if ( result.success ) + item->setText( 1, result.value.toString( Value::TimeTicksWithSeconds ) ); + else + item->setText( 1, QString( "ERROR: " ) + result.errorInfo.errorMessage() ); +} + +#include "proberesultdialog.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/proberesultdialog.h b/ksim/monitors/snmp/proberesultdialog.h new file mode 100644 index 0000000..9ba3523 --- /dev/null +++ b/ksim/monitors/snmp/proberesultdialog.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PROBERESULTDIALOG_H +#define PROBERESULTDIALOG_H + +#include "proberesultdialogbase.h" + +#include "probedialog.h" + +namespace KSim +{ + +namespace Snmp +{ + +class ProbeResultDialog : public ProbeResultDialogBase +{ + Q_OBJECT +public: + ProbeResultDialog( const HostConfig &hostConfig, const ProbeDialog::ProbeResultList &probeResults, + QWidget *parent, const char *name = 0 ); + +private: + void addResultItem( const ProbeDialog::ProbeResult &result ); +}; + +} + +} +#endif // PROBERESULTDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/proberesultdialogbase.ui b/ksim/monitors/snmp/proberesultdialogbase.ui new file mode 100644 index 0000000..01b0c70 --- /dev/null +++ b/ksim/monitors/snmp/proberesultdialogbase.ui @@ -0,0 +1,124 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>KSim::Snmp::ProbeResultDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>ProbeResultDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>501</width> + <height>321</height> + </rect> + </property> + <property name="caption"> + <string>Probe Results</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>info</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="KListView"> + <column> + <property name="text"> + <string>Object</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>probeResultView</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ProbeResultDialogBase</receiver> + <slot>accept()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/session.cpp b/ksim/monitors/snmp/session.cpp new file mode 100644 index 0000000..d7de283 --- /dev/null +++ b/ksim/monitors/snmp/session.cpp @@ -0,0 +1,283 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "session.h" +#include "snmp.h" +#include "snmp_p.h" +#include "snmplib.h" +#include "pdu.h" + +#include <assert.h> + +using namespace KSim::Snmp; + +// ### clean me up +struct Session::Data +{ + Data() : session( 0 ) {} + + netsnmp_session defaultSession; + netsnmp_session *session; + + bool initialized; + + HostConfig source; + + QCString host; + QCString community; + QCString securityName; + QCString authPassPhrase; + QCString privPassPhrase; +}; + +Session::Session( const HostConfig &source ) +{ + d = new Data; + d->initialized = false; + + d->source = source; + + // unicode madness + d->host = source.name.ascii(); + d->community = source.community.ascii(); + d->securityName = source.securityName.ascii(); + d->authPassPhrase = source.authentication.key.ascii(); + d->privPassPhrase = source.privacy.key.ascii(); + + SnmpLib::self()->snmp_sess_init( &d->defaultSession ); +} + +bool Session::snmpGetInternal( int getType, const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error ) +{ + if ( !d->initialized && !initialize( error ) ) + return false; + + bool result = false; + + if ( getType != SNMP_MSG_GETNEXT && d->session ) { + SnmpLib::self()->snmp_close( d->session ); + d->session = 0; + } + + if ( getType != SNMP_MSG_GETNEXT || + !d->session ) { + + if ( ( d->session = SnmpLib::self()->snmp_open( &d->defaultSession ) ) == 0 ) { + if ( error ) + *error = ErrorInfo( sessionErrorCode( d->defaultSession ) ); + return false; + } + } + + PDU request( getType ); + PDU response; + + request.addNullVariables( identifiers ); + + int status = SnmpLib::self()->snmp_synch_response( d->session, request.release(), &response ); + + if ( status == STAT_SUCCESS ) { + + if ( response.hasError() ) { + + if ( error ) + *error = ErrorInfo( response.errorCode() ); + + } else { + + variables = response.variables(); + result = true; + + if ( error ) + *error = ErrorInfo( ErrorInfo::NoError ); + } + + } else if ( status == STAT_TIMEOUT ) { + + if ( error ) + *error = ErrorInfo( ErrorInfo::ErrTimeout ); + + } else { + + if ( error ) + *error = ErrorInfo( sessionErrorCode( *d->session ) ); + + } + + if ( getType != SNMP_MSG_GETNEXT ) { + SnmpLib::self()->snmp_close( d->session ); + d->session = 0; + } + + return result; + +} + +bool Session::initialize( ErrorInfo *error ) +{ + if ( d->initialized ) { + if ( error ) + *error = ErrorInfo( ErrorInfo::NoError ); + return true; + } + + HostConfig &source = d->source; + + d->defaultSession.peername = d->host.data(); + + d->defaultSession.version = snmpVersionToSnmpLibConstant( source.version ); + + if ( source.version != SnmpVersion3 ) { + d->defaultSession.community = reinterpret_cast<u_char *>( d->community.data() ); + d->defaultSession.community_len = d->community.length(); + d->initialized = true; + return true; + } + + d->defaultSession.securityName = d->securityName.data(); + d->defaultSession.securityNameLen = d->securityName.length(); + + d->defaultSession.securityLevel = snmpSecurityLevelToSnmpLibConstant( source.securityLevel ); + + // ### clean me up + switch ( source.authentication.protocol ) { + case MD5Auth: { + d->defaultSession.securityAuthProto = usmHMACMD5AuthProtocol; + d->defaultSession.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN; + break; + } + case SHA1Auth: { + d->defaultSession.securityAuthProto = usmHMACSHA1AuthProtocol; + d->defaultSession.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN; + break; + } + default: assert( false ); + } + + d->defaultSession.securityAuthKeyLen = USM_AUTH_KU_LEN; + + int result; + if ( ( result = SnmpLib::self()->generate_Ku( d->defaultSession.securityAuthProto, d->defaultSession.securityAuthProtoLen, + reinterpret_cast<uchar *>( d->authPassPhrase.data() ), d->authPassPhrase.length(), + d->defaultSession.securityAuthKey, &d->defaultSession.securityAuthKeyLen ) ) + != SNMPERR_SUCCESS ) { + + if ( error ) + *error = ErrorInfo( result ); + + return false; + } + + switch ( source.privacy.protocol ) { + case DESPrivacy: { + d->defaultSession.securityPrivProto = usmDESPrivProtocol; + d->defaultSession.securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN; + break; + } + default: assert( false ); + } + + d->defaultSession.securityPrivKeyLen = USM_PRIV_KU_LEN; + + if ( ( result = SnmpLib::self()->generate_Ku( d->defaultSession.securityAuthProto, d->defaultSession.securityAuthProtoLen, + reinterpret_cast<u_char *>( d->privPassPhrase.data() ), d->privPassPhrase.length(), + d->defaultSession.securityPrivKey, &d->defaultSession.securityPrivKeyLen ) ) + != SNMPERR_SUCCESS ) { + + if ( error ) + *error = ErrorInfo( result ); + + + return false; + } + + d->initialized = true; + return true; +} + +bool Session::snmpGet( const QString &identifier, Value &value, ErrorInfo *error ) +{ + bool ok = false; + Identifier oid = Identifier::fromString( identifier, &ok ); + if ( !ok ) { + if ( error ) + *error = ErrorInfo( ErrorInfo::ErrUnknownOID ); + return false; + } + + return snmpGet( oid, value, error ); +} + +bool Session::snmpGet( const Identifier &identifier, Value &value, ErrorInfo *error ) +{ + ValueMap vars; + IdentifierList ids; + + ids << identifier; + + if ( !snmpGet( ids, vars, error ) ) + return false; + + ValueMap::ConstIterator it = vars.find( identifier ); + if ( it == vars.end() ) { + if ( error ) + *error = ErrorInfo( ErrorInfo::ErrMissingVariables ); + return false; + } + + value = it.data(); + + return true; +} + +bool Session::snmpGet( const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error ) +{ + return snmpGetInternal( SNMP_MSG_GET, identifiers, variables, error ); +} + +bool Session::snmpGetNext( Identifier &identifier, Value &value, ErrorInfo *error ) +{ + ValueMap vars; + IdentifierList ids; + + ids << identifier; + + if ( !snmpGetInternal( SNMP_MSG_GETNEXT, ids, vars, error ) ) + return false; + + assert( vars.count() == 1 ); + + ValueMap::ConstIterator it = vars.begin(); + identifier = it.key(); + value = it.data(); + + return true; + +} + +Session::~Session() +{ + if ( d->session ) + SnmpLib::self()->snmp_close( d->session ); + delete d; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/session.h b/ksim/monitors/snmp/session.h new file mode 100644 index 0000000..0d5cda3 --- /dev/null +++ b/ksim/monitors/snmp/session.h @@ -0,0 +1,64 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SESSION_H +#define SESSION_H + +#include "hostconfig.h" +#include "value.h" +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Session +{ +public: + struct Data; + + Session( const HostConfig &snmpHostConfig ); + ~Session(); + + bool snmpGet( const QString &identifier, Value &value, ErrorInfo *error = 0 ); + bool snmpGet( const Identifier &identifier, Value &value, ErrorInfo *error = 0 ); + bool snmpGet( const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error = 0 ); + + bool snmpGetNext( Identifier &identifier, Value &value, ErrorInfo *error = 0 ); + +private: + Data *d; + + bool snmpGetInternal( int getType, const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error = 0 ); + + bool initialize( ErrorInfo *error ); + + Session( const Session & ); + Session &operator=( const Session & ); +}; + +} + +} + +#endif // SESSION_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmp.cpp b/ksim/monitors/snmp/snmp.cpp new file mode 100644 index 0000000..80fb073 --- /dev/null +++ b/ksim/monitors/snmp/snmp.cpp @@ -0,0 +1,320 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "snmp.h" +#include "snmp_p.h" +#include "snmplib.h" +#include "value_p.h" + +#include <qmutex.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +static const struct EnumStringMapInfo +{ + const int enumValue; + const char *stringValue; + const char snmpLibConstant; +} snmpVersionStrings[ 4 ] = { + { SnmpVersion1, "1", SNMP_VERSION_1 }, + { SnmpVersion2c, "2c", SNMP_VERSION_2c }, + { SnmpVersion3, "3", SNMP_VERSION_3 }, + { 0, 0, 0 } +}, securityLevelStrings[ 4 ] = { + { NoAuthPriv, "NoAuthPriv", SNMP_SEC_LEVEL_NOAUTH }, + { AuthNoPriv, "AuthNoPriv", SNMP_SEC_LEVEL_AUTHNOPRIV }, + { AuthPriv, "AuthPriv", SNMP_SEC_LEVEL_AUTHPRIV }, + { 0, 0, 0 } +}, authenticationProtocolStrings[ 3 ] = { + { MD5Auth, "MD5", 0 }, + { SHA1Auth, "SHA1", 0 }, + { 0, 0, 0 } +}, privacyProtocolStrings[ 2 ] = { + { DESPrivacy, "DES", 0 }, + { 0, 0, 0 } +}; + +static QStringList allStrings( const EnumStringMapInfo *array ) +{ + QStringList result; + for ( uint i = 0; array[ i ].stringValue; ++i ) + result << QString::fromLatin1( array[ i ].stringValue ); + return result; +} + +static QString enumToString( const EnumStringMapInfo *array, int value ) +{ + for ( uint i = 0; array[ i ].stringValue; ++i ) + if ( array[ i ].enumValue == value ) + return QString::fromLatin1( array[ i ].stringValue ); + + assert( false ); + return QString::null; +} + +static int stringToEnum( const EnumStringMapInfo *array, QString string, bool *ok ) +{ + string = string.lower(); + uint i; + for ( i = 0; array[ i ].stringValue; ++i ) + if ( QString::fromLatin1( array[ i ].stringValue ).lower() == string ) { + if ( ok ) *ok = true; + return array[ i ].enumValue; + } + + if ( ok ) + *ok = false; + + // something.. + return array[ 0 ].enumValue; +} + +static int extractSnmpLibConstant( const EnumStringMapInfo *array, int enumValue ) +{ + for ( uint i = 0; array[ i ].stringValue; ++i ) + if ( array[ i ].enumValue == enumValue ) + return array[ i ].snmpLibConstant; + + assert( false ); + return 0; +} + +int KSim::Snmp::snmpVersionToSnmpLibConstant( SnmpVersion version ) +{ + return extractSnmpLibConstant( snmpVersionStrings, version ); +} + +int KSim::Snmp::snmpSecurityLevelToSnmpLibConstant( SecurityLevel secLevel ) +{ + return extractSnmpLibConstant( securityLevelStrings, secLevel ); +} + +QStringList KSim::Snmp::allSnmpVersions() +{ + return allStrings( snmpVersionStrings ); +} + +QString KSim::Snmp::snmpVersionToString( SnmpVersion version ) +{ + return enumToString( snmpVersionStrings, version ); +} + +SnmpVersion KSim::Snmp::stringToSnmpVersion( QString string, bool *ok ) +{ + return static_cast<SnmpVersion>( stringToEnum( snmpVersionStrings, string, ok ) ); +} + +QStringList KSim::Snmp::allSecurityLevels() +{ + return allStrings( securityLevelStrings ); +} + +QString KSim::Snmp::securityLevelToString( SecurityLevel level ) +{ + return enumToString( securityLevelStrings, level ); +} + +SecurityLevel KSim::Snmp::stringToSecurityLevel( QString string, bool *ok ) +{ + return static_cast<SecurityLevel>( stringToEnum( securityLevelStrings, string, ok ) ); +} + +QStringList KSim::Snmp::allAuthenticationProtocols() +{ + return allStrings( authenticationProtocolStrings ); +} + +QString KSim::Snmp::authenticationProtocolToString( AuthenticationProtocol proto ) +{ + return enumToString( authenticationProtocolStrings, proto ); +} + +AuthenticationProtocol KSim::Snmp::stringToAuthenticationProtocol( QString string, bool *ok ) +{ + return static_cast<AuthenticationProtocol>( stringToEnum( authenticationProtocolStrings, string, ok ) ); +} + +QStringList KSim::Snmp::allPrivacyProtocols() +{ + return allStrings( privacyProtocolStrings ); +} + +QString KSim::Snmp::privacyProtocolToString( PrivacyProtocol proto ) +{ + return enumToString( privacyProtocolStrings, proto ); +} + +PrivacyProtocol KSim::Snmp::stringToPrivacyProtocol( QString string, bool *ok ) +{ + return static_cast<PrivacyProtocol>( stringToEnum( privacyProtocolStrings, string, ok ) ); +} + +// I'm afraid of them changing the order in the error constants or the like, hence the +// slow list instead of a fast lookup table +static const struct ErrorMapInfo +{ + int errorCode; + ErrorInfo::ErrorType enumValue; +} errorMap[] = +{ + // API Errors + { SNMPERR_GENERR, ErrorInfo::ErrGeneric }, + { SNMPERR_BAD_LOCPORT, ErrorInfo::ErrInvalidLocalPort }, + { SNMPERR_BAD_ADDRESS, ErrorInfo::ErrUnknownHost }, + { SNMPERR_BAD_SESSION, ErrorInfo::ErrUnknownSession }, + { SNMPERR_TOO_LONG, ErrorInfo::ErrTooLong }, + { SNMPERR_NO_SOCKET, ErrorInfo::ErrNoSocket }, + { SNMPERR_V2_IN_V1, ErrorInfo::ErrCannotSendV2PDUOnV1Session }, + { SNMPERR_V1_IN_V2, ErrorInfo::ErrCannotSendV1PDUOnV2Session }, + { SNMPERR_BAD_REPEATERS, ErrorInfo::ErrBadValueForNonRepeaters }, + { SNMPERR_BAD_REPETITIONS, ErrorInfo::ErrBadValueForMaxRepetitions }, + { SNMPERR_BAD_ASN1_BUILD, ErrorInfo::ErrBuildingASN1Representation }, + { SNMPERR_BAD_SENDTO, ErrorInfo::ErrFailureInSendto }, + { SNMPERR_BAD_PARSE, ErrorInfo::ErrBadParseOfASN1Type }, + { SNMPERR_BAD_VERSION, ErrorInfo::ErrBadVersion }, + { SNMPERR_BAD_SRC_PARTY, ErrorInfo::ErrBadSourceParty }, + { SNMPERR_BAD_DST_PARTY, ErrorInfo::ErrBadDestinationParty }, + { SNMPERR_BAD_CONTEXT, ErrorInfo::ErrBadContext }, + { SNMPERR_BAD_COMMUNITY, ErrorInfo::ErrBadCommunity }, + { SNMPERR_NOAUTH_DESPRIV, ErrorInfo::ErrCannotSendNoAuthDesPriv }, + { SNMPERR_BAD_ACL, ErrorInfo::ErrBadACL }, + { SNMPERR_BAD_PARTY, ErrorInfo::ErrBadParty }, + { SNMPERR_ABORT, ErrorInfo::ErrSessionAbortFailure }, + { SNMPERR_UNKNOWN_PDU, ErrorInfo::ErrUnknownPDU }, + { SNMPERR_TIMEOUT, ErrorInfo::ErrTimeout }, + { SNMPERR_BAD_RECVFROM, ErrorInfo::ErrFailureInRecvfrom }, + { SNMPERR_BAD_ENG_ID, ErrorInfo::ErrUnableToDetermineContextEngineID }, + { SNMPERR_BAD_SEC_NAME, ErrorInfo::ErrNoSecurityName }, + { SNMPERR_BAD_SEC_LEVEL, ErrorInfo::ErrUnableToDetermineSecurityLevel }, + { SNMPERR_ASN_PARSE_ERR, ErrorInfo::ErrASN1ParseError }, + { SNMPERR_UNKNOWN_SEC_MODEL, ErrorInfo::ErrUnknownSecurityModel }, + { SNMPERR_INVALID_MSG, ErrorInfo::ErrInvalidMessage }, + { SNMPERR_UNKNOWN_ENG_ID, ErrorInfo::ErrUnknownEngineID }, + { SNMPERR_UNKNOWN_USER_NAME, ErrorInfo::ErrUnknownUserName }, + { SNMPERR_UNSUPPORTED_SEC_LEVEL, ErrorInfo::ErrUnsupportedSecurityLevel }, + { SNMPERR_AUTHENTICATION_FAILURE, ErrorInfo::ErrAuthenticationFailure }, + { SNMPERR_NOT_IN_TIME_WINDOW, ErrorInfo::ErrNotInTimeWindow }, + { SNMPERR_DECRYPTION_ERR, ErrorInfo::ErrDecryptionError }, + { SNMPERR_SC_GENERAL_FAILURE, ErrorInfo::ErrSCAPIGeneralFailure }, + { SNMPERR_SC_NOT_CONFIGURED, ErrorInfo::ErrSCAPISubSystemNotConfigured }, + { SNMPERR_KT_NOT_AVAILABLE, ErrorInfo::ErrNoKeyTools }, + { SNMPERR_UNKNOWN_REPORT, ErrorInfo::ErrUnknownReport }, + { SNMPERR_USM_GENERICERROR, ErrorInfo::ErrUSMGenericError }, + { SNMPERR_USM_UNKNOWNSECURITYNAME, ErrorInfo::ErrUSMUnknownSecurityName }, + { SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL, ErrorInfo::ErrUSMUnsupportedSecurityLevel }, + { SNMPERR_USM_ENCRYPTIONERROR, ErrorInfo::ErrUSMEncryptionError }, + { SNMPERR_USM_AUTHENTICATIONFAILURE, ErrorInfo::ErrUSMAuthenticationFailure }, + { SNMPERR_USM_PARSEERROR, ErrorInfo::ErrUSMParseError }, + { SNMPERR_USM_UNKNOWNENGINEID, ErrorInfo::ErrUSMUnknownEngineID }, + { SNMPERR_USM_NOTINTIMEWINDOW, ErrorInfo::ErrUSMNotInTimeWindow }, + { SNMPERR_USM_DECRYPTIONERROR, ErrorInfo::ErrUSMDecryptionError }, + { SNMPERR_NOMIB, ErrorInfo::ErrMIBNotInitialized }, + { SNMPERR_RANGE, ErrorInfo::ErrValueOutOfRange }, + { SNMPERR_MAX_SUBID, ErrorInfo::ErrSubIdOutOfRange }, + { SNMPERR_BAD_SUBID, ErrorInfo::ErrBadSubIdInOID }, + { SNMPERR_LONG_OID, ErrorInfo::ErrOIDTooLong }, + { SNMPERR_BAD_NAME, ErrorInfo::ErrBadValueName }, + { SNMPERR_VALUE, ErrorInfo::ErrBadValueNotation }, + { SNMPERR_UNKNOWN_OBJID, ErrorInfo::ErrUnknownOID }, + { SNMPERR_NULL_PDU, ErrorInfo::ErrNullPDU }, + { SNMPERR_NO_VARS, ErrorInfo::ErrMissingVariables }, + { SNMPERR_VAR_TYPE, ErrorInfo::ErrBadVariableType }, + { SNMPERR_MALLOC, ErrorInfo::ErrOOM }, + { SNMPERR_KRB5, ErrorInfo::ErrKerberos }, + + // PDU response errors + { SNMP_ERR_TOOBIG, ErrorInfo::ErrResponseTooLarge }, + { SNMP_ERR_NOSUCHNAME, ErrorInfo::ErrNoSuchVariable }, + { SNMP_ERR_BADVALUE, ErrorInfo::ErrBadValue }, + { SNMP_ERR_READONLY, ErrorInfo::ErrReadOnly }, + { SNMP_ERR_GENERR, ErrorInfo::ErrGeneric }, + { SNMP_ERR_NOACCESS, ErrorInfo::ErrNoAccess }, + { SNMP_ERR_WRONGTYPE, ErrorInfo::ErrWrongType }, + { SNMP_ERR_WRONGLENGTH, ErrorInfo::ErrWrongLength }, + { SNMP_ERR_WRONGENCODING, ErrorInfo::ErrWrongEncoding }, + { SNMP_ERR_WRONGVALUE, ErrorInfo::ErrWrongValue }, + { SNMP_ERR_NOCREATION, ErrorInfo::ErrNoCreation }, + { SNMP_ERR_INCONSISTENTVALUE, ErrorInfo::ErrInconsistentValue }, + { SNMP_ERR_RESOURCEUNAVAILABLE, ErrorInfo::ErrResourceUnavailable }, + { SNMP_ERR_COMMITFAILED, ErrorInfo::ErrCommitFailed }, + { SNMP_ERR_UNDOFAILED, ErrorInfo::ErrUndoFailed }, + { SNMP_ERR_AUTHORIZATIONERROR, ErrorInfo::ErrAuthorizationFailed }, + { SNMP_ERR_NOTWRITABLE, ErrorInfo::ErrNotWritable }, + { SNMP_ERR_INCONSISTENTNAME, ErrorInfo::ErrInconsistentName }, + + { SNMPERR_SUCCESS, ErrorInfo::NoError } +}; + +ErrorInfo::ErrorType KSim::Snmp::convertSnmpLibErrorToErrorInfo( int error ) +{ + for ( uint i = 0; errorMap[ i ].errorCode != SNMPERR_SUCCESS; ++i ) + if ( errorMap[ i ].errorCode == error ) + return errorMap[ i ].enumValue; + return ErrorInfo::ErrUnknown; +} + +int KSim::Snmp::convertErrorInfoToSnmpLibError( ErrorInfo::ErrorType error ) +{ + for ( uint i = 0; errorMap[ i ].errorCode != SNMPERR_SUCCESS; ++i ) + if ( errorMap[ i ].enumValue == error ) + return errorMap[ i ].errorCode; + assert( false ); + return SNMPERR_SUCCESS; +} + +int KSim::Snmp::sessionErrorCode( netsnmp_session &session ) +{ + int errorCode = 0; + SnmpLib::self()->snmp_error( &session, 0, &errorCode, 0 ); + return errorCode; +} + +static QString messageForErrorCode( int errorCode ) +{ + if ( errorCode >= SNMPERR_MAX && errorCode <= SNMPERR_GENERR ) + return QString::fromLatin1( SnmpLib::self()->snmp_api_errstring( errorCode ) ); + if ( errorCode >= SNMP_ERR_NOERROR && errorCode <= MAX_SNMP_ERR ) + return QString::fromLatin1( SnmpLib::self()->snmp_errstring( errorCode ) ); + + return QString::null; +} + +ErrorInfo::ErrorInfo() +{ + m_errorCode = NoError; +} + +ErrorInfo::ErrorInfo( int internalErrorCode ) +{ + m_errorCode = convertSnmpLibErrorToErrorInfo( internalErrorCode ); + m_errorMessage = messageForErrorCode( internalErrorCode ); +} + +ErrorInfo::ErrorInfo( ErrorType error ) +{ + m_errorCode = error; + if ( error != NoError && error != ErrUnknown ) + m_errorMessage = messageForErrorCode( convertErrorInfoToSnmpLibError( error ) ); +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmp.h b/ksim/monitors/snmp/snmp.h new file mode 100644 index 0000000..4710c2d --- /dev/null +++ b/ksim/monitors/snmp/snmp.h @@ -0,0 +1,165 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSIM_SNMP_H +#define KSIM_SNMP_H + +#include <kconfigbase.h> + +#include <qmap.h> + + +namespace KSim +{ + +namespace Snmp +{ + +enum SnmpVersion { SnmpVersion1, SnmpVersion2c, SnmpVersion3, SnmpLastVersion }; +QStringList allSnmpVersions(); +QString snmpVersionToString( SnmpVersion version ); +SnmpVersion stringToSnmpVersion( QString string, bool *ok = 0 ); + +enum SecurityLevel { NoAuthPriv, AuthNoPriv, AuthPriv, LastSecurityLevel }; +QStringList allSecurityLevels(); +QString securityLevelToString( SecurityLevel level ); +SecurityLevel stringToSecurityLevel( QString string, bool *ok = 0 ); + +enum AuthenticationProtocol { MD5Auth, SHA1Auth, LastAuthenticationProtocol }; +QStringList allAuthenticationProtocols(); +QString authenticationProtocolToString( AuthenticationProtocol proto ); +AuthenticationProtocol stringToAuthenticationProtocol( QString string, bool *ok = 0 ); + +enum PrivacyProtocol { DESPrivacy }; +QStringList allPrivacyProtocols(); +QString privacyProtocolToString( PrivacyProtocol proto ); +PrivacyProtocol stringToPrivacyProtocol( QString string, bool *ok = 0 ); + +class ErrorInfo +{ +public: + enum ErrorType { + NoError = 0, + ErrUnknown, // ... if we forgot a mapping of error codes + + // api errors + ErrGeneric, + ErrInvalidLocalPort, + ErrUnknownHost, + ErrUnknownSession, + ErrTooLong, + ErrNoSocket, + ErrCannotSendV2PDUOnV1Session, + ErrCannotSendV1PDUOnV2Session, + ErrBadValueForNonRepeaters, + ErrBadValueForMaxRepetitions, + ErrBuildingASN1Representation, + ErrFailureInSendto, + ErrBadParseOfASN1Type, + ErrBadVersion, + ErrBadSourceParty, + ErrBadDestinationParty, + ErrBadContext, + ErrBadCommunity, + ErrCannotSendNoAuthDesPriv, + ErrBadACL, + ErrBadParty, + ErrSessionAbortFailure, + ErrUnknownPDU, + ErrTimeout, + ErrFailureInRecvfrom, + ErrUnableToDetermineContextEngineID, + ErrNoSecurityName, + ErrUnableToDetermineSecurityLevel, + ErrASN1ParseError, + ErrUnknownSecurityModel, + ErrInvalidMessage, + ErrUnknownEngineID, + ErrUnknownUserName, + ErrUnsupportedSecurityLevel, + ErrAuthenticationFailure, + ErrNotInTimeWindow, + ErrDecryptionError, + ErrSCAPIGeneralFailure, + ErrSCAPISubSystemNotConfigured, + ErrNoKeyTools, + ErrUnknownReport, + ErrUSMGenericError, + ErrUSMUnknownSecurityName, + ErrUSMUnsupportedSecurityLevel, + ErrUSMEncryptionError, + ErrUSMAuthenticationFailure, + ErrUSMParseError, + ErrUSMUnknownEngineID, + ErrUSMNotInTimeWindow, + ErrUSMDecryptionError, + ErrMIBNotInitialized, + ErrValueOutOfRange, + ErrSubIdOutOfRange, + ErrBadSubIdInOID, + ErrOIDTooLong, + ErrBadValueName, + ErrBadValueNotation, + ErrUnknownOID, + ErrNullPDU, + ErrMissingVariables, + ErrBadVariableType, + ErrOOM, + ErrKerberos, + + // pdu response errors + + ErrResponseTooLarge, + ErrNoSuchVariable, + ErrBadValue, + ErrReadOnly, + ErrNoAccess, + ErrWrongType, + ErrWrongLength, + ErrWrongEncoding, + ErrWrongValue, + ErrNoCreation, + ErrInconsistentValue, + ErrResourceUnavailable, + ErrCommitFailed, + ErrUndoFailed, + ErrAuthorizationFailed, + ErrNotWritable, + ErrInconsistentName + }; + + ErrorInfo(); + ErrorInfo( int internalErrorCode ); + ErrorInfo( ErrorType error ); + + ErrorType errorCode() const { return m_errorCode; } + QString errorMessage() const { return m_errorMessage; } + +private: + ErrorType m_errorCode; + QString m_errorMessage; +}; + +} + +} + +#endif // KSIMSNMP_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmp_p.h b/ksim/monitors/snmp/snmp_p.h new file mode 100644 index 0000000..9d96868 --- /dev/null +++ b/ksim/monitors/snmp/snmp_p.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SNMP_P_H +#define SNMP_P_H + +#define HAVE_STRLCPY 1 +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include "snmp.h" +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +ErrorInfo::ErrorType convertSnmpLibErrorToErrorInfo( int error ); +int convertErrorInfoToSnmpLibError( ErrorInfo::ErrorType error ); + +int snmpVersionToSnmpLibConstant( SnmpVersion version ); +int snmpSecurityLevelToSnmpLibConstant( SecurityLevel secLevel ); + +int sessionErrorCode( netsnmp_session &session ); + +struct Identifier::Data +{ + Data() : length( 0 ) {} + Data( const oid *d, size_t length ); + + oid data[ MAX_OID_LEN ]; + size_t length; +}; + +} + +} + +#endif // SNMP_P_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmplib.cpp b/ksim/monitors/snmp/snmplib.cpp new file mode 100644 index 0000000..a063203 --- /dev/null +++ b/ksim/monitors/snmp/snmplib.cpp @@ -0,0 +1,151 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "snmplib.h" +#include "snmp_p.h" + +#include <kstaticdeleter.h> + +using namespace KSim::Snmp; + +SnmpLib *SnmpLib::s_self; + +::KStaticDeleter<KSim::Snmp::SnmpLib> sd; + +SnmpLib::SnmpLib() +{ + m_lockHelper = new ClassLocker<SnmpLib>( &m_guard, this ); + + init_snmp( "ksim" ); +} + +SnmpLib::~SnmpLib() +{ + delete m_lockHelper; +} + +ClassLocker<SnmpLib> &SnmpLib::self() +{ + if ( !s_self ) { + static QMutex singletonGuard; + + QMutexLocker locker( &singletonGuard ); + if ( !s_self ) + sd.setObject( s_self, new SnmpLib ); + } + return *s_self->m_lockHelper; +} + +oid *SnmpLib::snmp_parse_oid( const char *name, oid *oid, size_t *length ) +{ + return ::snmp_parse_oid( name, oid, length ); +} + +int SnmpLib::netsnmp_ds_set_int( int storeid, int which, int value ) +{ + return ::netsnmp_ds_set_int( storeid, which, value ); +} + +int SnmpLib::netsnmp_ds_get_int( int storeid, int which ) +{ + return ::netsnmp_ds_get_int( storeid, which ); +} + +struct tree *SnmpLib::netsnmp_sprint_realloc_objid_tree( u_char ** buf, + size_t * buf_len, + size_t * out_len, + int allow_realloc, + int *buf_overflow, + const oid * objid, + size_t objidlen ) +{ + return ::netsnmp_sprint_realloc_objid_tree( buf, buf_len, out_len, allow_realloc, buf_overflow, objid, objidlen ); +} + +int SnmpLib::netsnmp_oid_equals( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ) +{ + return ::netsnmp_oid_equals( firstOid, firstOidLen, secondOid, secondOidLen ); +} + +int SnmpLib::snmp_oid_compare( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ) +{ + return ::snmp_oid_compare( firstOid, firstOidLen, secondOid, secondOidLen ); +} + +void SnmpLib::snmp_error( netsnmp_session *session, int *p_errno, int *p_snmp_errno, char **p_str ) +{ + ::snmp_error( session, p_errno, p_snmp_errno, p_str ); +} + +const char *SnmpLib::snmp_api_errstring( int code ) +{ + return ::snmp_api_errstring( code ); +} + +const char *SnmpLib::snmp_errstring( int code ) +{ + return ::snmp_errstring( code ); +} + +netsnmp_pdu *SnmpLib::snmp_pdu_create( int pduType ) +{ + return ::snmp_pdu_create( pduType ); +} + +void SnmpLib::snmp_free_pdu( netsnmp_pdu *pdu ) +{ + ::snmp_free_pdu( pdu ); +} + +netsnmp_variable_list *SnmpLib::snmp_add_null_var( netsnmp_pdu *pdu, oid *var, size_t varlen ) +{ + return ::snmp_add_null_var( pdu, var, varlen ); +} + +void SnmpLib::snmp_sess_init( netsnmp_session *session ) +{ + ::snmp_sess_init( session ); +} + +netsnmp_session *SnmpLib::snmp_open( netsnmp_session *session ) +{ + return ::snmp_open( session ); +} + +int SnmpLib::snmp_close( netsnmp_session *session ) +{ + return ::snmp_close( session ); +} + +int SnmpLib::snmp_synch_response( netsnmp_session *session, netsnmp_pdu *pdu, + netsnmp_pdu **response ) +{ + return ::snmp_synch_response( session, pdu, response ); +} + +int SnmpLib::generate_Ku( const oid * hashtype, u_int hashtype_len, + u_char * P, size_t pplen, + u_char * Ku, size_t * kulen ) +{ + return ::generate_Ku( hashtype, hashtype_len, P, pplen, Ku, kulen ); +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmplib.h b/ksim/monitors/snmp/snmplib.h new file mode 100644 index 0000000..e8b14a4 --- /dev/null +++ b/ksim/monitors/snmp/snmplib.h @@ -0,0 +1,143 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SNMPLIB_H +#define SNMPLIB_H + +// ### REMOVEME: move snmplib somewhere else +#define HAVE_STRLCPY 1 +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include <qmutex.h> + +template <class> class KStaticDeleter; + +namespace KSim +{ + +namespace Snmp +{ + +template <class T> +class ClassLocker +{ +public: + ClassLocker( QMutex *guard, T *obj ) + : m_guard( guard ), m_obj( obj ) + {} + + struct ClassLockerHelper + { + ClassLockerHelper( QMutex *guard, T *obj ) + : m_guard( guard ), m_obj( obj ), m_locked( false ) + {} + + ~ClassLockerHelper() + { + if ( m_locked ) + m_guard->unlock(); + } + + T *operator->() + { + m_guard->lock(); + m_locked = true; + return m_obj; + } + + private: + QMutex *m_guard; + T *m_obj; + bool m_locked; + }; + + ClassLockerHelper operator->() + { + return ClassLockerHelper( m_guard, m_obj ); + } + +private: + ClassLocker( const ClassLocker & ); + ClassLocker &operator=( const ClassLocker & ); + + QMutex *m_guard; + T *m_obj; +}; + +class SnmpLib +{ + friend class KStaticDeleter<SnmpLib>; +public: + + static ClassLocker<SnmpLib> &self(); + + oid *snmp_parse_oid( const char *name, oid *oid, size_t *length ); + + int netsnmp_ds_set_int( int storeid, int which, int value ); + int netsnmp_ds_get_int( int storeid, int which ); + + struct tree *netsnmp_sprint_realloc_objid_tree( u_char ** buf, + size_t * buf_len, + size_t * out_len, + int allow_realloc, + int *buf_overflow, + const oid * objid, + size_t objidlen ); + + int netsnmp_oid_equals( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ); + int snmp_oid_compare( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ); + + void snmp_error( netsnmp_session *session, int *p_errno, int *p_snmp_errno, char **p_str ); + const char *snmp_api_errstring( int code ); + const char *snmp_errstring( int code ); + + netsnmp_pdu *snmp_pdu_create( int pduType ); + void snmp_free_pdu( netsnmp_pdu *pdu ); + netsnmp_variable_list *snmp_add_null_var( netsnmp_pdu *pdu, oid *var, size_t varlen ); + + void snmp_sess_init( netsnmp_session *session ); + netsnmp_session *snmp_open( netsnmp_session *session ); + int snmp_close( netsnmp_session *session ); + + int snmp_synch_response( netsnmp_session *session, netsnmp_pdu *pdu, + netsnmp_pdu **response ); + + int generate_Ku( const oid * hashtype, u_int hashtype_len, + u_char * P, size_t pplen, + u_char * Ku, size_t * kulen ); + +private: + SnmpLib(); + ~SnmpLib(); + + QMutex m_guard; + ClassLocker<SnmpLib> *m_lockHelper; + + static SnmpLib *s_self; +}; + +} +} + + +#endif // SNMPLIB_H +/* vim: et sw=4 ts=4 + */ + diff --git a/ksim/monitors/snmp/value.cpp b/ksim/monitors/snmp/value.cpp new file mode 100644 index 0000000..fe42a08 --- /dev/null +++ b/ksim/monitors/snmp/value.cpp @@ -0,0 +1,333 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "value.h" +#include "value_p.h" +#include "snmp_p.h" + +#include <qvariant.h> + +#include <klocale.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +ValueImpl::ValueImpl( variable_list *var ) +{ + switch ( var->type ) { + case ASN_INTEGER: { + type = Value::Int; + data = QVariant( static_cast<int>( *var->val.integer ) ); + break; + } + case ASN_UINTEGER: { + type = Value::UInt; + data = QVariant( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_OCTET_STR: { + type = Value::ByteArray; + QByteArray d; + d.setRawData( reinterpret_cast<char *>( var->val.string ), var->val_len ); + QByteArray copy = d; + copy.detach(); + d.resetRawData( reinterpret_cast<char *>( var->val.string ), var->val_len ); + data = QVariant( copy ); + break; + } + case ASN_NULL: { + type = Value::Null; + break; + } + case ASN_OBJECT_ID: { + type = Value::Oid; + oid = Identifier( new Identifier::Data( var->val.objid, var->val_len / sizeof( oid ) ) ); + break; + } + case ASN_IPADDRESS: { + type = Value::IpAddress; + addr = QHostAddress( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_COUNTER: { + type = Value::Counter; + data = QVariant( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_GAUGE: { + type = Value::Gauge; + data = QVariant( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_COUNTER64: { + type = Value::Counter64; + ctr64 = ( ( ( Q_UINT64 )var->val.counter64->high ) << 32 ) | ( var->val.counter64->low ); + break; + } + case ASN_TIMETICKS: { + type = Value::TimeTicks; + data = QVariant( static_cast<int>( *var->val.integer ) ); + break; + } + case SNMP_NOSUCHOBJECT: { + type = Value::NoSuchObject; + break; + } + case SNMP_NOSUCHINSTANCE: { + type = Value::NoSuchInstance; + break; + } + case SNMP_ENDOFMIBVIEW: { + type = Value::EndOfMIBView; + break; + } +#if defined( OPAQUE_SPECIAL_TYPES ) + case ASN_OPAQUE_FLOAT: { + type = Value::Double; + data = QVariant( static_cast<float>( *var->val.floatVal ) ); + break; + } + case ASN_OPAQUE_DOUBLE: { + type = Value::Double; + data = QVariant( static_cast<float>( *var->val.doubleVal ) ); + break; + } +#endif + default: { + qDebug( "ValueImp: converting from %i to invalid", var->type ); + type = Value::Invalid; break; + } + } +} + +Value::Value() +{ + d = new ValueImpl; +} + +Value::Value( ValueImpl *impl ) + : d( impl ) +{ +} + +Value::Value( int val, Type type ) +{ + d = new ValueImpl; + + assert( type == Int || type == TimeTicks ); + + d->type = type; + d->data = QVariant( val ); +} + +Value::Value( uint val, Type type ) +{ + d = new ValueImpl; + + assert( type == UInt || type == Counter || type == Gauge ); + + d->type = type; + d->data = QVariant( val ); +} + +Value::Value( double val ) +{ + d = new ValueImpl; + d->type = Double; + d->data = QVariant( val ); +} + +Value::Value( const QByteArray &data ) +{ + d = new ValueImpl; + d->type = ByteArray; + d->data = QVariant( data ); +} + +Value::Value( const KSim::Snmp::Identifier &oid ) +{ + d = new ValueImpl; + d->type = Value::Oid; + d->oid = oid; +} + +Value::Value( const QHostAddress &address ) +{ + d = new ValueImpl; + d->type = IpAddress; + d->addr = address; +} + +Value::Value( Q_UINT64 counter ) +{ + d = new ValueImpl; + d->type = Counter64; + d->ctr64 = counter; +} + +Value::Value( const Value &rhs ) +{ + d = new ValueImpl( *rhs.d ); +} + +Value &Value::operator=( const Value &rhs ) +{ + if ( this == &rhs ) + return *this; + + delete d; + d = new ValueImpl( *rhs.d ); + + return *this; +} + +Value::~Value() +{ + delete d; +} + +Value::Type Value::type() const +{ + return d->type; +} + +int Value::toInt() const +{ + switch ( d->type ) { + case Int: + case TimeTicks: return d->data.toInt(); + case Invalid: qDebug( "cannot convert from invalid to int" ); + default: assert( false ); + } + assert( false ); + return -1; +} + +uint Value::toUInt() const +{ + switch ( d->type ) { + case UInt: + case Counter: + case Gauge: return d->data.toUInt(); + case Invalid: qDebug( "cannot convert from invalid to uint" ); + default: assert( false ); + } + assert( false ); + return 0; +} + +double Value::toDouble() const +{ + assert( d->type == Double ); + return d->data.toDouble(); +} + +const QByteArray Value::toByteArray() const +{ + assert( d->type == ByteArray ); + return d->data.toByteArray(); +} + +const Identifier Value::toOID() const +{ + assert( d->type == Oid ); + return d->oid; +} + +const QHostAddress Value::toIpAddress() const +{ + assert( d->type == IpAddress ); + return d->addr; +} + +uint Value::toCounter() const +{ + return toUInt(); +} + +uint Value::toGauge() const +{ + return toUInt(); +} + +int Value::toTimeTicks() const +{ + return toInt(); +} + +Q_UINT64 Value::toCounter64() const +{ + assert( d->type == Counter64 ); + return d->ctr64; +} + +QString Value::toString( int conversionFlags ) const +{ + switch ( type() ) { + case Value::Int: return QString::number( toInt() ); + case Value::Gauge: + case Value::Counter: + case Value::UInt: return QString::number( toUInt() ); + case Value::Double: return QString::number( toDouble() ); + case Value::Counter64: return QString::number( toCounter64() ); + case Value::ByteArray: return QString::fromAscii( toByteArray().data(), toByteArray().size() ); + case Value::IpAddress: return toIpAddress().toString(); + case Value::Oid: return toOID().toString(); + case Value::TimeTicks: return formatTimeTicks( toTimeTicks(), conversionFlags ); + // not using i18n here, because it may be called from within a worker thread, and I'm + // not sure it makes sense to translate it anyway + case Value::NoSuchObject: return QString::fromLatin1( "No Such Object" ); + case Value::NoSuchInstance: return QString::fromLatin1( "No Such Instance" ); + case Value::EndOfMIBView: return QString::fromLatin1( "End Of MIB View" ); + case Value::Invalid: + case Value::Null: return QString::null; + } + return QString::null; +} + +QString Value::formatTimeTicks( int ticks, int conversionFlags ) +{ + ticks /= 100; + + int days = ticks / ( 60 * 60 * 24 ); + ticks %= 60 * 60 * 24; + + int hours = ticks / ( 60 * 60 ); + ticks %= 60 * 60; + + int minutes = ticks / 60; + int seconds = ticks % 60; + + QString result; + + if ( days > 0 ) + result += QString::number( days ) + "d:"; + + result += QString::fromAscii( "%1h:%2m" ).arg( hours ).arg( minutes ); + + if ( conversionFlags & TimeTicksWithSeconds ) + result += ":" + QString::number( seconds ) + "s"; + + return result; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/value.h b/ksim/monitors/snmp/value.h new file mode 100644 index 0000000..4ffdcbb --- /dev/null +++ b/ksim/monitors/snmp/value.h @@ -0,0 +1,106 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VALUE_H +#define VALUE_H + +#include <qhostaddress.h> + +namespace KSim +{ + +namespace Snmp +{ + +class ValueImpl; + +class Identifier; + +struct ValueImpl; + +class Value +{ +public: + enum Type { + Invalid, + Int, + UInt, + Double, + ByteArray, + Null, + Oid, + IpAddress, + Counter, + Gauge, + TimeTicks, + Counter64, + NoSuchObject, + NoSuchInstance, + EndOfMIBView + }; + + enum StringConversionFlags { TimeTicksWithSeconds = 0x1 }; + + Value(); + + Value( ValueImpl *imp ); + + Value( int val, Type type ); + Value( uint val, Type type ); + Value( float val ); + Value( double val ); + Value( const QByteArray &data ); + Value( const Identifier &oid ); + Value( const QHostAddress &address ); + Value( Q_UINT64 counter ); + + Value( const Value &rhs ); + Value &operator=( const Value &rhs ); + ~Value(); + + Type type() const; + + bool isCounterType() const { return type() == Value::Counter || type() == Value::Counter64; } + + int toInt() const; + uint toUInt() const; + double toDouble() const; + const QByteArray toByteArray() const; + const Identifier toOID() const; + const QHostAddress toIpAddress() const; + uint toCounter() const; + uint toGauge() const; + int toTimeTicks() const; + Q_UINT64 toCounter64() const; + + QString toString( int conversionFlags = 0 ) const; + +private: + static QString formatTimeTicks( int ticks, int conversionFlags ); + + ValueImpl *d; +}; + +} + +} + +#endif // VALUE_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/value_p.h b/ksim/monitors/snmp/value_p.h new file mode 100644 index 0000000..8d61f59 --- /dev/null +++ b/ksim/monitors/snmp/value_p.h @@ -0,0 +1,63 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VALUE_P_H +#define VALUE_P_H + +#define HAVE_STRLCPY 1 +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include <qvariant.h> + +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +struct ValueImpl +{ + ValueImpl() + : type( Value::Invalid ) + {} + + ValueImpl( const ValueImpl &rhs ) + { + ( *this ) = rhs; + } + + ValueImpl( variable_list *var ); + + Value::Type type; + QVariant data; + Identifier oid; + QHostAddress addr; + Q_UINT64 ctr64; +}; + +} + +} + +#endif // VALUE_P_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/view.cpp b/ksim/monitors/snmp/view.cpp new file mode 100644 index 0000000..0a4b276 --- /dev/null +++ b/ksim/monitors/snmp/view.cpp @@ -0,0 +1,80 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "view.h" +#include "plugin.h" +#include "monitorconfig.h" + +#include <label.h> + +#include <qlayout.h> + +#include <kconfig.h> + +using namespace KSim::Snmp; + +View::View( Plugin *parent, const char *name ) + : KSim::PluginView( parent, name ) +{ + m_layout = new QVBoxLayout( this ); + + reparseConfig(); +} + +View::~View() +{ +} + +void View::reparseConfig() +{ + m_widgets.setAutoDelete( true ); + m_widgets.clear(); + m_widgets.setAutoDelete( false ); + + KConfig &cfg = *config(); + cfg.setGroup( "General" ); + QStringList allHosts = cfg.readListEntry( "Hosts" ); + QStringList monitors = cfg.readListEntry( "Monitors" ); + + HostConfigMap hosts; + hosts.load( cfg, allHosts ); + + MonitorConfigMap monitorConfigs; + monitorConfigs.load( cfg, monitors, hosts ); + + for ( MonitorConfigMap::ConstIterator it = monitorConfigs.begin(); + it != monitorConfigs.end(); ++it ) { + + MonitorConfig monitorConfig = *it; + + QWidget *w = monitorConfig.createMonitorWidget( this ); + if ( !w ) + continue; + + m_widgets.append( w ); + m_layout->addWidget( w ); + + w->show(); + } +} + +#include "view.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/view.h b/ksim/monitors/snmp/view.h new file mode 100644 index 0000000..f03a59c --- /dev/null +++ b/ksim/monitors/snmp/view.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VIEW_H +#define VIEW_H + +#include <pluginmodule.h> + +class QBoxLayout; + +namespace KSim +{ + +namespace Snmp +{ + +class Plugin; + +class View : public KSim::PluginView +{ + Q_OBJECT +public: + View( Plugin *parent, const char *name ); + ~View(); + + virtual void reparseConfig(); + +private: + QPtrList<QWidget> m_widgets; + QBoxLayout *m_layout; +}; + +} + +} + +#endif // VIEW_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/walker.cpp b/ksim/monitors/snmp/walker.cpp new file mode 100644 index 0000000..593cd04 --- /dev/null +++ b/ksim/monitors/snmp/walker.cpp @@ -0,0 +1,121 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "walker.h" + +#include <qapplication.h> + +#include <functional> +#include <algorithm> + +using namespace KSim::Snmp; + +namespace +{ + template <class T> + struct Deleter : public std::unary_function<T, void> + { + void operator()( T arg ) + { delete arg; } + }; +} + +static const uint walkerRefresh = 0; + +Walker::Walker( const HostConfig &host, const Identifier &startOid, QObject *parent, const char *name ) + : QObject( parent, name ), m_stop( false ), m_oid( startOid ), m_session( host ) +{ + m_timerId = startTimer( walkerRefresh ); + start(); +} + +Walker::~Walker() +{ + m_stopGuard.lock(); + m_stop = true; + m_stopGuard.unlock(); + + if ( QThread::running() ) + QThread::wait(); + + std::for_each( m_results.begin(), m_results.end(), Deleter<Result *>() ); +} + +void Walker::run() +{ + while ( !m_stop ) { + Result *result = new Result; + + result->success = m_session.snmpGetNext( m_oid, result->data, &result->error ); + result->oid = m_oid; + + // do it here, because it sometimes is slow and can block for a bit + if ( result->success ) { + result->identifierString = result->oid.toString(); + result->dataString = result->data.toString(); + } + + m_stopGuard.lock(); + if ( !m_stop ) + m_stop = !result->success; + m_stopGuard.unlock(); + + m_resultGuard.lock(); + m_results << result; + m_resultGuard.unlock(); + } + + // cause finished signal to be emitted + QApplication::postEvent( this, new QCustomEvent( QEvent::User ) ); +} + +void Walker::timerEvent( QTimerEvent *ev ) +{ + if ( ev->timerId() != m_timerId ) + return; + + Result *result = 0; + + m_resultGuard.lock(); + if ( !m_results.isEmpty() ) { + result = m_results.first(); + m_results.remove( m_results.begin() ); + } + m_resultGuard.unlock(); + + if ( result ) { + emit resultReady( *result ); + + delete result; + } + + if ( !QThread::running() && !result ) { + killTimer( m_timerId ); + m_timerId = 0; + } +} + +void Walker::customEvent( QCustomEvent * ) +{ + emit finished(); +} + +#include "walker.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/walker.h b/ksim/monitors/snmp/walker.h new file mode 100644 index 0000000..e1b1ace --- /dev/null +++ b/ksim/monitors/snmp/walker.h @@ -0,0 +1,82 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef WALKER_H +#define WALKER_H + +#include <qthread.h> +#include <qobject.h> +#include <qmutex.h> +#include <qvaluelist.h> + +#include "session.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Walker : public QObject, public QThread +{ + Q_OBJECT +public: + Walker( const HostConfig &host, const Identifier &startOid, QObject *parent, const char *name = 0 ); + virtual ~Walker(); + + struct Result + { + Result() : success( false ) {} + bool success; + Identifier oid; + QString identifierString; + Value data; + QString dataString; + ErrorInfo error; + }; + +signals: + void resultReady( const Walker::Result &result ); + void finished(); + +protected: + virtual void run(); + virtual void timerEvent( QTimerEvent *ev ); + virtual void customEvent( QCustomEvent *ev ); + +private: + typedef QValueList<Result *> ResultList; + + ResultList m_results; + QMutex m_resultGuard; + + bool m_stop; + QMutex m_stopGuard; + + Identifier m_oid; + int m_timerId; + Session m_session; +}; + +} +} + +#endif // WALKER_H +/* vim: et sw=4 ts=4 + */ |