00001 // $Id: EthernetPacket.cc 1792 2011-06-09 15:49:59Z tho $ 00002 // 00003 // Copyright (C) 2006 00004 // Fraunhofer (FOKUS) 00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY 00006 // Stefan Bund <g0dil@berlios.de> 00007 // 00008 // This program is free software; you can redistribute it and/or modify 00009 // it under the terms of the GNU General Public License as published by 00010 // the Free Software Foundation; either version 2 of the License, or 00011 // (at your option) any later version. 00012 // 00013 // This program is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU General Public License 00019 // along with this program; if not, write to the 00020 // Free Software Foundation, Inc., 00021 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00022 00026 #include "EthernetPacket.hh" 00027 //#include "EthernetPacket.ih" 00028 00029 // Custom includes 00030 #include "LlcSnapPacket.hh" 00031 #include <iomanip> 00032 #include <boost/io/ios_state.hpp> 00033 #include <senf/Utils/Format.hh> 00034 00035 #define prefix_ 00036 //-///////////////////////////////////////////////////////////////////////////////////////////////// 00037 00038 namespace { 00039 SENF_PACKET_REGISTRY_REGISTER( senf::EtherTypes, 0x8100, senf::EthVLanPacket); 00040 } 00041 00042 //-///////////////////////////////////////////////////////////////////////////////////////////////// 00043 // senf::EthernetPacketType 00044 00045 prefix_ void senf::EthernetPacketType::dump(packet p, std::ostream & os) 00046 { 00047 boost::io::ios_all_saver ias(os); 00048 if (p->type_length() <= 1500) 00049 os << "Ethernet 802.3"; 00050 else if (p->type_length() >= 0x600) 00051 os << "Ethernet II (DIX)"; 00052 else 00053 os << "Ethernet 802.3 (bad ethertype >1500 and <1536)"; 00054 os << ": \n" 00055 << senf::fieldName("destination") << p->destination() << "\n" 00056 << senf::fieldName("source") << p->source() << "\n" 00057 << senf::fieldName("type/length") << senf::format::dumpint(p->type_length().value()) << "\n"; 00058 } 00059 00060 prefix_ senf::PacketInterpreterBase::factory_t senf::EthernetPacketType::nextPacketType(packet p) 00061 { 00062 if (p->type_length() >= 1536) return lookup(p->type_length()); 00063 else if (p->type_length() <= 1500) return LlcSnapPacket::factory(); 00064 else return no_factory(); 00065 } 00066 00067 prefix_ void senf::EthernetPacketType::finalize(packet p) 00068 { 00069 Packet n (p.next(nothrow)); 00070 if (n) { 00071 optional_key_t k (key(n)); 00072 if (k) 00073 p->type_length() << k; 00074 else if (n.is<LlcSnapPacket>()) 00075 p->type_length() << n.data().size(); 00076 } 00077 // Do NOT reset type_length if the type is not known ... doing this will destroy read packets 00078 } 00079 00080 prefix_ void senf::EthVLanPacketType::dump(packet p, std::ostream & os) 00081 { 00082 boost::io::ios_all_saver ias(os); 00083 os << "Ethernet 802.1q (VLAN):\n" 00084 << senf::fieldName("priority") << p->priority() << "\n" 00085 << senf::fieldName("cfi") << p->cfi() << "\n" 00086 << senf::fieldName("vlan-ID") << p->vlanId() << "\n" 00087 << senf::fieldName("ethertype") 00088 << " 0x" << std::hex << std::setw(4) << std::setfill('0') << std::right << p->type() << "\n"; 00089 } 00090 00091 prefix_ void senf::EthVLanPacketType::finalize(packet p) 00092 { 00093 p->type() << key(p.next(nothrow)); 00094 } 00095 00096 00097 //-///////////////////////////////////////////////////////////////////////////////////////////////// 00098 #undef prefix_ 00099 00100 00101 // Local Variables: 00102 // mode: c++ 00103 // fill-column: 100 00104 // c-file-style: "senf" 00105 // indent-tabs-mode: nil 00106 // ispell-local-dictionary: "american" 00107 // compile-command: "scons -u test" 00108 // comment-column: 40 00109 // End: