xorp

parser.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2011 XORP, Inc and Others
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License, Version 2, June
00008 // 1991 as published by the Free Software Foundation. Redistribution
00009 // and/or modification of this program under the terms of any other
00010 // version of the GNU General Public License is not permitted.
00011 // 
00012 // This program is distributed in the hope that it will be useful, but
00013 // WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00015 // see the GNU General Public License, Version 2, a copy of which can be
00016 // found in the XORP LICENSE.gpl file.
00017 // 
00018 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00019 // http://xorp.net
00020 
00021 // $XORP: xorp/rib/parser.hh,v 1.24 2008/10/02 21:58:10 bms Exp $
00022 
00023 #ifndef __RIB_PARSER_HH__
00024 #define __RIB_PARSER_HH__
00025 
00026 
00027 
00028 
00029 
00030 #include "libxorp/xorp.h"
00031 #include "libxorp/ipv4.hh"
00032 #include "libxorp/ipv4net.hh"
00033 
00034 #include "rib.hh"
00035 
00036 
00037 class Command;
00038 
00042 class Datum {
00043 public:
00044     virtual ~Datum() {}
00045 };
00046 
00047 class Uint32Datum : public Datum {
00048 public:
00049     Uint32Datum(const string& s) {
00050     _n = 0;
00051     for (size_t i = 0; i < s.size(); i++) {
00052         if (!xorp_isdigit(s[i]))
00053         xorp_throw0(InvalidString);
00054         _n *= 10;
00055         _n += s[i] - '0';
00056     }
00057     }
00058     const uint32_t& get() const { return _n; }
00059 
00060 protected:
00061     uint32_t _n;
00062 };
00063 
00064 class StringDatum : public Datum {
00065 public:
00066     StringDatum(const string& s) : _s(s) {}
00067     const string& get() const { return _s; }
00068 
00069 protected:
00070     const string _s;
00071 };
00072 
00073 class IPv4Datum : public Datum {
00074 public:
00075     IPv4Datum(const string& s) : _ipv4(s.c_str()) {}
00076     const IPv4& get() const { return _ipv4; }
00077 
00078 protected:
00079     const IPv4 _ipv4;
00080 };
00081 
00082 class IPv4NetDatum : public Datum {
00083 public:
00084     IPv4NetDatum(const string& s) : _ipv4net(s.c_str()) {}
00085     const IPv4Net& get() const { return _ipv4net; }
00086 
00087 protected:
00088     const IPv4Net _ipv4net;
00089 };
00090 
00094 class ArgumentParser {
00095 public:
00096     ArgumentParser(const string& parser_name) : _argname(parser_name) {}
00097     virtual ~ArgumentParser() {}
00098     virtual Datum* parse(const string& s) const = 0;
00099     const string& name() const { return _argname;}
00100 
00101 private:
00102     const string _argname;
00103 };
00104 
00105 class Uint32ArgumentParser : public ArgumentParser {
00106 public:
00107     Uint32ArgumentParser() : ArgumentParser("~Uint32") {}
00108     Datum* parse(const string& str) const; 
00109 };
00110 
00111 class StringArgumentParser : public ArgumentParser {
00112 public:
00113     StringArgumentParser() : ArgumentParser("~String") {}
00114     Datum* parse(const string& str) const;
00115 };
00116 
00117 class IPv4ArgumentParser : public ArgumentParser {
00118 public:
00119     IPv4ArgumentParser() : ArgumentParser("~IPv4") {}
00120     Datum* parse(const string& str) const;
00121 };
00122 
00123 class IPv4NetArgumentParser : public ArgumentParser {
00124 public:
00125     IPv4NetArgumentParser() : ArgumentParser("~IPv4Net") {}
00126     Datum* parse(const string& str) const;
00127 };
00128 
00129 class Parser {
00130 public:
00131     Parser();
00132     ~Parser();
00133     int parse(const string& str) const;
00134     bool add_command(Command* command);
00135     bool add_argtype(ArgumentParser* arg); 
00136 
00137 private:
00138     ArgumentParser* get_argument_parser(const string& name) const;
00139     int split_into_words(const string& str, vector <string>& words) const;
00140 
00141     char _separator;
00142     map<string, Command* > _templates;
00143     map<string, ArgumentParser* > _argtypes;
00144 };
00145 
00146 class Parse_error {
00147 public:
00148     Parse_error() : _str("generic error") {}
00149     Parse_error(const string& s) : _str(s) {}
00150     const string& str() const { return _str; }
00151 
00152 private:
00153     string _str;
00154 };
00155 
00159 class DatumVariableBinding {
00160 public:
00161     virtual ~DatumVariableBinding() {}
00162     virtual void transfer(Datum* d) throw (Parse_error) = 0;
00163 };
00164 
00165 class DatumUint32Binding : public DatumVariableBinding {
00166 public:
00167     virtual ~DatumUint32Binding() {}
00168     DatumUint32Binding(uint32_t& i) : _i(i) {}
00169     void transfer(Datum* d) throw (Parse_error) {
00170     Uint32Datum* id = dynamic_cast<Uint32Datum *>(d);
00171     if (NULL == id)
00172         throw Parse_error("Wrong type ? int decoding failed");
00173     _i = id->get();
00174     }
00175 
00176 private:
00177     uint32_t& _i;
00178 };
00179 
00180 class DatumStringBinding : public DatumVariableBinding {
00181 public:
00182     virtual ~DatumStringBinding() {}
00183     DatumStringBinding(string& s) : _s(s) {}
00184     void transfer(Datum* d) throw (Parse_error) {
00185     StringDatum* id = dynamic_cast<StringDatum *>(d);
00186     if (NULL == id)
00187         throw Parse_error("Wrong type ? string decoding failed");
00188     _s = id->get();
00189     }
00190 
00191 private:
00192     string& _s;
00193 };
00194 
00195 class DatumIPv4Binding : public DatumVariableBinding {
00196 public:
00197     virtual ~DatumIPv4Binding() {}
00198     DatumIPv4Binding(IPv4& ipv4) : _ipv4(ipv4) {}
00199     void transfer(Datum* d) throw (Parse_error) {
00200     IPv4Datum* id = dynamic_cast<IPv4Datum *>(d);
00201     if (NULL == id)
00202         throw Parse_error("Wrong type ? ipv4 decoding failed");
00203     _ipv4 = id->get();
00204     }
00205 
00206 private:
00207     IPv4& _ipv4;
00208 };
00209 
00210 class DatumIPv4NetBinding : public DatumVariableBinding {
00211 public:
00212     virtual ~DatumIPv4NetBinding() {}
00213     DatumIPv4NetBinding(IPv4Net& ipv4net) : _ipv4net(ipv4net) {}
00214     void transfer(Datum* d) throw (Parse_error) {
00215     IPv4NetDatum* id = dynamic_cast<IPv4NetDatum *>(d);
00216     if (NULL == id)
00217         throw Parse_error("Wrong type ? ipv4 decoding failed");
00218     _ipv4net = id->get();
00219     }
00220 private:
00221     IPv4Net& _ipv4net;
00222 };
00223 
00224 class Command {
00225 public:
00226     Command(const string& cmd_syntax, int nargs) : 
00227     _syntax(cmd_syntax), _nargs(nargs), _last_arg(-1) { check_syntax(); }
00228     virtual ~Command();
00229     virtual int execute() = 0;
00230     const string& syntax() const { return _syntax; }
00231 
00232     void set_arg(int argnum, Datum* d) throw (Parse_error);
00233     int num_args() const { return _nargs; }
00234 
00235 protected:
00236     //
00237     // Abort if number of args in syntax string does not matches
00238     //  number given. 
00239     //
00240     void check_syntax();
00241 
00242     void set_last_arg(int n) { _last_arg = n; }
00243 
00244     //
00245     // Bind positional argument to Datum type so when argument n arrives, it
00246     // can be decoded into a member variable.
00247     //
00248     void bind(int n, DatumVariableBinding* b);
00249     void bind_uint32(int n, uint32_t& i);
00250     void bind_string(int n, string& s);
00251     void bind_ipv4(int n, IPv4& addr);
00252     void bind_ipv4net(int n, IPv4Net& net);
00253 
00254     DatumVariableBinding* find_binding(int n);
00255 
00256 protected:
00257     const string _syntax;
00258     const int    _nargs;    // Number of args before execute can be called
00259     int      _last_arg; // Last argument added
00260 
00261     map<int, DatumVariableBinding *> _bindings;
00262 };
00263 
00264 class TableOriginCommand : public Command {
00265 public:
00266     TableOriginCommand() : Command("table origin ~String ~Uint32", 2) {
00267     bind_string(0, _tablename);
00268     bind_uint32(1, _admin_distance);
00269     }
00270     virtual int execute() = 0;
00271 
00272 protected:
00273     string  _tablename;
00274     uint32_t    _admin_distance;
00275 };
00276 
00277 class TableMergedCommand : public Command {
00278 public:
00279     TableMergedCommand() : Command("table merged ~String ~String ~String", 3) {
00280     bind_string(0, _tablename);
00281     bind_string(1, _t1);
00282     bind_string(2, _t2);
00283     }
00284     virtual int execute() = 0;
00285 
00286 protected:
00287     string _tablename;
00288     string _t1;
00289     string _t2;
00290 };
00291 
00292 class TableExtIntCommand : public Command {
00293 public:
00294     TableExtIntCommand() : Command("table extint ~String ~String ~String", 3) {
00295     bind_string(0, _tablename);
00296     bind_string(1, _t1);
00297     bind_string(2, _t2);
00298     }
00299     virtual int execute() = 0;
00300 
00301 protected:
00302     string _tablename;
00303     string _t1;
00304     string _t2;
00305 };
00306 
00307 class RouteAddCommand : public Command {
00308 public:
00309     RouteAddCommand() : Command("route add ~String ~IPv4Net ~IPv4 ~Uint32", 4) {
00310     bind_string(0, _tablename);
00311     bind_ipv4net(1, _net);
00312     bind_ipv4(2, _nexthop);
00313     bind_uint32(3, _metric);
00314     }
00315     virtual int execute() = 0;
00316 
00317 protected:
00318     string  _tablename;
00319     IPv4Net _net;
00320     IPv4    _nexthop;
00321     uint32_t    _metric;
00322 };
00323 
00324 class RouteVifAddCommand : public Command {
00325 public:
00326     RouteVifAddCommand() : Command("route vifadd ~String ~IPv4Net ~String ~IPv4 ~Uint32", 5) {
00327     bind_string(0, _tablename);
00328     bind_ipv4net(1, _net);
00329     bind_string(2, _vifname);
00330     bind_ipv4(3, _nexthop);
00331     bind_uint32(4, _metric);
00332     }
00333     virtual int execute() = 0;
00334 
00335 protected:
00336     string  _tablename;
00337     IPv4Net _net;
00338     string  _vifname;
00339     IPv4    _nexthop;
00340     uint32_t    _metric;
00341 };
00342 
00343 class RouteDeleteCommand : public Command {
00344 public:
00345     RouteDeleteCommand() : Command("route delete ~String ~IPv4Net", 2) {
00346     bind_string(0, _tablename);
00347     bind_ipv4net(1, _net);
00348     }
00349     virtual int execute() = 0;
00350 
00351 protected:
00352     string  _tablename;
00353     IPv4Net _net;
00354 };
00355 
00356 class RouteVerifyCommand : public Command {
00357 public:
00358     RouteVerifyCommand() : Command(
00359 "route verify ~String ~IPv4 ~String ~IPv4 ~Uint32", 5)
00360     {
00361     bind_string(0, _type);
00362     bind_ipv4(1, _lookupaddr);
00363     bind_string(2, _ifname);
00364     bind_ipv4(3, _nexthop);
00365     bind_uint32(4, _metric);
00366     }
00367     virtual int execute() = 0;
00368 
00369 protected:
00370     string  _type;          // Type of result expected.
00371     string  _ifname;
00372     IPv4    _lookupaddr;
00373     IPv4    _nexthop;
00374     uint32_t    _metric;
00375 };
00376 
00377 class DiscardVifCommand : public Command {
00378 public:
00379     DiscardVifCommand() : Command("vif Discard ~String ~IPv4 ~Uint32", 3) {
00380     bind_string(0, _ifname);
00381     bind_ipv4(1, _addr);
00382     bind_uint32(2, _prefix_len);
00383     }
00384     virtual int execute() = 0;
00385 
00386 protected:
00387     string  _ifname;
00388     IPv4    _addr;
00389     uint32_t    _prefix_len;
00390 };
00391 
00392 class UnreachableVifCommand : public Command {
00393 public:
00394     UnreachableVifCommand() : Command(
00395     "vif Unreachable ~String ~IPv4 ~Uint32", 3) {
00396     bind_string(0, _ifname);
00397     bind_ipv4(1, _addr);
00398     bind_uint32(2, _prefix_len);
00399     }
00400     virtual int execute() = 0;
00401 
00402 protected:
00403     string  _ifname;
00404     IPv4    _addr;
00405     uint32_t    _prefix_len;
00406 };
00407 
00408 class ManagementVifCommand : public Command {
00409 public:
00410     ManagementVifCommand() : Command(
00411     "vif Management ~String ~IPv4 ~Uint32", 3) {
00412     bind_string(0, _ifname);
00413     bind_ipv4(1, _addr);
00414     bind_uint32(2, _prefix_len);
00415     }
00416     virtual int execute() = 0;
00417 
00418 protected:
00419     string  _ifname;
00420     IPv4    _addr;
00421     uint32_t    _prefix_len;
00422 };
00423 
00424 class EtherVifCommand : public Command {
00425 public:
00426     EtherVifCommand() : Command("vif Ethernet ~String ~IPv4 ~Uint32", 3) {
00427     bind_string(0, _ifname);
00428     bind_ipv4(1, _addr);
00429     bind_uint32(2, _prefix_len);
00430     }
00431     virtual int execute() = 0;
00432 
00433 protected:
00434     string  _ifname;
00435     IPv4    _addr;
00436     uint32_t    _prefix_len;
00437 };
00438 
00439 class LoopbackVifCommand : public Command {
00440 public:
00441     LoopbackVifCommand() : Command("vif Loopback ~String ~IPv4 ~Uint32", 3) {
00442     bind_string(0, _ifname);
00443     bind_ipv4(1, _addr);
00444     bind_uint32(2, _prefix_len);
00445     }
00446     virtual int execute() = 0;
00447 
00448 protected:
00449     string  _ifname;
00450     IPv4    _addr;
00451     uint32_t    _prefix_len;
00452 };
00453 
00454 class RedistEnableCommand : public Command {
00455 public:
00456     RedistEnableCommand() : Command("redistribute enable ~String ~String", 2) {
00457     bind_string(0, _from_table);
00458     bind_string(1, _to_table);
00459     }
00460     virtual int execute() = 0;
00461 
00462 protected:
00463     string _from_table;
00464     string _to_table;
00465 };
00466 
00467 class RedistDisableCommand : public Command {
00468 public:
00469     RedistDisableCommand() : Command("redistribute disable ~String ~String", 2)
00470     {
00471     bind_string(0, _from_table);
00472     bind_string(1, _to_table);
00473     }
00474     virtual int execute() = 0;
00475 
00476 protected:
00477     string _from_table;
00478     string _to_table;
00479 };
00480 
00481 class AddIGPTableCommand : public Command {
00482 public:
00483     AddIGPTableCommand() : Command("add_igp_table ~String", 1) {
00484     bind_string(0, _tablename);
00485     }
00486     virtual int execute() = 0;
00487 
00488 protected:
00489     string _tablename;
00490 };
00491 
00492 class DeleteIGPTableCommand : public Command {
00493 public:
00494     DeleteIGPTableCommand() : Command("delete_igp_table ~String", 1) {
00495     bind_string(0, _tablename);
00496     }
00497     virtual int execute() = 0;
00498 
00499 protected:
00500     string _tablename;
00501 };
00502 
00503 class AddEGPTableCommand : public Command {
00504 public:
00505     AddEGPTableCommand() : Command("add_egp_table ~String", 1) {
00506     bind_string(0, _tablename);
00507     }
00508     virtual int execute() = 0;
00509 
00510 protected:
00511     string _tablename;
00512 };
00513 
00514 class DeleteEGPTableCommand : public Command {
00515 public:
00516     DeleteEGPTableCommand() : Command("delete_egp_table ~String", 1) {
00517     bind_string(0, _tablename);
00518     }
00519     virtual int execute() = 0;
00520 
00521 protected:
00522     string _tablename;
00523 };
00524 
00525 #endif // __RIB_PARSER_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations