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

📄 print_lsas.cc

📁 xorp源码hg
💻 CC
字号:
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// vim:set sts=4 ts=8:// Copyright (c) 2001-2007 International Computer Science Institute//// 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/ospf/tools/print_lsas.cc,v 1.22 2007/02/16 22:46:45 pavlin Exp $"// Get LSAs (in raw binary) from OSPF and print them.// #define DEBUG_LOGGING// #define DEBUG_PRINT_FUNCTION_NAME#include "ospf/ospf_module.h"#include "libxorp/xorp.h"#include "libxorp/debug.h"#include "libxorp/xlog.h"#include "libxorp/ipv4.hh"#include "libxorp/ipv6.hh"#include "libxorp/service.hh"#include "libxorp/status_codes.h"#include "libxorp/eventloop.hh"#include "libxorp/tlv.hh"#include <set>#include <list>#ifdef HAVE_GETOPT_H#include <getopt.h>#endif#ifdef HAVE_SYS_UTSNAME_H#include <sys/utsname.h>#endif#include "libxipc/xrl_std_router.hh"#include "xrl/interfaces/ospfv2_xif.hh"#include "xrl/interfaces/ospfv3_xif.hh"#include "ospf/ospf.hh"#include "ospf/test_common.hh"/** * return OS name. */stringhost_os(){#ifdef	HAVE_UNAME    struct utsname name;    if (0 != uname(&name)) {	return HOST_OS_NAME;    }    return name.sysname;#endif    return HOST_OS_NAME;}/** * Get the list of configured areas */class GetAreaList {public:    GetAreaList(XrlStdRouter& xrl_router, OspfTypes::Version version)	: _xrl_router(xrl_router), _version(version),	  _done(false), _fail(false)    {    }    void add(IPv4 area) {	_areas.push_back(area);    }    void start() {	switch(_version) {	case OspfTypes::V2: {	    XrlOspfv2V0p1Client ospfv2(&_xrl_router);	    ospfv2.send_get_area_list(xrl_target(_version),				      callback(this, &GetAreaList::response));	}	    break;	case OspfTypes::V3: {	    XrlOspfv3V0p1Client ospfv3(&_xrl_router);	    ospfv3.send_get_area_list(xrl_target(_version),				      callback(this, &GetAreaList::response));	}	    break;	}    }    bool busy() {	return !_done;    }    bool fail() {	return _fail;    }    list<IPv4>& get() {	return _areas;    }private:    void response(const XrlError& error, const XrlAtomList *atomlist) {	_done = true;	if (XrlError::OKAY() != error) {	    XLOG_WARNING("Attempt to get lsa failed");	    _fail = true;	    return;	}	const size_t size = atomlist->size();	for (size_t i = 0; i < size; i++)	    _areas.push_back(IPv4(htonl(atomlist->get(i).uint32())));	    }private:    XrlStdRouter &_xrl_router;    OspfTypes::Version _version;    bool _done;    bool _fail;    list<IPv4> _areas;};/** * Fetch all the LSAs for one area. */class FetchDB {public:    FetchDB(XrlStdRouter& xrl_router, OspfTypes::Version version, IPv4 area)	: _xrl_router(xrl_router), _version(version), _lsa_decoder(version),	  _done(false), _fail(false), _area(area), _index(0)    {	initialise_lsa_decoder(version, _lsa_decoder);    }    void start() {	switch(_version) {	case OspfTypes::V2: {	    XrlOspfv2V0p1Client ospfv2(&_xrl_router);	    ospfv2.send_get_lsa(xrl_target(_version), _area, _index,				callback(this, &FetchDB::response));	}	    break;	case OspfTypes::V3: {	    XrlOspfv3V0p1Client ospfv3(&_xrl_router);	    ospfv3.send_get_lsa(xrl_target(_version), _area, _index,				callback(this, &FetchDB::response));	}	    break;	}    }    bool busy() {	return !_done;    }    bool fail() {	return _fail;    }    list<Lsa::LsaRef>& get_lsas() {	return _lsas;    }private:    void response(const XrlError& error,		  const bool *valid,		  const bool *toohigh,		  const bool *self,		  const vector<uint8_t>* lsa) {	if (XrlError::OKAY() != error) {	    XLOG_WARNING("Attempt to get lsa failed");	    _done = true;	    _fail = true;	    return;	}	if (*valid) {	    size_t len = lsa->size();	    Lsa::LsaRef lsar = _lsa_decoder.		decode(const_cast<uint8_t *>(&(*lsa)[0]), len);	    lsar->set_self_originating(*self);	    _lsas.push_back(lsar);	}	if (*toohigh) {	    _done = true;	    return;	}	_index++;	start();    }private:    XrlStdRouter &_xrl_router;    OspfTypes::Version _version;    LsaDecoder _lsa_decoder;    bool _done;    bool _fail;    const IPv4 _area;    uint32_t _index;    list<Lsa::LsaRef> _lsas;};/** * Filter LSAs. If the filter is empty everything is accepted, if the * filter contains types then only an LSA matching a type is passed. */class FilterLSA {public:    void add(uint16_t type) {	_filter.push_back(type);    }    bool accept(uint16_t type) {	if (_filter.empty())	    return true;	if (_filter.end() != find(_filter.begin(), _filter.end(), type))	    return true;		return false;    }private:    list<uint16_t> _filter;};/** * The base class that needs to be implemented by all print routines. */ class Output {public:    Output(OspfTypes::Version version, FilterLSA& filter)	: _version(version), _filter(filter)    {}    virtual ~Output()    {}    virtual bool begin() {	return true;    }    void print_area(string area) {	printf("   OSPF link state database, Area %s\n", area.c_str());    }    virtual bool begin_area(string area) {	_area = area;	return true;    }    virtual bool print(Lsa::LsaRef lsar) {	printf("%s\n", lsar->str().c_str());	return true;    }    virtual bool end_area(string /*area*/) {	_area = "";	return true;    }    virtual bool end() {	return true;    }protected:    OspfTypes::Version _version;    FilterLSA& _filter;    string _area;};class Brief : public Output {public:    Brief(OspfTypes::Version version, FilterLSA& filter)	: Output(version, filter)    {}    bool begin_area(string area) {	print_area(area);	switch(_version) {	case OspfTypes::V2:	    printf(" Type       ID               Adv "		   "Rtr           Seq      Age  Opt  Cksum  Len\n");	    break;	case OspfTypes::V3:	    printf(" Type       ID               Adv "		   "Rtr           Seq         Age  Cksum  Len\n");	    break;	}	return true;    }    bool print(Lsa::LsaRef lsar) {	switch(_version) {	case OspfTypes::V2:	    printf("%-8s", lsar->name());	    break;	case OspfTypes::V3:	    printf("%-11s", lsar->name());	    break;	}	printf("%c", lsar->get_self_originating() ? '*' : ' ');	Lsa_header& header = lsar->get_header();	printf("%-17s", pr_id(header.get_link_state_id()).c_str());	printf("%-17s", pr_id(header.get_advertising_router()).c_str());	printf("%-#12x", header.get_ls_sequence_number());	printf("%4d", header.get_ls_age());	switch(_version) {	case OspfTypes::V2:	    printf("  %-#5x", header.get_options());	    break;	case OspfTypes::V3:	    printf("  ");	    break;	}	printf("%-#7x", header.get_ls_checksum());	printf("%3d", header.get_length());	printf("\n");	return true;    }};class Detail : public Output {public:    Detail(OspfTypes::Version version, FilterLSA& filter)	: Output(version, filter)    {}    bool begin_area(string area) {	print_area(area);		return true;    }};class Summary : public Output {public:    Summary(OspfTypes::Version version, FilterLSA& filter)	: Output(version, filter), _externals(0)    {}    bool begin_area(string area) {	printf("Area %s\n", area.c_str());	_summary.clear();	return true;    }    bool print(Lsa::LsaRef lsar) {	uint16_t type = lsar->get_ls_type();	if (0 == _summary.count(type)) {	    _summary[type] = 1;	} else {	    _summary[type] = _summary[type] + 1;	}		return true;    }    bool end_area(string /*area*/) {	LsaDecoder lsa_decoder(_version);	initialise_lsa_decoder(_version, lsa_decoder);	map<uint16_t, uint32_t>::const_iterator i;	for (i = _summary.begin(); i != _summary.end(); i++) {	    uint16_t type = (*i).first;	    uint32_t count = (*i).second;	    if (lsa_decoder.external(type)) {		if (0 == _externals)		    _externals = count;	    } else {		printf("%5d %s LSAs\n", count, lsa_decoder.name(type));	    }	}	return true;    }    bool end() {	if (_filter.accept(ASExternalLsa(_version).get_ls_type())) {	    printf("Externals:\n");	    if (0 != _externals)		printf("%5d External LSAs\n", _externals);	}	return true;    }private:    uint32_t _externals;	// Number of AS-External-LSAs.    map<uint16_t, uint32_t> _summary;};class Save : public Output {public:    Save(OspfTypes::Version version, FilterLSA& filter, string& fname)	: Output(version, filter), _fname(fname)    {}    bool begin() {	if (!_tlv.open(_fname, false /* write */)) {	    XLOG_ERROR("Unable to open %s", _fname.c_str());	    return false;	}	// 1) Version	vector<uint8_t> data;	data.resize(sizeof(uint32_t));	_tlv.put32(data, 0, TLV_VERSION);	if (!_tlv.write(TLV_CURRENT_VERSION, data))	    return false;	// 2) System info	string host = host_os();	uint32_t len = host.size();	data.resize(len);	memcpy(&data[0], host.c_str(), len);	if (!_tlv.write(TLV_SYSTEM_INFO, data))	    return false;	// 3) OSPF Version	data.resize(sizeof(uint32_t));	_tlv.put32(data, 0, _version);	if (!_tlv.write(TLV_OSPF_VERSION, data))	    return false;	return true;    }    bool begin_area(string area) {	vector<uint8_t> data;	data.resize(sizeof(uint32_t));	_tlv.put32(data, 0, ntohl(IPv4(area.c_str()).addr()));	return _tlv.write(TLV_AREA, data);    }    bool print(Lsa::LsaRef lsar) {	size_t len;	uint8_t *ptr = lsar->lsa(len);	vector<uint8_t> data;	data.resize(len);	memcpy(&data[0], ptr, len);	return _tlv.write(TLV_LSA, data);    }    bool end() {	return _tlv.close();    }private:    string _fname;    Tlv _tlv;};enum Pstyle {    BRIEF,    DETAIL,    SUMMARY,    SAVE};intusage(const char *myname){    fprintf(stderr,	    "usage: %s [-a area] [-f type] [-s] [-b] [-d] [-S fname]\n",	    myname);    return -1;}int main(int argc, char **argv){    XorpUnexpectedHandler x(xorp_unexpected_handler);    //    // Initialize and start xlog    //    xlog_init(argv[0], NULL);    xlog_set_verbose(XLOG_VERBOSE_LOW);		// Least verbose messages    // XXX: verbosity of the error messages temporary increased    xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH);    xlog_add_default_output();    xlog_start();    OspfTypes::Version version = OspfTypes::V2;    Pstyle pstyle = BRIEF;    FilterLSA filter;    string area;    string fname;    int c;    while ((c = getopt(argc, argv, "23a:f:sbdS:")) != -1) {	switch (c) {	case '2':	    version = OspfTypes::V2;	    break;	case '3':	    version = OspfTypes::V3;	    break;	case 'a':	    area = optarg;	    break;	case 'f': {	    char *endptr;	    uint32_t number = strtoul(optarg, &endptr, 0);	    if (0 != *endptr) {		XLOG_ERROR("<%s> is not a number", optarg);		return -1;	    }	    filter.add(number);	}	    break;	case 's':	    pstyle = SUMMARY;	    break;	case 'b':	    pstyle = BRIEF;	    break;	case 'd':	    pstyle = DETAIL;	    break;	case 'S':	    pstyle = SAVE;	    fname = optarg;	    break;	default:	    return usage(argv[0]);	}    }    Output *output = 0;    switch (pstyle) {    case BRIEF:	output = new Brief(version, filter);	break;    case DETAIL:	output = new Detail(version, filter);	break;    case SUMMARY:	output = new Summary(version, filter);	break;    case SAVE:	output = new Save(version, filter, fname);	break;    }    try {	EventLoop eventloop;	XrlStdRouter xrl_router(eventloop, "print_lsas");	debug_msg("Waiting for router");	xrl_router.finalize();	wait_until_xrl_router_is_ready(eventloop, xrl_router);	debug_msg("\n");	GetAreaList get_area_list(xrl_router, version);	if (area.empty()) {	    get_area_list.start();	    while(get_area_list.busy())		eventloop.run();	    if (get_area_list.fail()) {		XLOG_ERROR("Failed to get area list");		return -1;	    }	} else {	    get_area_list.add(IPv4(area.c_str()));	}	if (!output->begin())	    return -1;	list<IPv4>& area_list = get_area_list.get();	list<IPv4>::const_iterator i;	for (i = area_list.begin(); i != area_list.end(); i++) {	    FetchDB fetchdb(xrl_router, version, *i);	    fetchdb.start();	    while(fetchdb.busy())		eventloop.run();	    if (fetchdb.fail()) {		XLOG_ERROR("Failed to fetch area %s", i->str().c_str());		return -1;	    }	    if (!output->begin_area(i->str()))		return -1;	    list<Lsa::LsaRef>& lsas = fetchdb.get_lsas();	    list<Lsa::LsaRef>::const_iterator j;	    for (j = lsas.begin(); j != lsas.end(); j++) {		uint16_t type = (*j)->get_ls_type();		if (!filter.accept(type))		    continue;		if (!output->print(*j))		    return -1;	    }	    if (!output->end_area(i->str()))		return -1;	}	if (!output->end())	    return -1;	delete output;    } catch (...) {	xorp_catch_standard_exceptions();    }    xlog_stop();    xlog_exit();    return 0;}

⌨️ 快捷键说明

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