libtins  3.4
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
pppoe.h
1 /*
2  * Copyright (c) 2016, Matias Fontanini
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #ifndef TINS_PPPoE_H
31 #define TINS_PPPoE_H
32 
33 #include <list>
34 #include <string>
35 #include <vector>
36 #include "pdu.h"
37 #include "macros.h"
38 #include "endianness.h"
39 #include "small_uint.h"
40 #include "pdu_option.h"
41 #include "cxxstd.h"
42 
43 namespace Tins {
48 class TINS_API PPPoE : public PDU {
49 public:
53  enum TagTypes {
54  END_OF_LIST = 0,
55  SERVICE_NAME = 0x101,
56  #if TINS_IS_LITTLE_ENDIAN
57  AC_NAME = 0x201,
58  HOST_UNIQ = 0x301,
59  AC_COOKIE = 0x401,
60  VENDOR_SPECIFIC = 0x501,
61  RELAY_SESSION_ID = 0x101,
62  SERVICE_NAME_ERROR = 0x102,
63  AC_SYSTEM_ERROR = 0x202,
64  GENERIC_ERROR = 0x302
65  #else
66  AC_NAME = 0x102,
67  HOST_UNIQ = 0x103,
68  AC_COOKIE = 0x104,
69  VENDOR_SPECIFIC = 0x105,
70  RELAY_SESSION_ID = 0x110,
71  SERVICE_NAME_ERROR = 0x201,
72  AC_SYSTEM_ERROR = 0x202,
73  GENERIC_ERROR = 0x203
74  #endif
75  };
76 
81 
85  typedef std::list<tag> tags_type;
86 
91  typedef std::vector<uint8_t> data_type;
92 
93  uint32_t vendor_id;
94  data_type data;
95 
96  vendor_spec_type(uint32_t vendor_id = 0, const data_type& data = data_type())
97  : vendor_id(vendor_id), data(data) { }
98 
99  static vendor_spec_type from_option(const tag& opt);
100  };
101 
105  static const PDU::PDUType pdu_flag = PDU::PPPOE;
106 
112  PPPoE();
113 
123  PPPoE(const uint8_t* buffer, uint32_t total_sz);
124 
125  // Getters
126 
132  return header_.version;
133  }
134 
139  small_uint<4> type() const {
140  return header_.type;
141  }
142 
147  uint8_t code() const {
148  return header_.code;
149  }
150 
155  uint16_t session_id() const {
156  return Endian::be_to_host(header_.session_id);
157  }
158 
163  uint16_t payload_length() const {
164  return Endian::be_to_host(header_.payload_length);
165  }
166 
172  uint32_t header_size() const;
173 
177  const tags_type& tags() const {
178  return tags_;
179  }
180 
184  PPPoE* clone() const {
185  return new PPPoE(*this);
186  }
187 
188  const tag* search_tag(TagTypes identifier) const;
189 
194  PDUType pdu_type() const { return pdu_flag; }
195 
196  // Setters
197 
202  void version(small_uint<4> new_version);
203 
208  void type(small_uint<4> new_type);
209 
214  void code(uint8_t new_code);
215 
220  void session_id(uint16_t new_session_id);
221 
226  void payload_length(uint16_t new_payload_length);
227 
233  void add_tag(const tag& option);
234 
235  #if TINS_IS_CXX11
236 
243  void add_tag(tag &&option) {
244  tags_size_ += static_cast<uint16_t>(option.data_size() + sizeof(uint16_t) * 2);
245  tags_.push_back(std::move(option));
246  }
247  #endif
248 
249  // Option setters
250 
254  void end_of_list();
255 
261  void service_name(const std::string& value);
262 
268  void ac_name(const std::string& value);
269 
275  void host_uniq(const byte_array& value);
276 
282  void ac_cookie(const byte_array& value);
283 
289  void vendor_specific(const vendor_spec_type& value);
290 
296  void relay_session_id(const byte_array& value);
297 
303  void service_name_error(const std::string& value);
304 
310  void ac_system_error(const std::string& value);
311 
317  void generic_error(const std::string& value);
318 
319  // Option getters
320 
327  std::string service_name() const;
328 
335  std::string ac_name() const;
336 
343  byte_array host_uniq() const;
344 
351  byte_array ac_cookie() const;
352 
359  vendor_spec_type vendor_specific() const;
360 
367  byte_array relay_session_id() const;
368 
375  std::string service_name_error() const;
376 
383  std::string ac_system_error() const;
384 
391  std::string generic_error() const;
392 private:
393  void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU *);
394 
395  template<typename T>
396  void add_tag_iterable(TagTypes id, const T& data) {
397  add_tag(
398  tag(
399  id,
400  data.begin(),
401  data.end()
402  )
403  );
404  }
405 
406  template<typename T>
407  T search_and_convert(TagTypes id) const {
408  const tag* t = search_tag(id);
409  if (!t) {
410  throw option_not_found();
411  }
412  return t->to<T>();
413  }
414 
415  TINS_BEGIN_PACK
416  struct pppoe_header {
417  #if TINS_IS_LITTLE_ENDIAN
418  uint8_t version:4,
419  type:4;
420  uint8_t code;
421  #else
422  uint16_t version:4,
423  type:4,
424  code:8;
425  #endif
426  uint16_t session_id;
427  uint16_t payload_length;
428  } TINS_END_PACK;
429 
430  pppoe_header header_;
431  tags_type tags_;
432  uint16_t tags_size_;
433 };
434 }
435 
436 #endif // TINS_PPPoE_H
TagTypes
Definition: pppoe.h:53
std::vector< uint8_t > byte_array
Definition: pdu.h:46
std::list< tag > tags_type
Definition: pppoe.h:85
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:128
small_uint< 4 > type() const
Getter for the type field.
Definition: pppoe.h:139
small_uint< 4 > version() const
Getter for the version field.
Definition: pppoe.h:131
Definition: pppoe.h:90
Represents a PDU option field.
Definition: pdu_option.h:320
PPPoE * clone() const
Definition: pppoe.h:184
void add_tag(tag &&option)
Adds a PPPoE tag.
Definition: pppoe.h:243
PDUOption< TagTypes, PPPoE > tag
Definition: pppoe.h:80
uint16_t session_id() const
Getter for the session_id field.
Definition: pppoe.h:155
const tags_type & tags() const
Returns the list of tags.
Definition: pppoe.h:177
uint16_t payload_length() const
Getter for the payload_length field.
Definition: pppoe.h:163
uint8_t code() const
Getter for the code field.
Definition: pppoe.h:147
PDUType pdu_type() const
Getter for the PDU's type.
Definition: pppoe.h:194
Base class for protocol data units.
Definition: pdu.h:108
Represents a Point-to-point protocol over Ethernet PDU.
Definition: pppoe.h:48