📄 ettstat.cc
字号:
rates.push_back(rs); fwd.push_back(lnfo->_fwd); rev.push_back(lnfo->_rev); } update_link(_ip, entry->_ip, rates, fwd, rev, entry->_seq); ptr += probe->_probe_types.size()*sizeof(link_info); } } lp->_num_links = num_entries; lp->_psz = sizeof(link_probe) + lp->_num_links*sizeof(link_entry); lp->_cksum = 0; lp->_cksum = click_in_cksum((unsigned char *) lp, lp->_psz); struct click_wifi_extra *ceh = (struct click_wifi_extra *) p->all_user_anno(); ceh->magic = WIFI_EXTRA_MAGIC; ceh->rate = rate; checked_output_push(0, p);}intETTStat::initialize(ErrorHandler *errh){ if (noutputs() > 0) { if (!_eth) return errh->error("Source Ethernet address must be specified to send probes"); _timer.initialize(this); _next = Timestamp::now(); unsigned max_jitter = _period / 10; add_jitter(max_jitter, &_next); _timer.schedule_at(_next); } reset(); return 0;}Packet *ETTStat::simple_action(Packet *p){ Timestamp now = Timestamp::now(); unsigned min_sz = sizeof(click_ether) + sizeof(link_probe); if (p->length() < min_sz) { click_chatter("ETTStat %s: packet is too small", id().cc()); p->kill(); return 0; } click_ether *eh = (click_ether *) p->data(); if (ntohs(eh->ether_type) != _et) { click_chatter("ETTStat %s: got non-ETTStat packet type", id().cc()); p->kill(); return 0; } link_probe *lp = (link_probe *)(p->data() + sizeof(click_ether)); if (lp->_version != _ett_version) { static bool version_warning = false; _bad_table.insert(EtherAddress(eh->ether_shost), lp->_version); if (!version_warning) { version_warning = true; click_chatter ("%{element}: unknown sr version %x from %s", this, lp->_version, EtherAddress(eh->ether_shost).s().cc()); } p->kill(); return 0; } if (click_in_cksum((unsigned char *) lp, lp->_psz) != 0) { click_chatter("ETTStat %s: failed checksum", id().cc()); p->kill(); return 0; } if (p->length() < lp->_psz + sizeof(click_ether)) { click_chatter("ETTStat %s: packet is smaller (%d) than it claims (%u)", id().cc(), p->length(), lp->_psz); } IPAddress ip = IPAddress(lp->_ip); if (ip == _ip) { click_chatter("%{element} got own packet %s\n", this, _ip.s().cc()); p->kill(); return 0; } if (_arp_table) { _arp_table->insert(ip, EtherAddress(eh->ether_shost)); _rev_arp.insert(EtherAddress(eh->ether_shost), ip); } struct click_wifi_extra *ceh = (struct click_wifi_extra *) p->all_user_anno(); uint8_t rate = ceh->rate; if (ceh->rate != lp->_rate) { click_chatter("%{element} packet says rate %d is %d\n", this, lp->_rate, ceh->rate); p->kill(); return 0; } probe_t probe(now, lp->_seq, lp->_rate, lp->_size); int new_period = lp->_period; probe_list_t *l = _bcast_stats.findp(ip); int x = 0; if (!l) { _bcast_stats.insert(ip, probe_list_t(ip, new_period, lp->_tau)); l = _bcast_stats.findp(ip); l->_sent = 0; /* add into the neighbors vector */ _neighbors.push_back(ip); } else if (l->_period != new_period) { click_chatter("ETTStat %s: %s has changed its link probe period from %u to %u; clearing probe info", id().cc(), ip.s().cc(), l->_period, new_period); l->_probes.clear(); } else if (l->_tau != lp->_tau) { click_chatter("ETTStat %s: %s has changed its link tau from %u to %u; clearing probe info", id().cc(), ip.s().cc(), l->_tau, lp->_tau); l->_probes.clear(); } if (lp->_sent < (unsigned)l->_sent) { click_chatter("ETTStat %s: %s has reset; clearing probe info", id().cc(), ip.s().cc()); l->_probes.clear(); } RateSize rs = RateSize(rate, lp->_size); l->_period = new_period; l->_tau = lp->_tau; l->_sent = lp->_sent; l->_last_rx = now; l->_num_probes = lp->_num_probes; l->_probes.push_back(probe); l->_seq = probe._seq; /* keep stats for at least the averaging period */ while ((unsigned) l->_probes.size() && now._sec - l->_probes[0]._when._sec > (signed) (1 + (l->_tau / 1000))) l->_probes.pop_front(); for (x = 0; x < l->_probe_types.size(); x++) { if (rs == l->_probe_types[x]) { break; } } if (x == l->_probe_types.size()) { l->_probe_types.push_back(rs); l->_fwd_rates.push_back(0); } uint8_t *ptr = (uint8_t *) (lp + 1); uint8_t *end = (uint8_t *) p->data() + p->length(); if (lp->_flags &= PROBE_AVAILABLE_RATES) { int num_rates = ptr[0]; Vector<int> rates; ptr++; int x = 0; while (ptr < end && x < num_rates) { int rate = ptr[x]; rates.push_back(rate); x++; } ptr += num_rates; if(_rtable) { _rtable->insert(EtherAddress(eh->ether_shost), rates); } } int link_number = 0; while (ptr < end && (unsigned) link_number < lp->_num_links) { link_number++; link_entry *entry = (struct link_entry *)(ptr); IPAddress neighbor = entry->_ip; int num_rates = entry->_num_rates; if (0) { click_chatter("%{element} on link number %d / %d: neighbor %s, num_rates %d\n", this, link_number, lp->_num_links, neighbor.s().cc(), num_rates); } ptr += sizeof(struct link_entry); Vector<RateSize> rates; Vector<int> fwd; Vector<int> rev; for (int x = 0; x < num_rates; x++) { struct link_info *nfo = (struct link_info *) (ptr + x * (sizeof(struct link_info))); if (0) { click_chatter("%{element} on %s neighbor %s: size %d rate %d fwd %d rev %d\n", this, ip.s().cc(), neighbor.s().cc(), nfo->_size, nfo->_rate, nfo->_fwd, nfo->_rev); } RateSize rs = RateSize(nfo->_rate, nfo->_size); /* update other link stuff */ rates.push_back(rs); fwd.push_back(nfo->_fwd); if (neighbor == _ip) { rev.push_back(l->rev_rate(_start, rates[x]._rate, rates[x]._size)); } else { rev.push_back(nfo->_rev); } if (neighbor == _ip) { /* set the fwd rate */ for (int x = 0; x < l->_probe_types.size(); x++) { if (rs == l->_probe_types[x]) { l->_fwd_rates[x] = nfo->_rev; break; } } } } int seq = entry->_seq; if (neighbor == ip && ((uint32_t) neighbor > (uint32_t) _ip)) { seq = now._sec; } update_link(ip, neighbor, rates, fwd, rev, seq); ptr += num_rates * sizeof(struct link_info); } p->kill(); return 0;}static int ipaddr_sorter(const void *va, const void *vb) { IPAddress *a = (IPAddress *)va, *b = (IPAddress *)vb; if (a->addr() == b->addr()) { return 0; } return (ntohl(a->addr()) < ntohl(b->addr())) ? -1 : 1;}StringETTStat::read_bcast_stats(){ Vector<IPAddress> ip_addrs; for (ProbeMap::const_iterator i = _bcast_stats.begin(); i; i++) ip_addrs.push_back(i.key()); Timestamp now = Timestamp::now(); StringAccum sa; click_qsort(ip_addrs.begin(), ip_addrs.size(), sizeof(IPAddress), ipaddr_sorter); for (int i = 0; i < ip_addrs.size(); i++) { IPAddress ip = ip_addrs[i]; probe_list_t *pl = _bcast_stats.findp(ip); //sa << _ip << " " << _eth << " "; sa << ip; if (_arp_table) { EtherAddress eth_dest = _arp_table->lookup(ip); if (eth_dest) { sa << " " << eth_dest.s().cc(); } else { sa << " ?"; } } else { sa << " ?"; } for (int x = 0; x < _ads_rs.size(); x++) { int rate = _ads_rs[x]._rate; int size = _ads_rs[x]._size; int rev = pl->rev_rate(_start, rate, size); int fwd = pl->fwd_rate(rate, size); sa << " [ " << rate << " " << size << " "; sa << fwd << " " << rev << " ]"; } sa << " seq " << pl->_seq; sa << " period " << pl->_period; sa << " tau " << pl->_tau; sa << " sent " << pl->_sent; sa << " last_rx " << now - pl->_last_rx; sa << "\n"; } return sa.take_string();}String ETTStat::bad_nodes() { StringAccum sa; for (BadTable::const_iterator i = _bad_table.begin(); i; i++) { uint8_t version = i.value(); EtherAddress dst = i.key(); sa << this << " eth " << dst.s().cc() << " version " << (int) version << "\n"; } return sa.take_string();}voidETTStat::clear_stale() { Vector<IPAddress> new_neighbors; Timestamp now = Timestamp::now(); for (int x = 0; x < _neighbors.size(); x++) { IPAddress n = _neighbors[x]; probe_list_t *l = _bcast_stats.findp(n); if (!l || (unsigned) now._sec - l->_last_rx._sec > 2 * l->_tau/1000) { click_chatter("%{element} clearing stale neighbor %s age %d\n ", this, n.s().cc(), now._sec - l->_last_rx._sec); _bcast_stats.remove(n); } else { new_neighbors.push_back(n); } } _neighbors.clear(); for (int x = 0; x < new_neighbors.size(); x++) { _neighbors.push_back(new_neighbors[x]); }}voidETTStat::reset(){ _neighbors.clear(); _bcast_stats.clear(); _rev_arp.clear(); _seq = 0; _sent = 0; _start = Timestamp::now();}voidETTStat::add_handlers(){ add_read_handler("bcast_stats", ETTStat_read_param, (void *) H_BCAST_STATS); add_read_handler("bad_version", ETTStat_read_param, (void *) H_BAD_VERSION); add_read_handler("ip", ETTStat_read_param, (void *) H_IP); add_read_handler("tau", ETTStat_read_param, (void *) H_TAU); add_read_handler("period", ETTStat_read_param, (void *) H_PERIOD); add_read_handler("probes", ETTStat_read_param, (void *) H_PROBES); add_write_handler("reset", ETTStat_write_param, (void *) H_RESET); add_write_handler("tau", ETTStat_write_param, (void *) H_TAU); add_write_handler("period", ETTStat_write_param, (void *) H_PERIOD); add_write_handler("probes", ETTStat_write_param, (void *) H_PROBES);}IPAddress ETTStat::reverse_arp(EtherAddress eth){ IPAddress *ip = _rev_arp.findp(eth); return (ip) ? IPAddress(ip->addr()) : IPAddress();}EXPORT_ELEMENT(ETTStat)#include <click/bighashmap.cc>#include <click/dequeue.cc>#include <click/vector.cc>template class DEQueue<ETTStat::probe_t>;template class HashMap<IPAddress, ETTStat::probe_list_t>;template class HashMap<EtherAddress, uint8_t>;CLICK_ENDDECLS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -