Revised OpenFlow Library  v0.6.0dev
 All Classes Files Functions Variables Friends Groups Pages
cpacket.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef CPACKET_H
6 #define CPACKET_H 1
7 
8 #include <utility>
9 #include <iostream>
10 #include <string>
11 #include <deque>
12 #include <list>
13 #include <set>
14 #include <algorithm>
15 #include <typeinfo>
16 #include <unistd.h>
17 #include <sys/types.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <inttypes.h>
21 #include <pthread.h>
22 #include <sys/uio.h>
23 #include <assert.h>
24 
25 #include "rofl/common/croflexception.h"
26 #include "rofl/common/cclock.h"
27 #include "rofl/common/fframe.h"
28 #include "rofl/common/cmemory.h"
29 #include "rofl/common/thread_helper.h"
30 
31 #include "rofl/common/openflow/openflow.h"
32 
33 namespace rofl {
34 
35 class ePacketBase : public RoflException {
36 public:
37  ePacketBase(const std::string& __arg) : RoflException(__arg) {};
38 };
39 class ePacketInval : public ePacketBase {
40 public:
41  ePacketInval(const std::string& __arg) : ePacketBase(__arg) {};
42 };
43 class ePacketNotFound : public ePacketBase {
44 public:
45  ePacketNotFound(const std::string& __arg) : ePacketBase(__arg) {};
46 };
48 public:
49  ePacketOutOfRange(const std::string& __arg) : ePacketBase(__arg) {};
50 };
51 
52 
56 class cpacket : public rofl::cmemory {
57 public:
58 
62  cpacket() :
63  rofl::cmemory(0), head(0), tail(0), initial_head(0), initial_tail(0) {};
64 
68  virtual
69  ~cpacket() {};
70 
74  cpacket(
75  size_t size, size_t head = DEFAULT_HSPACE, size_t tail = DEFAULT_TSPACE) :
76  rofl::cmemory(head + size + tail), head(head), tail(tail), initial_head(head), initial_tail(tail) {};
77 
81  cpacket(
82  uint8_t *buf, size_t buflen, size_t head = DEFAULT_HSPACE, size_t tail = DEFAULT_TSPACE) :
83  rofl::cmemory(head + buflen + tail), head(head), tail(tail), initial_head(head), initial_tail(tail)
84  { memcpy(somem()+head, buf, buflen); };
85 
89  cpacket(const cpacket& pack)
90  { *this = pack; };
91 
95  cpacket&
96  operator= (const cpacket& pack) {
97  if (this == &pack)
98  return *this;
100  head = pack.head;
101  tail = pack.tail;
102  initial_head = pack.initial_head;
103  initial_tail = pack.initial_tail;
104  return *this;
105  };
106 
107 public:
108 
112  void
113  clear() {
115  head = initial_head;
116  tail = initial_tail;
117  };
118 
119 public:
120 
124  uint8_t&
125  operator[] (size_t index) {
126  if (index >= length()) {
127  throw ePacketOutOfRange("cpacket::operator[] index out of range");
128  }
129  return (rofl::cmemory::operator[] (head + index));
130  };
131 
135  bool
136  operator== (const cpacket& p) {
137  if (length() != p.length())
138  return false;
139  return (not (memcmp(soframe(), p.soframe(), length())));
140  };
141 
145  bool
146  operator== (const cmemory& m) {
147  if (length() != m.memlen())
148  return false;
149  return (not (memcmp(soframe(), m.somem(), length())));
150  };
151 
155  bool
156  operator!= (
157  const cpacket& p) {
158  if (length() != p.length())
159  return true;
160  return (memcmp(soframe(), p.soframe(), length()));
161  };
162 
166  bool
167  operator!= (
168  const cmemory& m) {
169  if (length() != m.memlen())
170  return true;
171  return (memcmp(soframe(), m.somem(), length()));
172  };
173 
177  cpacket
178  operator+ (
179  const cpacket& pack) {
180  cpacket p(this->length() + pack.length());
181  memcpy(p.soframe(), this->soframe(), this->length());
182  memcpy(p.soframe() + this->length(), pack.soframe(), pack.length());
183  return p;
184  };
185 
189  cpacket&
190  operator+= (
191  const cpacket& pack) {
192  size_t offset = this->length();
193  rofl::cmemory::resize(this->length() + pack.length());
194  memcpy(this->soframe() + offset, pack.soframe(), pack.length());
195  return *this;
196  };
197 
198 public:
199 
203  virtual void
204  assign(uint8_t *buf, size_t buflen) {
205  head = initial_head;
206  tail = initial_tail;
207  cmemory::resize(head + buflen + tail);
208  cmemory::clear();
209  memcpy(soframe(), buf, buflen);
210  };
211 
215  virtual uint8_t*
216  resize(size_t len) {
217  cmemory::resize(head + len + tail);
218  return soframe();
219  };
220 
224  uint8_t*
225  soframe() const
226  { return (rofl::cmemory::somem() + head); };
227 
231  bool
232  empty() const
233  { return (0 == length()); };
234 
238  size_t
239  length() const
240  { return (rofl::cmemory::memlen() - head - tail); };
241 
245  virtual void
246  pack(uint8_t* buf, size_t buflen) {
247  if (buflen < length()) {
248  throw ePacketInval("cpacket::pack() insufficient space");
249  }
250  memcpy(buf, soframe(), buflen);
251  };
252 
256  virtual void
257  unpack(uint8_t* buf, size_t buflen) {
258  rofl::cmemory::resize(head + buflen + tail);
259  memcpy(soframe(), buf, buflen);
260  };
261 
262 private:
263 
267  uint8_t*
268  tag_insert(
269  uint8_t* ptr, size_t len) { throw eNotImplemented(); };
270 
274  void
275  tag_remove(
276  uint8_t* ptr, size_t len) { throw eNotImplemented(); };
277 
278 public:
279 
283  void
284  tag_insert(
285  size_t len) {
286  if (len > head) {
287  throw ePacketInval("cpacket::tag_insert() insufficient head space");
288  }
289  head -= len;
290  };
291 
295  void
296  tag_remove(
297  size_t len) {
298  if ((len + head) > rofl::cmemory::memlen()) {
299  throw ePacketInval("cpacket::tag_insert() invalid tag size");
300  }
301  head += len;
302  };
303 
307  uint8_t*
308  push(unsigned int offset, unsigned int nbytes) {
309  if (nbytes > head) {
310  resize(length() + nbytes);
311  }
312  memmove(somem() + head - nbytes, somem() + head, offset);
313  head -= nbytes;
314  memset(somem() + head + offset, 0, nbytes);
315  return (soframe() + offset);
316  };
317 
321  void
322  pop(unsigned int offset, unsigned int nbytes) {
323  if ((head + offset + nbytes) > memlen()) {
324  throw ePacketOutOfRange("rofl::cpacket::pop()");
325  }
326  memmove(somem() + head + nbytes, somem() + head, offset);
327  memset(somem() + head, 0, nbytes);
328  head += nbytes;
329  };
330 
331 public:
332 
336  friend std::ostream &
337  operator<<(std::ostream& os, const cpacket& pack) {
338  os << rofl::indent(0) << "<cpacket ";
339  os << "data:" << (void*)pack.soframe() << " ";
340  os << "datalen:" << (int)pack.length() << " ";
341  os << ">" << std::endl;
342  rofl::indent i(2);
343 
344  unsigned int nbytes = 32;
345  if (pack.length() > 0) {
346  for (unsigned int i=0; i < pack.length(); i++) {
347  if (0 == (i % nbytes)) {
348  os << indent(2)
349  << std::setfill('0')
350  << std::setw(4)
351  << std::dec << (i/nbytes) << ": " << std::hex
352  << std::setw(0)
353  << std::setfill(' ');
354  }
355 
356  os << std::setfill('0')
357  << std::setw(2)
358  << std::hex << (int)(*(pack.soframe() + i)) << std::dec
359  << std::setw(0)
360  << std::setfill(' ')
361  << " ";
362 
363  if (0 == ((i+1) % 8))
364  os << " ";
365  if (0 == ((i+1) % nbytes))
366  os << std::endl;
367  }
368  os << std::endl;
369  }
370  return os;
371  };
372 
373 private:
374 
375  static const int DEFAULT_SIZE = 0;
376  static const int DEFAULT_HSPACE = 64; // head room for push operations
377  static const int DEFAULT_TSPACE = 256; // tail room for appending payload(s)
378 
379  size_t head; // head space size: this is used as extra space for pushing tags
380  size_t tail; // tail space size: this is used as extra space for appending payload(s)
381  size_t initial_head;
382  size_t initial_tail;
383 };
384 
385 }; // end of namespace rofl
386 
387 #endif
Definition: croflexception.h:57
Definition: cpacket.h:47
virtual void assign(uint8_t *buf, size_t buflen)
Overwrites memory area with plain buffer specified. Resizes internal memory as necessary.
Definition: cpacket.h:204
size_t memlen() const
Returns length of allocated memory area.
Definition: cmemory.cc:109
Definition: cpacket.h:39
Definition: cpacket.h:43
uint8_t * somem() const
Returns pointer to start of allocated memory area.
Definition: cmemory.cc:101
virtual void pack(uint8_t *buf, size_t buflen)
Copies content of this cmemory instance to specified buffer.
Definition: cpacket.h:246
virtual void unpack(uint8_t *buf, size_t buflen)
Copies content of specified buffer into this cmemory instance .
Definition: cpacket.h:257
virtual uint8_t * resize(size_t len)
Resizes allocated memory area by calling C-function realloc().
Definition: cmemory.cc:253
C++ abstraction for malloc'ed memory areas.
Definition: cmemory.h:44
virtual uint8_t * resize(size_t len)
Resizes allocated memory area by calling C-function realloc().
Definition: cpacket.h:216
cmemory & operator=(cmemory const &m)
Assignment operator.
Definition: cmemory.cc:85
bool empty() const
Returns boolean value empty/non empty.
Definition: cpacket.h:232
Definition: cpacket.h:56
Definition: logging.h:76
Definition: cpacket.h:35
Definition: croflexception.h:27
void clear()
Clears the allocated memory area by setting all bytes to 0.
Definition: cmemory.cc:281