?? ripng_announcer.cc
字號:
// -*- 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/ripng_announcer.cc,v 1.15 2008/07/23 05:11:40 pavlin Exp $"#include "rip/rip_module.h"#include "libxorp/xorp.h"#include "libxorp/xlog.h"#include <vector>#include <fstream>#ifdef HAVE_NET_IF_H#include <net/if.h>#endif#include "libxorp/utils.hh"#include "libxorp/eventloop.hh"#include "libxorp/ipv4.hh"#include "libxorp/ipv6.hh"#include "libcomm/comm_api.h"#include "rip/auth.hh"#include "rip/packet_assembly.hh"#ifdef HAVE_GETOPT_H#include <getopt.h>#endiftemplate <typename A>struct RipRoute { RipRoute() {} RipRoute(const IPNet<A>& a_net, const A& a_nh, uint16_t a_cost, uint16_t a_tag) : net(a_net), nh(a_nh), cost(a_cost), tag(a_tag) {} IPNet<A> net; A nh; uint16_t cost; uint16_t tag;};static boolannounce_routes(XorpFd fd, vector<RipRoute<IPv6> >* my_routes){ PacketAssemblerSpecState<IPv6> sp; ResponsePacketAssembler<IPv6> rpa(sp); vector<RipRoute<IPv6> >& rts = *my_routes; size_t n = my_routes->size(); size_t i = 0; while (i != n) { RipPacket<IPv6> pkt(IPv6::RIP2_ROUTERS(), 521); rpa.packet_start(&pkt); while (i != n && rpa.packet_full() == false) { rpa.packet_add_route(rts[i].net, rts[i].nh, rts[i].cost, rts[i].tag); i++; } list<RipPacket<IPv6>*> auth_packets; if (rpa.packet_finish(auth_packets) != true) break; if (pkt.data_bytes() == 0) break; list<RipPacket<IPv6>*>::iterator iter; for (iter = auth_packets.begin(); iter != auth_packets.end(); ++iter) { RipPacket<IPv6>* auth_pkt = *iter; sockaddr_in6 sai; auth_pkt->address().copy_out(sai); sai.sin6_port = htons(auth_pkt->port()); if (sendto(fd, XORP_BUF_CAST(auth_pkt->data_ptr()), auth_pkt->data_bytes(), 0, reinterpret_cast<const sockaddr*>(&sai), sizeof(sai)) < 0) { cerr << "Write failed: " << strerror(errno) << endl; return false; } else { cout << "Packet sent" << endl; } } delete_pointers_list(auth_packets); } return true;}static voidrip_announce(XorpFd fd, vector<RipRoute<IPv6> >& my_routes){ EventLoop e; XorpTimer t = e.new_periodic_ms(30 * 1000, callback(announce_routes, fd, &my_routes)); announce_routes(fd, &my_routes); while (t.scheduled()) { e.run(); }}static voidoriginate_routes_from_file(const char* file, vector<RipRoute<IPv6> >& my_routes, IPv6 nh, uint16_t cost, uint16_t tag){ ifstream fin(file); if (!fin) { cerr << "Could not open nets file " << file << endl; return; } string l; while (fin >> l) { try { IPv6Net net(l.c_str()); my_routes.push_back(RipRoute<IPv6>(net, nh, cost, tag)); } catch (...) { } } fin.close();}static XorpFdinit_rip_socket(int if_num){#ifdef HAVE_IPV6 in6_addr grp_addr; IPv6::RIP2_ROUTERS().copy_out(grp_addr); XorpFd fd = comm_bind_join_udp6(&grp_addr, if_num, htons(521), COMM_SOCK_ADDR_PORT_REUSE, COMM_SOCK_NONBLOCKING); if (!fd.is_valid()) { cerr << "comm_bind_join_udp6 failed" << endl; } if (comm_set_iface6(fd, if_num) != XORP_OK) { cerr << "comm_set_iface6 failed" << endl; comm_close(fd); fd.clear(); return fd; } if (comm_set_multicast_ttl(fd, 255) != XORP_OK) { cerr << "comm_set_multicast_ttl failed" << endl; comm_close(fd); fd.clear(); return fd; } if (comm_set_loopback(fd, 0) != XORP_OK) { cerr << "comm_set_loopback failed" << endl; comm_close(fd); fd.clear(); return fd; } return fd;#else cerr << "IPv6 support not found during build." << endl; XorpFd fd; return fd; UNUSED(if_num);#endif}static voidshort_usage(){ cerr << "Use -h for more details. " << endl;}static voidusage(){ cerr << xlog_process_name() << " [options] -i <ifname> -o <netsfile>" << endl; cerr << "Options:" << endl; cerr << " -c <cost> specify cost for nets in next <netsfile>." << endl; cerr << " -i <ifname> specify outbound interface." << endl; cerr << " -n <nexthop> specify nexthop for nets in next <netsfile>." << endl; cerr << " -o <netsfile> specify file containing list of nets for announcement." << endl; cerr << " -t <tag> specify tag for nets in next <netsfile>." << endl; cerr << " -h show this information." << endl;}intmain(int argc, char* const argv[]){ // // Initialize and start xlog // xlog_init(argv[0], NULL); xlog_set_verbose(XLOG_VERBOSE_LOW); // Least verbose messages xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH); xlog_add_default_output(); xlog_start(); comm_init(); try { vector<RipRoute<IPv6> > my_routes; const char* if_name = ""; bool do_run = true; // Defaults uint16_t tag = 0; uint16_t cost = 1; IPv6 nh; int if_num = -1; int ch; while ((ch = getopt(argc, argv, "c:n:i:I:o:t:h")) != -1) { switch(ch) { case 'c': cost = atoi(optarg); break; case 'i': if_name = optarg; break; case 'I': if_num = atoi(optarg); break; case 'n': nh = IPv6(optarg); break; case 'o': originate_routes_from_file(optarg, my_routes, nh, cost, tag); break; case 't': tag = atoi(optarg); break; case 'h': default: usage(); do_run = false; } } if (do_run) {#ifdef HAVE_IF_NAMETOINDEX if_num = if_nametoindex(if_name);#endif if (if_num <= 0) { cerr << "Must specify a valid interface name with -i." << endl; short_usage(); } else if (my_routes.empty()) { cerr << "No routes to originate." << endl; short_usage(); } else { XorpFd fd = init_rip_socket(if_num); if (!fd.is_valid()) { rip_announce(fd, my_routes); comm_close(fd); } } } } catch (...) { xorp_print_standard_exceptions(); } comm_exit(); // // Gracefully stop and exit xlog // xlog_stop(); xlog_exit(); return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -