📄 etherswitch.cc
字号:
/* * etherswitch.{cc,hh} -- learning, forwarding Ethernet bridge * John Jannotti * * 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. */#include <click/config.h>#include "etherswitch.hh"#include <clicknet/ether.h>#include <click/etheraddress.hh>#include <click/glue.hh>#include <click/bitvector.hh>CLICK_DECLSEtherSwitch::EtherSwitch() : _table(0), _timeout(300){}EtherSwitch::~EtherSwitch(){ for (Table::iterator iter = _table.begin(); iter; iter++) delete iter.value(); _table.clear();}EtherSwitch::AddrInfo::AddrInfo(int p, const timeval& s) : port(p), stamp(s){}voidEtherSwitch::notify_ninputs(int n){ set_ninputs(n); set_noutputs(n);}voidEtherSwitch::broadcast(int source, Packet *p){ int n = noutputs(); int sent = 0; for (int i = 0; i < n; i++) if (i != source) { Packet *pp = (sent < n - 2 ? p->clone() : p); output(i).push(pp); sent++; }}voidEtherSwitch::push(int source, Packet *p){ click_ether* e = (click_ether*) p->data(); timeval t; click_gettimeofday(&t); EtherAddress src = EtherAddress(e->ether_shost); EtherAddress dst = EtherAddress(e->ether_dhost);#if 0 click_chatter("Got a packet %p on %d at %d.%06d with src %s and dst %s", p, source, t.tv_sec, t.tv_usec, src.s().cc(), dst.s().cc());#endif if (AddrInfo* src_info = _table[src]) { src_info->port = source; // It's possible that it has changed. src_info->stamp = t; } else { _table.insert(src, new AddrInfo(source, t)); } int outport = -1; // Broadcast // Set outport if dst is unicast, we have info about it, and the // info is still valid. if (!dst.is_group()) { if (AddrInfo* dst_info = _table[dst]) { // click_chatter("Got a packet for a known dst on %d to %d\n", // source, dst_info->port); t.tv_sec -= _timeout; if (timercmp(&dst_info->stamp, &t, >)) { outport = dst_info->port; } } } if (outport < 0) broadcast(source, p); else if (outport == source) // Don't send back out on same interface p->kill(); else // forward output(outport).push(p);}StringEtherSwitch::read_table(Element* f, void *) { EtherSwitch* sw = (EtherSwitch*)f; String s; for (Table::iterator iter = sw->_table.begin(); iter; iter++) s += iter.key().s() + " " + String(iter.value()->port) + "\n"; return s;}voidEtherSwitch::add_handlers(){ add_read_handler("table", read_table, 0);}EXPORT_ELEMENT(EtherSwitch)#include <click/hashmap.cc>#if EXPLICIT_TEMPLATE_INSTANCEStemplate class HashMap<EtherAddress, EtherSwitch::AddrInfo*>;#endifCLICK_ENDDECLS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -