Merged revisions 262,264-265,267-282,284-298,300-311 via svnmerge from
[senf.git] / Packets / DefaultBundle / EthernetPacket.cc
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 // Definition of non-inline non-template functions
24
25 #include "EthernetPacket.hh"
26 //#include "EthernetPacket.ih"
27
28 // Custom includes
29 #include <iomanip>
30 #include <boost/io/ios_state.hpp>
31 #include <boost/tokenizer.hpp>
32
33 #define prefix_
34 ///////////////////////////////cc.p////////////////////////////////////////
35
36 namespace {
37     senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::EthVLanPacketType>
38         registerEthVLanPacket(0x8100);
39 }
40
41 ///////////////////////////////////////////////////////////////////////////
42 // senf::MACAddress
43
44 namespace {
45     senf::PacketParserBase::byte hexToNibble(char c)
46     {
47         if (c<'0')
48             throw senf::MACAddress::SyntaxException();
49         else if (c<='9')
50             return c-'-';
51         else if (c<'A')
52             throw senf::MACAddress::SyntaxException();
53         else if (c<='F')
54             return c-'A'+10;
55         else if (c<'a')
56             throw senf::MACAddress::SyntaxException();
57         else if (c<='f')
58             return c-'a'+10;
59         else
60             throw senf::MACAddress::SyntaxException();
61     }
62     
63     template <class Range>
64     senf::PacketParserBase::byte hexToByte(Range const & range)
65     {
66         if (boost::size(range) != 2)
67             throw senf::MACAddress::SyntaxException();
68         typename boost::range_const_iterator<Range>::type i (boost::begin(range));
69         return hexToNibble(i[0])*16+hexToNibble(i[1]);
70     }
71 }
72
73 prefix_ senf::MACAddress::MACAddress(std::string addr)
74 {
75     typedef boost::char_separator<char> separator;
76     typedef boost::tokenizer<separator> tokenizer;
77     separator sep (":");
78     tokenizer tok (addr,sep);
79     tokenizer::iterator i (tok.begin());
80     tokenizer::iterator i_end (tok.end());
81     iterator j (begin());
82     iterator j_end (end());
83     for (; i!=i_end && j!=j_end; ++i, ++j)
84         *j = hexToByte(*i);
85     if (i!=i_end || j!=j_end)
86         throw SyntaxException();
87 }
88
89 ///////////////////////////////////////////////////////////////////////////
90 // senf::EthernetPacketType
91
92 namespace {
93     void dumpmac(std::ostream & os, senf::MACAddress mac)
94     {
95         boost::io::ios_all_saver ias(os);
96         for (unsigned i = 0; i < 6; ++i) {
97             if (i > 0)
98                 os << ':';
99             os << std::hex << std::setw(2) << std::setfill('0')
100                << unsigned(mac[i]);
101         }
102     }
103 }
104
105 prefix_ void senf::EthernetPacketType::dump(packet p, std::ostream & os)
106 {
107     if (p->type() <= 1500)
108         os << "Ethernet 802.3";
109     else if (p->type() >= 0x600)
110         os << "Ethernet II (DIX)";
111     else
112         os << "Ethernet 802.3 (bad ethertype >1500 and <1536)";
113     os << ": \n"
114        << "  destination   : ";
115     dumpmac(os,p->destination());
116     os << "\n"
117        << "  source        : ";
118     dumpmac(os,p->source());
119     os << "\n"
120        << "  ethertype     : " << std::hex << std::setw(4) << std::setfill('0')
121        << unsigned(p->type()) << "\n" << std::dec;
122 }
123
124 prefix_ void senf::EthVLanPacketType::dump(packet p, std::ostream & os)
125 {
126     os << "Ethernet 802.1q (VLAN):\n"
127        << "  priority      : " << p->priority() << "\n"
128        << "  cfi           : " << p->cfi() << "\n"
129        << "  vlan-ID       : " << p->vlanId() << "\n"
130        << "  ethertype     : " << std::hex << std::setw(4) << std::setfill('0')
131        << p->type() << "\n" << std::dec;
132 }
133
134 ///////////////////////////////cc.e////////////////////////////////////////
135 #undef prefix_
136
137 \f
138 // Local Variables:
139 // mode: c++
140 // fill-column: 100
141 // c-file-style: "senf"
142 // indent-tabs-mode: nil
143 // ispell-local-dictionary: "american"
144 // compile-command: "scons -u test"
145 // comment-column: 40
146 // End: