⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 show_peer_stats.cc

📁 RIP 协议实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- 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,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -