📄 lookupiproutelinux.cc
字号:
/* * lookupiproutelinux.{cc,hh} -- element looks up next-hop address in * Linux's routing table * Robert Morris * * Copyright (c) 1999-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. */// N.B. does not work in kernel because of odd handling of _out2dev; should// pay attention to device up/down and do reference counting correctly#include <click/config.h>#include "lookupiproutelinux.hh"#include <click/ipaddress.hh>#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>#ifdef CLICK_LINUXMODULE# include <click/cxxprotect.h>CLICK_CXX_PROTECT# include <linux/netdevice.h># include <linux/ip.h># include <net/route.h>CLICK_CXX_UNPROTECT# include <click/cxxunprotect.h>#endifCLICK_DECLSLinuxIPLookup::LinuxIPLookup(){ add_input(); _nout = 0;#ifdef CLICK_LINUXMODULE _out2dev = 0;#endif}LinuxIPLookup::~LinuxIPLookup(){#ifdef CLICK_LINUXMODULE if(_out2dev) delete[] _out2dev;#endif}intLinuxIPLookup::configure(Vector<String> &conf, ErrorHandler *){ _out2devname = conf; _nout = _out2devname.size(); set_noutputs(_nout + 1); return 0;}intLinuxIPLookup::initialize(ErrorHandler *errh){ if(init_routes(errh) < 0) return(-1); return 0;}#ifdef CLICK_LINUXMODULEintLinuxIPLookup::init_routes(ErrorHandler *errh){ if (_out2dev) delete[] _out2dev; _out2dev = new net_device * [_nout]; _out2dev[0] = 0; int i; for(i = 0; i < _nout; i++){ net_device *dev = dev_get_by_name(_out2devname[i].cc()); if (dev == 0) return errh->error("Cannot find device %s", _out2devname[i].cc()); } return(0);}boolLinuxIPLookup::lookup(IPAddress a, IPAddress &gw, int &ifi){ struct rtable *rt = 0; if (ip_route_output(&rt, a.addr(), /* dst */ 0, /* src */ 0, /* tos */ 0) == 0){ gw = IPAddress(rt->rt_gateway); ifi = -1; net_device *dev = rt->u.dst.dev; int i; for(i = 0; i < _nout; i++){ if(_out2dev[i] == dev) ifi = i; } if(ifi == -1) click_chatter("LinuxIPLookup: unknown dev %x", dev); ip_rt_put(rt); return(true); } return(false);}#else /* !CLICK_LINUXMODULE */intLinuxIPLookup::init_routes(ErrorHandler *errh){ _t.clear(); FILE *fp; char buf[200]; fp = fopen("/proc/net/route", "r"); if(fp == 0) return errh->error("cannot open /proc/net/route"); while(fgets(buf, sizeof(buf), fp)){ char devname[200]; unsigned int dst, gw, mask; // Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT if(sscanf(buf, "%s%x%x%*s%*s%*s%*s%x", devname, &dst, &gw, &mask) == 4){ int i; for(i = 0; i < _nout; i++) if(_out2devname[i] == devname) break; if(i < _nout){ _t.add(dst, mask, gw, i); } else { click_chatter("LinuxIPLookup: no output for dev %s", devname); } } } fclose(fp); return(0);}boolLinuxIPLookup::lookup(IPAddress a, IPAddress &gw, int &ifi){ return _t.lookup(a, gw, ifi);}#endif /* CLICK_LINUXMODULE */voidLinuxIPLookup::push(int, Packet *p){ IPAddress a = p->dst_ip_anno(); IPAddress gw; int ifi = -1; if (lookup(a, gw, ifi) == true){ click_chatter("routed %x to %x %d", a.addr(), gw.addr(), ifi); if(gw.addr() != 0) p->set_dst_ip_anno(gw); output(ifi).push(p); } else { click_chatter("LinuxIPLookup: no gw for %x", a.addr()); output(_nout).push(p); }}CLICK_ENDDECLSELEMENT_REQUIRES(userlevel)EXPORT_ELEMENT(LinuxIPLookup)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -