libtins  4.0
llc.h
1 /*
2  * Copyright (c) 2017, 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_IEEE8022_H
31 #define TINS_IEEE8022_H
32 
33 #include <vector>
34 #include <stdint.h>
35 #include <tins/macros.h>
36 #include <tins/pdu.h>
37 #include <tins/endianness.h>
38 
39 namespace Tins {
40 
47 class TINS_API LLC : public PDU {
48 public:
52  static const PDU::PDUType pdu_flag = PDU::LLC;
53 
57  static const uint8_t GLOBAL_DSAP_ADDR;
58 
62  static const uint8_t NULL_ADDR;
63 
67  enum Format {
68  INFORMATION = 0,
69  SUPERVISORY = 1,
70  UNNUMBERED = 3
71  };
72 
77  UI = 0x00,
78  XID = 0x1D,
79  TEST = 0x07,
80  SABME = 0x1E,
81  DISC = 0x02,
82  UA = 0x06,
83  DM = 0x18,
84  FRMR = 0x11
85  };
86 
91  RECEIVE_READY = 0,
92  REJECT = 2,
93  RECEIVE_NOT_READY = 1
94  };
95 
99  LLC();
100 
107  LLC(uint8_t dsap, uint8_t ssap);
108 
119  LLC(const uint8_t* buffer, uint32_t total_sz);
120 
121  /* Setters */
122 
127  void group(bool value);
128 
133  void dsap(uint8_t new_dsap);
134 
139  void response(bool value);
140 
145  void ssap(uint8_t new_ssap);
146 
151  void type(Format type);
152 
158  void send_seq_number(uint8_t seq_number);
159 
165  void receive_seq_number(uint8_t seq_number);
166 
171  void poll_final(bool value);
172 
178  void supervisory_function(SupervisoryFunctions new_func);
179 
185  void modifier_function(ModifierFunctions mod_func);
186 
194  void add_xid_information(uint8_t xid_id,
195  uint8_t llc_type_class,
196  uint8_t receive_window);
197 
198  //TODO: Add Acknowledged connectionless information
199 
200  /* Getters */
201 
206  bool group() {
207  return header_.dsap & 0x01;
208  }
209 
214  uint8_t dsap() {
215  return header_.dsap;
216  }
217 
222  bool response() {
223  return (header_.ssap & 0x01);
224  }
225 
230  uint8_t ssap() {
231  return header_.ssap;
232  }
233 
238  uint8_t type() {
239  return type_;
240  }
241 
247  uint8_t send_seq_number() {
248  return (type() == INFORMATION) ? (control_field.info.send_seq_num) : 0;
249  }
250 
257  uint8_t receive_seq_number() {
258  switch (type()) {
259  case INFORMATION:
260  return control_field.info.recv_seq_num;
261  case SUPERVISORY:
262  return control_field.super.recv_seq_num;
263  case UNNUMBERED:
264  return 0;
265  default:
266  return 0;
267  }
268  }
269 
274  bool poll_final() {
275  switch (type()) {
276  case UNNUMBERED:
277  return control_field.unnumbered.poll_final_bit;
278  case INFORMATION:
279  return control_field.info.poll_final_bit;
280  case SUPERVISORY:
281  return control_field.super.poll_final_bit;
282  default:
283  return false;
284  }
285  }
286 
293  if (type() == SUPERVISORY) {
294  return control_field.super.supervisory_func;
295  }
296  return 0;
297  }
298 
304  uint8_t modifier_function() {
305  if (type() == UNNUMBERED) {
306  return (control_field.unnumbered.mod_func1 << 3) + control_field.unnumbered.mod_func2;
307  }
308  return 0;
309  }
310 
317  uint32_t header_size() const;
318 
323  PDUType pdu_type() const {
324  return pdu_flag;
325  }
326 
330  void clear_information_fields();
331 
337  LLC* clone() const {
338  return new LLC(*this);
339  }
340 private:
341  TINS_BEGIN_PACK
342  struct llchdr {
343  uint8_t dsap;
344  uint8_t ssap;
345  } TINS_END_PACK;
346 
347  #if TINS_IS_LITTLE_ENDIAN
348  TINS_BEGIN_PACK
349  struct info_control_field {
350  uint16_t
351  type_bit:1,
352  send_seq_num:7,
353  poll_final_bit:1,
354  recv_seq_num:7;
355  } TINS_END_PACK;
356 
357  TINS_BEGIN_PACK
358  struct super_control_field {
359  uint16_t type_bit:2,
360  supervisory_func:2,
361  unused:4,
362  poll_final_bit:1,
363  recv_seq_num:7;
364  } TINS_END_PACK;
365 
366  TINS_BEGIN_PACK
367  struct un_control_field {
368  uint8_t type_bits:2,
369  mod_func1:2,
370  poll_final_bit:1,
371  mod_func2:3;
372  } TINS_END_PACK;
373  #elif TINS_IS_BIG_ENDIAN
374  TINS_BEGIN_PACK
375  struct info_control_field {
376  uint16_t send_seq_num:7,
377  type_bit:1,
378  recv_seq_num:7,
379  poll_final_bit:1;
380  } TINS_END_PACK;
381 
382  TINS_BEGIN_PACK
383  struct super_control_field {
384  uint16_t unused:4,
385  supervisory_func:2,
386  type_bit:2,
387  recv_seq_num:7,
388  poll_final_bit:1;
389  } TINS_END_PACK;
390 
391  TINS_BEGIN_PACK
392  struct un_control_field {
393  uint8_t mod_func2:3,
394  poll_final_bit:1,
395  mod_func1:2,
396  type_bits:2;
397  } TINS_END_PACK;
398  #endif
399 
400  typedef std::vector<uint8_t> field_type;
401  typedef std::vector<field_type> field_list;
402 
403  void write_serialization(uint8_t* buffer, uint32_t total_sz);
404 
405  llchdr header_;
406  uint8_t control_field_length_;
407  union {
408  info_control_field info;
409  super_control_field super;
410  un_control_field unnumbered;
411  } control_field;
412  Format type_;
413  uint8_t information_field_length_;
414  field_list information_fields_;
415 };
416 
417 } // Tins
418 
419 #endif // TINS_IEEE8022_H
SupervisoryFunctions
LLC Supervisory functions.
Definition: llc.h:90
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:127
static const uint8_t GLOBAL_DSAP_ADDR
Represents the LLC global DSAP address.
Definition: llc.h:57
uint8_t send_seq_number()
Getter for sender send sequence number.
Definition: llc.h:247
PDUType pdu_type() const
Getter for the PDU&#39;s type.
Definition: llc.h:323
uint8_t type()
Getter for the LLC frame format type.
Definition: llc.h:238
uint8_t receive_seq_number()
Getter for sender receive sequence number.
Definition: llc.h:257
uint8_t dsap()
Getter for the dsap field.
Definition: llc.h:214
uint8_t modifier_function()
Getter for the modifier function field.
Definition: llc.h:304
uint8_t supervisory_function()
Getter for the supervisory function.
Definition: llc.h:292
bool poll_final()
Getter for the poll/final flag.
Definition: llc.h:274
The Tins namespace.
Definition: address_range.h:38
Representing a LLC frame.
Definition: llc.h:47
LLC * clone() const
Clones this PDU.
Definition: llc.h:337
bool response()
Getter for the response bit.
Definition: llc.h:222
ModifierFunctions
LLC Modifier functions.
Definition: llc.h:76
static const uint8_t NULL_ADDR
Represents the LLC NULL address.
Definition: llc.h:62
uint8_t ssap()
Getter for the ssap field.
Definition: llc.h:230
Base class for protocol data units.
Definition: pdu.h:107
Format
LLC Format flags.
Definition: llc.h:67
bool group()
Getter for the group destination bit.
Definition: llc.h:206