📄 anydevice.cc
字号:
/* * anydevice.{cc,hh} -- support BSD device interaction * Eddie Kohler, Nickolai Zeldovich * * Copyright (c) 2000, 2001 Massachusetts Institute of Technology * Copyright (c) 2000 Mazu Networks, 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 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 <click/glue.hh>#include "anydevice.hh"#include <click/confparse.hh>#include <click/error.hh>#include <click/cxxprotect.h>CLICK_CXX_PROTECT#include <sys/lock.h>CLICK_CXX_UNPROTECT#include <click/cxxunprotect.h>AnyDevice::AnyDevice() : _dev(0), _task(this), _idles(0), _next(0){}AnyDevice::~AnyDevice(){}static voidlock_kernel(){ // XXX not yet in BSD}static voidunlock_kernel(){ // XXX not yet in BSD}intAnyDevice::find_device(bool allow_nonexistent, AnyDeviceMap *adm, ErrorHandler *errh){ _dev = ifunit((char *) _devname.cc()); if (!_dev) _dev = find_device_by_ether_address(_devname, this); if (!_dev) { if (!allow_nonexistent) return errh->error("unknown device `%s'", _devname.cc()); else errh->warning("unknown device `%s'", _devname.cc()); } if (_dev && !(_dev->if_flags & IFF_UP)) { errh->warning("device `%s' is down", _devname.cc()); _dev = 0; } return 0;}voidAnyDevice::clear_device(AnyDeviceMap *adm){#if 0 /* MARKO XXX */ if (_dev && _promisc) dev_set_promiscuity(_dev, -1);#endif if (adm) adm->remove(this); _dev = 0;}AnyTaskDevice::AnyTaskDevice() : _task(this), _idles(0){}voidAnyDeviceMap::initialize(){ _unknown_map = 0; for (int i = 0; i < MAP_SIZE; i++) _map[i] = 0;}voidAnyDeviceMap::insert(AnyDevice *d){ // lock whole kernel when manipulating device map lock_kernel(); int ifi = d->ifindex(); AnyDevice **head; if (ifi < 0) head = &_unknown_map; else head = &_map[ifi % MAP_SIZE]; // put new devices first on the list d->set_next(*head); *head = d; unlock_kernel();}voidAnyDeviceMap::remove(AnyDevice *d){ lock_kernel(); int ifi = d->ifindex(); AnyDevice **head = (ifi >= 0 ? &_map[ifi % MAP_SIZE] : &_unknown_map); AnyDevice *prev = 0; AnyDevice *trav = *head; while (trav && trav != d) { prev = trav; trav = trav->next(); } if (trav) { if (prev) prev->set_next(trav->next()); else *head = trav->next(); } unlock_kernel();}AnyDevice *AnyDeviceMap::lookup_unknown(struct ifnet *dev){ // make sure device is valid if (dev == NULL) return NULL; // look first by device names String dev_name = dev->if_name; for (AnyDevice *d = _unknown_map; d; d = d->next()) if (d->devname() == dev_name) return d;#if 0 /* XXX this is slightly more complicated in BSD */ // then by Ethernet addresses if (dev->if_type == IFT_ETHER) { unsigned char en[6]; for (AnyDevice *d = _unknown_map; d; d = d->next()) if (cp_ethernet_address(d->devname(), en, d)) if (memcmp(en, dev->dev_addr, 6) == 0) return d; }#endif return 0;}struct ifnet *find_device_by_ether_address(const String &name, Element *context){#if 0 /* XXX slightly more difficult in BSD */ unsigned char en[6]; if (!cp_ethernet_address(name, en, context)) return 0; for (struct ifnet *dev = dev_base; dev; dev = dev->next) if (dev->type == ARPHRD_ETHER && memcmp(en, dev->dev_addr, 6) == 0) return dev;#endif return 0;}ELEMENT_REQUIRES(bsdmodule)ELEMENT_PROVIDES(AnyDevice)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -