?? show_peer_stats.cc
字號(hào):
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// Copyright (c) 2001-2008 XORP, Inc.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the "Software")// to deal in the Software without restriction, subject to the conditions// listed in the XORP LICENSE file. These conditions include: you must// preserve this copyright notice, and you cannot mention the copyright// holders in advertising related to the Software without their permission.// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This// notice is a summary of the XORP LICENSE file; the license in that file is// legally binding.#ident "$XORP: xorp/rip/tools/show_peer_stats.cc,v 1.15 2008/07/23 05:11:40 pavlin Exp $"#include <iomanip>#include "rip/rip_module.h"#include "libxorp/xorp.h"#include "libxorp/xlog.h"#include "libxorp/eventloop.hh"#include "libxorp/ipv4.hh"#include "libxorp/ipv6.hh"#include "libxorp/ref_ptr.hh"#include "libxorp/service.hh"#include "libxipc/xrl_std_router.hh"#include "xrl/interfaces/rip_xif.hh"#include "xrl/interfaces/ripng_xif.hh"#include "common.hh"#ifdef HAVE_GETOPT_H#include <getopt.h>#endifstatic const char* NO_PEERS = "There are no known peers.";static const char* NO_PEERS_ON_ADDR = "There are no known peers on ";// ----------------------------------------------------------------------------// Utility methodsstatic voidusage(){ fprintf(stderr, "Usage: %s [options] (rip|ripng) [<interface> <vif> <addr> [<peer>]]\n", xlog_process_name()); fprintf(stderr, "Options:\n"); fprintf(stderr, "\t -1 " "Single line output (used by 'show rip peer')\n"); fprintf(stderr, "\t -F <finder_host>:<finder_port> " "Specify Finder host and port to use.\n"); fprintf(stderr, "\t -T <targetname> " "Specify XrlTarget to query.\n\n"); exit(-1);}template <typename A>static voidprint_peer_header(const A& peer, const string& ifn, const string& vifn, const A& addr){ cout << endl; cout << "* RIP statistics for peer " << peer.str() << " on " << ifn << " " << vifn << " " << addr.str() << endl << endl;}static voidpretty_print_counters(const XrlAtomList& descriptions, const XrlAtomList& values, uint32_t last_active){ static const uint32_t COL1 = 32; static const uint32_t COL2 = 16; time_t when = static_cast<time_t>(last_active); char whenbuf[12]; (void)strftime(&whenbuf[0], sizeof(whenbuf), "%H:%M:%S", gmtime(&when)); // Save flags ios::fmtflags fl = cout.flags(); cout << " "; cout << "Last Active at " << whenbuf << endl; cout.flags(ios::left); cout << " "; cout << setw(COL1) << "Counter" << setw(0) << " "; cout.flags(ios::right); cout << setw(COL2) << "Value" << endl; cout.flags(ios::left); cout << " "; cout << setw(COL1) << string(COL1, '-') << setw(0) << " "; cout.flags(ios::right); cout << setw(COL2) << string(COL2, '-') << endl; for (size_t i = 0; i != descriptions.size(); ++i) { const XrlAtom& d = descriptions.get(i); const XrlAtom& v = values.get(i); cout.flags(ios::left); cout << setw(0) << " "; // NB we use string.c_str() here as GCC's string ostream // renderer seems to ignore the field width. Formatting // ostreams is supremely fugly. cout << setw(COL1) << d.text().c_str(); cout << setw(0) << " "; cout.flags(ios::right); cout << setw(COL2) << v.uint32() << endl; } // Restore flags cout.flags(fl);}template <typename A>static voidpretty_print_counters_single_line(const XrlAtomList& descriptions, const XrlAtomList& values, uint32_t last_active, const A& peer, const string& ifn, const string& vifn){ time_t when = static_cast<time_t>(last_active); char whenbuf[12]; (void)strftime(&whenbuf[0], sizeof(whenbuf), "%H:%M:%S", gmtime(&when)); // RIP sends the descriptions of each counter back, // we will need to scan the atom list for what we want. uint32_t rxcount = 0; for (size_t i = 0; i != descriptions.size(); ++i) { const XrlAtom& d = descriptions.get(i); const XrlAtom& v = values.get(i); if (0 == strcasecmp(d.text().c_str(), "Request Packets Received")) { rxcount = v.uint32(); break; } } ios::fmtflags fl = cout.flags(); cout.flags(ios::left); // XXX We are using C++ style formatting here. I would prefer to use // fprintf because you can just bang that out. This is somewhat tedious. cout << setw(17) << peer.str() << setw(4) << ifn << setw(1) << "/" << setw(12) << vifn << setw(8) << "Up" << setw(12) << rxcount << // receive count (not held) setw(12) << 0 << // transmit count XXX notyet setw(10) << (last_active == 0 ? "Never" : whenbuf) << endl; cout.flags(fl);}/** * Invoke Xrl to get peer stats on RIP address and pretty print result. */class GetPeerStats4 : public XrlJobBase {public: GetPeerStats4(XrlJobQueue& jq, const string& ifname, const string& vifname, IPv4 addr, IPv4 peer, bool single_line = false, bool hide_errors = false) : XrlJobBase(jq), _ifn(ifname), _vifn(vifname), _a(addr), _p(peer), _single_line(single_line), _hide_errs(hide_errors) {} bool dispatch() { XrlRipV0p1Client cl(queue().sender()); return cl.send_get_peer_counters(queue().target().c_str(), _ifn, _vifn, _a, _p, callback(this, &GetPeerStats4::cmd_callback) ); }protected: void cmd_callback(const XrlError& xe, const XrlAtomList* descriptions, const XrlAtomList* values, const uint32_t* peer_last_active) { if (xe == XrlError::OKAY()) { if (_single_line) { pretty_print_counters_single_line(*descriptions, *values, *peer_last_active, _p, _ifn, _vifn); } else { print_peer_header(_p, _ifn, _vifn, _a); pretty_print_counters(*descriptions, *values, *peer_last_active); } queue().dispatch_complete(xe, this); } else if (_hide_errs) { // When invoked by GetAllPeerStats4 or GetPortPeerStats4 // we do not report an error. They queried RIP to get the // complete peers list and if we get here the specified // port has been garbage collected at the time it's stats // are queried. queue().dispatch_complete(XrlError::OKAY(), this); } else { queue().dispatch_complete(xe, this); } }protected: string _ifn; string _vifn; IPv4 _a; IPv4 _p; bool _single_line; bool _hide_errs;};/** * Invoke Xrl to get all peers, which we then use to get the counters * for to pretty print result. */class GetAllPeerStats4 : public XrlJobBase {public: GetAllPeerStats4(XrlJobQueue& jq, bool single_line = false) : XrlJobBase(jq), _single_line(single_line) { } bool dispatch() { XrlRipV0p1Client cl(queue().sender()); return cl.send_get_all_peers(queue().target().c_str(), callback(this, &GetAllPeerStats4::cmd_callback) ); }protected: void cmd_callback(const XrlError& xe, const XrlAtomList* peers, const XrlAtomList* ifnames, const XrlAtomList* vifnames, const XrlAtomList* addrs) { if (xe == XrlError::OKAY()) { if (peers->size() == 0) { cout << NO_PEERS << endl; } else { for (size_t i = 0; i < peers->size(); i++) { const IPv4& peer_addr = peers->get(i).ipv4(); const string& ifn = ifnames->get(i).text(); const string& vifn = vifnames->get(i).text(); const IPv4& addr = addrs->get(i).ipv4(); queue().enqueue( new GetPeerStats4(queue(), ifn, vifn, addr, peer_addr, _single_line, true) ); } } } else { cerr << xe.str() << endl; } queue().dispatch_complete(xe, this); } bool _single_line;};/** * Invoke Xrl to get peers on if/vif/addr, which we then use to get * the counters for to pretty print result. */class GetPortPeerStats4 : public XrlJobBase {public: GetPortPeerStats4(XrlJobQueue& jq, const string& ifname, const string& vifname, const IPv4& addr) : XrlJobBase(jq), _ifn(ifname), _vifn(vifname), _a(addr) {} bool dispatch() { XrlRipV0p1Client cl(queue().sender()); return cl.send_get_all_peers(queue().target().c_str(), callback(this, &GetPortPeerStats4::cmd_callback)); }protected: void cmd_callback(const XrlError& xe, const XrlAtomList* peers, const XrlAtomList* ifnames, const XrlAtomList* vifnames, const XrlAtomList* addrs) { if (xe == XrlError::OKAY()) { if (peers->size() == 0) { cout << NO_PEERS_ON_ADDR << _ifn << " " << _vifn << " " << _a.str() << endl; } else { for (size_t i = 0; i < peers->size(); i++) { const IPv4& peer_addr = peers->get(i).ipv4(); const string& ifn = ifnames->get(i).text(); const string& vifn = vifnames->get(i).text(); const IPv4& addr = addrs->get(i).ipv4(); if (ifn == _ifn && vifn == _vifn && _a == addr) { queue().enqueue( new GetPeerStats4(queue(), ifn, vifn, addr, peer_addr,
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -