📄 arpprint.cc
字号:
/* * arpprint.{cc,hh} -- element prints packet contents to system log * Jose Maria Gonzalez * * Shameless graft of ipprint.hh/cc and tcpdump-3.8.3/print-arp.c * * Copyright (c) 2005-2006 Regents of the University of California * * 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 "arpprint.hh"#include <click/glue.hh>#include <click/confparse.hh>#include <click/error.hh>#include <click/straccum.hh>#include <click/packet_anno.hh>#include <click/router.hh>#include <click/nameinfo.hh>#include <click/etheraddress.hh>#include <clicknet/ether.h>#if CLICK_USERLEVEL# include <stdio.h>#endifCLICK_DECLS/* * Address Resolution Protocol. * * See RFC 826 for protocol description. ARP packets are variable * in size; the arphdr structure defines the fixed-length portion. * Protocol type values are the same as those for 10 Mb/s Ethernet. * It is followed by the variable-sized fields ar_sha, arp_spa, * arp_tha and arp_tpa in that order, according to the lengths * specified. Field names used correspond to RFC 826. */ARPPrint::ARPPrint(){#if CLICK_USERLEVEL _outfile = 0;#endif}ARPPrint::~ARPPrint(){}intARPPrint::configure(Vector<String> &conf, ErrorHandler *errh){ _label = ""; bool print_time = true; String channel; if (cp_va_kparse(conf, this, errh, "LABEL", cpkP, cpString, &_label, "TIMESTAMP", 0, cpBool, &print_time,#if CLICK_USERLEVEL "OUTFILE", 0, cpFilename, &_outfilename,#endif cpEnd) < 0) return -1; _print_timestamp = print_time; _errh = router()->chatter_channel(channel); return 0;}intARPPrint::initialize(ErrorHandler *errh){#if CLICK_USERLEVEL if (_outfilename) { _outfile = fopen(_outfilename.c_str(), "wb"); if (!_outfile) return errh->error("%s: %s", _outfilename.c_str(), strerror(errno)); }#else (void) errh;#endif return 0;}voidARPPrint::cleanup(CleanupStage){#if CLICK_USERLEVEL if (_outfile) fclose(_outfile); _outfile = 0;#endif}Packet *ARPPrint::simple_action(Packet *p){ if (!p->has_network_header()) return p; StringAccum sa; if (_label) sa << _label << ": "; if (_print_timestamp) sa << p->timestamp_anno() << ": "; if (p->network_length() < (int) sizeof(click_arp)) sa << "truncated-arp (" << p->network_length() << ")"; else { const click_ether_arp *ap = (const click_ether_arp *) p->network_header(); uint16_t hrd = ntohs(ap->ea_hdr.ar_hrd); uint16_t pro = ntohs(ap->ea_hdr.ar_pro); uint8_t hln = ap->ea_hdr.ar_hln; uint8_t pln = ap->ea_hdr.ar_pln; uint16_t op = ntohs(ap->ea_hdr.ar_op); if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || pln != 4 || hln == 0) { sa << "arp-#" << op << " for proto #" << pro << " (" << pln << ") " << "hardware #" << hrd << " (" << hln << ")"; return p; } const unsigned char *sha = (const unsigned char *)ap->arp_sha; const unsigned char *spa = (const unsigned char *)ap->arp_spa; const unsigned char *tha = (const unsigned char *)ap->arp_tha; const unsigned char *tpa = (const unsigned char *)ap->arp_tpa; if (pro == ETHERTYPE_TRAIL) sa << "trailer-"; switch (op) { case ARPOP_REQUEST: { const unsigned char ezero[6] = {0,0,0,0,0,0}; sa << "arp who-has " << IPAddress(tpa); if ( memcmp (ezero, tha, hln) != 0 ) sa << " (" << EtherAddress(tha) << ")"; sa << " tell " << IPAddress(spa); break; } case ARPOP_REPLY: sa << "arp reply " << IPAddress(spa); sa << " is-at " << EtherAddress(sha); break; case ARPOP_REVREQUEST: sa << "rarp who-is " << EtherAddress(tha) << " tell " << EtherAddress(sha); break; case ARPOP_REVREPLY: sa << "rarp reply " << EtherAddress(tha) << " at " << IPAddress(tpa); break; case ARPOP_INVREQUEST: sa << "invarp who-is " << EtherAddress(tha) << " tell " << EtherAddress(sha); break; case ARPOP_INVREPLY: sa << "invarp reply " << EtherAddress(tha) << " at " << IPAddress(tpa); break; default: sa << "arp-#" << op; // default_print((const u_char *)ap, caplen); } if (hrd != ARPHRD_ETHER) sa << "hardware #" << hrd; }#if CLICK_USERLEVEL if (_outfile) { sa << '\n'; ignore_result(fwrite(sa.data(), 1, sa.length(), _outfile)); } else#endif _errh->message("%s", sa.c_str()); return p;}CLICK_ENDDECLSEXPORT_ELEMENT(ARPPrint)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -