1 // Copyright (c) 2012, Miriam Ruiz <miriam@debian.org>. All rights reserved.
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
6 // 1. Redistributions of source code must retain the above copyright notice,
7 // this list of conditions and the following disclaimer.
9 // 2. Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
13 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS", AND ANY EXPRESS
14 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 // NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
17 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 #ifndef HEADERS_H_25E85D1E_4C87_11E2_BB32_7BDCB76BDF0B_
25 #define HEADERS_H_25E85D1E_4C87_11E2_BB32_7BDCB76BDF0B_
30 #include <net/ethernet.h>
31 #include <netinet/ip_icmp.h>
32 #include <netinet/udp.h>
33 #include <netinet/tcp.h>
34 #include <netinet/ip.h>
35 #include <net/if_arp.h>
43 unsigned char address
[ETH_ALEN
];
46 inline MacAddress(const unsigned char * v
);
47 inline operator const unsigned char * () const { return address
; }
48 const unsigned char * operator=(const unsigned char * v
);
49 bool less (const unsigned char * other
, bool equal
) const;
50 bool equal (const unsigned char * other
) const;
51 inline bool operator< (const unsigned char * other
) const {
52 return less (other
, false);
54 inline bool operator<= (const unsigned char * other
) const {
55 return less (other
, true);
57 inline bool operator> (const unsigned char * other
) const {
58 return ! less (other
, true);
60 inline bool operator>= (const unsigned char * other
) const {
61 return ! less (other
, false);
63 inline bool operator== (const unsigned char * other
) const {
66 inline bool operator!= (const unsigned char * other
) const {
67 return ! equal (other
);
71 std::ostream
& operator<< (std::ostream
& out
, const MacAddress
& v
);
77 inline IpAddress() : value(0) { }
78 inline IpAddress(in_addr_t v
) : value(v
) { }
79 inline operator in_addr_t() const { return value
; }
80 in_addr_t
operator=(in_addr_t v
) { return value
= v
; }
83 std::ostream
& operator<< (std::ostream
& out
, const IpAddress
& v
);
87 struct in6_addr address
;
90 inline Ip6Address(const struct in6_addr
& a
);
91 inline const struct in6_addr
&getAddress() const { return address
; }
94 std::ostream
& operator<< (std::ostream
& out
, const Ip6Address
& v
);
100 inline PortNumber() : value(0) { }
101 inline PortNumber(u_int16_t v
) : value(v
) { }
102 inline operator u_int16_t() const { return value
; }
103 u_int16_t
operator=(u_int16_t v
) { return value
= v
; }
106 // Separate semantically TCP and UDP ports even though they're the same type
108 class TCPPortNumber
: public PortNumber
{
111 class UDPPortNumber
: public PortNumber
{
114 std::ostream
& operator<< (std::ostream
& out
, const PortNumber
& v
);
119 PHYSICAL_LAYER
= 1 << 0,
120 DATA_LINK_LAYER
= 1 << 1, // Frames
121 NETWORK_LAYER
= 1 << 2, // Packets
122 TRANSPORT_LAYER
= 1 << 3, // Flow control
123 SESSION_LAYER
= 1 << 4, // Session support, authentication
124 PRESENTATION_LAYER
= 1 << 5, // Translation, unit conversion, encryption
125 APPLICATION_LAYER
= 1 << 6, // Program
126 PAYLOAD_DATA
= 1 << 7, // Data contents
129 class AbstractHeader
{
131 AbstractHeader(const void * buffer
, unsigned int len
)
132 : data((unsigned char *)buffer
), data_len(len
), prev(NULL
), next(NULL
) { }
133 virtual ~AbstractHeader() { // Deleting any node deletes the whole list
144 virtual const char * getTypeName() const = 0;
145 virtual unsigned int getTypeID() const = 0;
147 virtual const char * getHeaderName() const = 0;
148 virtual const unsigned int getLayers() const = 0;
149 virtual void print(std::ostream
& where
) const;
151 inline AbstractHeader
* getPreviousHeader() const {
154 inline AbstractHeader
* getNextHeader() { // Lazy creation
156 next
= createNextHeader();
157 if (next
) next
->prev
= this;
162 // Extract relevant info from headers
163 virtual const unsigned char * getMacAddress() const { return NULL
; }
164 virtual const in_addr_t
getIpAddress() const { return 0; }
165 virtual const u_int16_t
getPortNumber() const { return 0; }
168 virtual AbstractHeader
* createNextHeader() const { return NULL
; }
170 const unsigned char * data
;
171 unsigned int data_len
;
172 AbstractHeader
* prev
;
173 AbstractHeader
* next
;
175 static unsigned int next_id
;
179 AbstractHeader(const AbstractHeader
&other
);
180 AbstractHeader
&operator=(const AbstractHeader
&other
);
183 inline std::ostream
& operator<< (std::ostream
& out
, const AbstractHeader
& hd
) {
188 template <typename DERIVED
>
189 class HeaderAux
: public AbstractHeader
{
191 inline HeaderAux(const void * buffer
, unsigned int len
)
192 : AbstractHeader(buffer
, len
) {
193 if (id
==0) { id
= ++next_id
; }
196 static unsigned int ID() {
197 if (id
==0) { id
= ++next_id
; }
201 virtual const char * getTypeName() const {
202 return typeid(DERIVED
).name();
205 virtual unsigned int getTypeID() const {
210 static unsigned int id
;
213 // Headers for different protocols
215 class EthernetHeader
: public HeaderAux
<EthernetHeader
> {
217 EthernetHeader(const void * buffer
, unsigned int len
)
218 : HeaderAux
<EthernetHeader
>(buffer
, len
) { }
219 virtual const char * getHeaderName() const { return "Ethernet"; }
220 virtual const unsigned int getLayers() const { return PHYSICAL_LAYER
+ DATA_LINK_LAYER
; }
221 virtual void print(std::ostream
& where
) const;
222 static AbstractHeader
* createHeader(const void * buffer
, unsigned int len
, AbstractHeader
* prev_header
) {
223 return new EthernetHeader(buffer
, len
);
226 virtual AbstractHeader
* createNextHeader() const;
229 class IpHeader
: public HeaderAux
<IpHeader
> {
231 IpHeader(const void * buffer
, unsigned int len
)
232 : HeaderAux
<IpHeader
>(buffer
, len
) { }
233 virtual const char * getHeaderName() const { return "IP"; }
234 virtual const unsigned int getLayers() const { return NETWORK_LAYER
; }
235 virtual void print(std::ostream
& where
) const;
236 static AbstractHeader
* createHeader(const void * buffer
, unsigned int len
) {
237 return new IpHeader(buffer
, len
);
240 virtual AbstractHeader
* createNextHeader() const;
243 class TcpHeader
: public HeaderAux
<TcpHeader
> {
245 TcpHeader(const void * buffer
, unsigned int len
)
246 : HeaderAux
<TcpHeader
>(buffer
, len
) { }
247 virtual const char * getHeaderName() const { return "TCP"; }
248 virtual const unsigned int getLayers() const { return TRANSPORT_LAYER
; }
249 virtual void print(std::ostream
& where
) const;
250 static AbstractHeader
* createHeader(const void * buffer
, unsigned int len
) {
251 return new TcpHeader(buffer
, len
);
254 virtual AbstractHeader
* createNextHeader() const;
257 class UdpHeader
: public HeaderAux
<UdpHeader
> {
259 UdpHeader(const void * buffer
, unsigned int len
)
260 : HeaderAux
<UdpHeader
>(buffer
, len
) { }
261 virtual const char * getHeaderName() const { return "UDP"; }
262 virtual const unsigned int getLayers() const { return TRANSPORT_LAYER
; }
263 virtual void print(std::ostream
& where
) const;
264 static AbstractHeader
* createHeader(const void * buffer
, unsigned int len
) {
265 return new UdpHeader(buffer
, len
);
268 virtual AbstractHeader
* createNextHeader() const;
271 class IcmpHeader
: public HeaderAux
<IcmpHeader
> {
273 IcmpHeader(const void * buffer
, unsigned int len
)
274 : HeaderAux
<IcmpHeader
>(buffer
, len
) { }
275 virtual const char * getHeaderName() const { return "ICMP"; }
276 virtual const unsigned int getLayers() const { return NETWORK_LAYER
; }
277 virtual void print(std::ostream
& where
) const;
278 static AbstractHeader
* createHeader(const void * buffer
, unsigned int len
) {
279 return new IcmpHeader(buffer
, len
);
282 virtual AbstractHeader
* createNextHeader() const;
285 class IgmpHeader
: public HeaderAux
<IgmpHeader
> {
287 IgmpHeader(const void * buffer
, unsigned int len
)
288 : HeaderAux
<IgmpHeader
>(buffer
, len
) { }
289 virtual const char * getHeaderName() const { return "IGMP"; }
290 virtual const unsigned int getLayers() const { return NETWORK_LAYER
; }
291 static AbstractHeader
* createHeader(const void * buffer
, unsigned int len
) {
292 return new IgmpHeader(buffer
, len
);
296 class ArpHeader
: public HeaderAux
<ArpHeader
> {
298 ArpHeader(const void * buffer
, unsigned int len
)
299 : HeaderAux
<ArpHeader
>(buffer
, len
) { }
300 virtual const char * getHeaderName() const { return "ARP"; }
301 virtual const unsigned int getLayers() const { return DATA_LINK_LAYER
+ NETWORK_LAYER
; }
302 virtual void print(std::ostream
& where
) const;
303 static AbstractHeader
* createHeader(const void * buffer
, unsigned int len
);
306 struct arphdr_eth_ipv4
308 unsigned char ar_sha
[ETH_ALEN
]; /* Sender hardware address. */
309 unsigned char ar_spa
[4]; /* Sender IP address. */
310 unsigned char ar_tha
[ETH_ALEN
]; /* Target hardware address. */
311 unsigned char ar_tpa
[4]; /* Target IP address. */
314 class ArpEthIpHeader
: public ArpHeader
{
316 ArpEthIpHeader(const void * buffer
, unsigned int len
)
317 : ArpHeader(buffer
, len
) { }
318 virtual const char * getHeaderName() const { return "ARP (Ethernet, IP4)"; }
319 virtual void print(std::ostream
& where
) const;
322 class UnknownHeader
: public HeaderAux
<UnknownHeader
> {
324 UnknownHeader(const void * buffer
, unsigned int len
)
325 : HeaderAux
<UnknownHeader
>(buffer
, len
) { }
326 virtual const char * getHeaderName() const { return "Unknown"; }
327 virtual const unsigned int getLayers() const { return 0; }
328 static AbstractHeader
* createHeader(const void * buffer
, unsigned int len
) {
329 return new UnknownHeader(buffer
, len
);
333 class PayloadData
: public HeaderAux
<PayloadData
> {
335 PayloadData(const void * buffer
, unsigned int len
)
336 : HeaderAux
<PayloadData
>(buffer
, len
) { }
337 virtual const char * getHeaderName() const { return "Data"; }
338 virtual const unsigned int getLayers() const { return PAYLOAD_DATA
; }
339 static AbstractHeader
* createHeader(const void * buffer
, unsigned int len
) {
340 return new PayloadData(buffer
, len
);
344 } // namespace filter
346 #endif // HEADERS_H_25E85D1E_4C87_11E2_BB32_7BDCB76BDF0B_