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

📄 click-combine.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * click-combine.cc -- combine several Click configurations at their devices * Eddie Kohler * * Copyright (c) 2000 Massachusetts Institute of Technology * * 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 Click 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 Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include "routert.hh"#include "lexert.hh"#include <click/error.hh>#include <click/clp.h>#include "toolutils.hh"#include "elementmap.hh"#include <click/confparse.hh>#include <click/straccum.hh>#include <click/variableenv.hh>#include <click/driver.hh>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <time.h>#include <unistd.h>#include <sys/stat.h>#include <stdarg.h>#define HELP_OPT		300#define VERSION_OPT		301#define ROUTER_OPT		302#define OUTPUT_OPT		303#define NAME_OPT		304#define LINK_OPT		305#define EXPRESSION_OPT		306#define CONFIG_OPT		307static const Clp_Option options[] = {  { "config", 'c', CONFIG_OPT, 0, 0 },  { "expression", 'e', EXPRESSION_OPT, Clp_ValString, 0 },  { "file", 'f', ROUTER_OPT, Clp_ValString, 0 },  { "help", 0, HELP_OPT, 0, 0 },  { "link", 'l', LINK_OPT, Clp_ValString, 0 },  { "name", 'n', NAME_OPT, Clp_ValString, 0 },  { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 },  { "version", 'v', VERSION_OPT, 0, 0 },};static const char *program_name;static String runclick_prog;voidshort_usage(){  fprintf(stderr, "Usage: %s [OPTION]... [ROUTERFILE]\n\Try '%s --help' for more information.\n",	  program_name, program_name);}voidusage(){  printf("\'Click-combine' combines several Click router configurations at their network\n\devices and writes the combined configuration to the standard output. The\n\combination is controlled by link specifications. The click-uncombine tool can\n\extract components from these combined configurations.\n\\n\Usage: %s [OPTION]... [ROUTERFILE | ROUTERNAME=FILE | LINKSPEC]\n\\n\Options:\n\  -o, --output FILE      Write combined configuration to FILE.\n\  -n, --name NAME        The next router component name is NAME.\n\  -f, --file FILE        Read router component configuration from FILE.\n\  -e, --expression EXPR  Use EXPR as router component configuration.\n\  -l, --link LINKSPEC    Add a link between router components. LINKSPEC has the\n\                         form 'NAME1.COMP1=NAME2.COMP2'. Each NAME is a router\n\                         component name. Each COMP is either an element name or\n\                         a device name (for linking at From/To/PollDevices).\n\  -c, --config           Output config only (not an archive).\n\      --help             Print this message and exit.\n\  -v, --version          Print version number and exit.\n\\n\Report bugs to <click@pdos.lcs.mit.edu>.\n", program_name);}static Vector<String> router_names;static Vector<RouterT *> routers;typedef PortT RouterPortT;	// except that 'port' is the router indexstatic Vector<RouterPortT> links_from;static Vector<RouterPortT> links_to;static Vector<int> link_id;static voidcc_read_router(String name, String &next_name, int &next_number,	       const char *filename, bool file_is_expr, ErrorHandler *errh){  if (name && next_name)    errh->warning("router name specified twice ('%s' and '%s')",		  next_name.c_str(), name.c_str());  else if (name)    next_name = name;  RouterT *r = read_router(filename, file_is_expr, errh);  if (r) {    r->flatten(errh);    if (next_name) {      int span = strspn(next_name.c_str(), "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/@0123456789");      if (span != next_name.length() || strstr(next_name.c_str(), "//") != 0	  || next_name[0] == '/' || next_name.back() == '/')	errh->error("router name '%s' is not a legal Click identifier", next_name.c_str());      router_names.push_back(next_name);    } else      router_names.push_back(String(next_number));    routers.push_back(r);  }  next_name = String();  next_number++;}static ElementT *try_find_device(String devname, String class1, String class2,		int rn, ErrorHandler *errh){  RouterT *r = routers[rn];  String router_name = router_names[rn];  // fix config  {    Vector<String> words;    cp_argvec(devname, words);    devname = words[0];  }  ElementClassT *t1 = ElementClassT::base_type(class1);  ElementClassT *t2 = ElementClassT::base_type(class2);  ElementT *found = 0;  bool duplicate = false;  for (int i = 0; i < r->nelements(); i++) {    ElementT *e = r->element(i);    if (e->live() && (e->type() == t1 || e->type() == t2)) {      Vector<String> words;      cp_argvec(e->configuration(), words);      if (words.size() >= 1 && words[0] == devname) {	// found it, but check for duplication	if (!found && !duplicate)	  found = e;	else if (!duplicate) {	  if (class2)	    errh->error("more than one '%s(%s)' or '%s(%s)' element in router '%s'", class1.c_str(), devname.c_str(), class2.c_str(), devname.c_str(), router_name.c_str());	  else	    errh->error("more than one '%s(%s)' element in router '%s'",			class1.c_str(), devname.c_str(), router_name.c_str());	  duplicate = true;	  found = 0;	}      }    }  }  return found;}static intparse_link(String text, ErrorHandler *errh){  // separate into words  Vector<String> words;  {    StringAccum sa;    const char *s = text.data();    for (int i = 0; i < text.length(); i++)      if (s[i] == '.' || s[i] == '=')	sa << ' ' << s[i] << ' ';      else	sa << s[i];    cp_spacevec(sa.take_string(), words);  }  // check for errors  if (words.size() != 7 || words[1] != "." || words[3] != "="      || words[5] != ".")    return errh->error("bad link definition '%s'", text.c_str());  // find pieces  int router1 = -1, router2 = -1;  for (int i = 0; i < routers.size(); i++) {    if (router_names[i] == words[0])      router1 = i;    if (router_names[i] == words[4])      router2 = i;  }  if (router1 < 0 || router2 < 0) {    if (router1 < 0) errh->error("no router named '%s'", words[0].c_str());    if (router2 < 0) errh->error("no router named '%s'", words[4].c_str());    return -1;  }  ElementT *element1 = routers[router1]->element(words[2]);  if (!element1)    element1 = try_find_device(words[2], "ToDevice", "", router1, errh);  ElementT *element2 = routers[router2]->element(words[6]);  if (!element2)    element2 = try_find_device(words[6], "FromDevice", "PollDevice", router2, errh);  if (!element1 || !element2) {    if (!element1)      errh->error("router '%s' has no element or device named '%s'", words[0].c_str(), words[2].c_str());    if (!element2)      errh->error("router '%s' has no element or device named '%s'", words[4].c_str(), words[6].c_str());    return -1;  }  // check element types  String tn1 = element1->type_name();  String tn2 = element2->type_name();  if (tn1 != "ToDevice") {    errh->warning("router '%s' element '%s' has unexpected class", words[0].c_str(), words[2].c_str());    errh->message("  expected ToDevice, got %s", tn1.c_str());  }  if (tn2 != "FromDevice" && tn2 != "PollDevice") {    errh->warning("router '%s' element '%s' has unexpected class", words[4].c_str(), words[6].c_str());    errh->message("  expected FromDevice or PollDevice, got %s", tn2.c_str());  }  // append link definition  links_from.push_back(RouterPortT(element1, router1));  links_to.push_back(RouterPortT(element2, router2));  return -1;}static voidfrob_nested_routerlink(ElementT *e){  String prefix = e->name().substring(e->name().begin(), find(e->name(), '/') + 1);  assert(prefix.length() > 1 && prefix.back() == '/');  Vector<String> words;  cp_argvec(e->configuration(), words);  for (int i = 0; i < words.size(); i += 2)    words[i] = prefix + words[i];  e->set_configuration(cp_unargvec(words));}static intcombine_links(ErrorHandler *errh){  // check for same name used as both source and destination  int before = errh->nerrors();  for (int i = 1; i < links_from.size(); i++)    for (int j = 0; j < i; j++)      if (links_from[i] == links_to[j] || links_from[j] == links_to[i]) {	const RouterPortT &h = links_from[i];	errh->error("router '%s' element '%s' used as both source and destination", router_names[h.port].c_str(), h.element->name_c_str());      }  if (errh->nerrors() != before)    return -1;  // combine links

⌨️ 快捷键说明

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