Revised OpenFlow Library  v0.6.0dev
 All Classes Files Functions Variables Friends Groups Pages
ficmpv6frame.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 ficmpv6frame_H
6 #define ficmpv6frame_H 1
7 
8 #include <map>
9 #include <endian.h>
10 #ifndef htobe16
11  #include "../endian_conversion.h"
12 #endif
13 
14 #include "../fframe.h"
15 #include "../caddress.h"
16 
17 namespace rofl
18 {
19 
20 class eICMPv6FrameBase : public eFrameBase {};
26 
27 
28 
29 
30 
31 
32 
33 class ficmpv6opt : public fframe {
34 
35  #define IPV6_ADDR_LEN 16
36  #define ETHER_ADDR_LEN 6
37 
38 public: // static definitions and constants
39 
40  /*
41  * ICMPv6 NDP options
42  */
43 
44  enum icmpv6_option_type_t {
45  ICMPV6_OPT_LLADDR_SOURCE = 1,
46  ICMPV6_OPT_LLADDR_TARGET = 2,
47  ICMPV6_OPT_PREFIX_INFO = 3,
48  ICMPV6_OPT_REDIRECT = 4,
49  ICMPV6_OPT_MTU = 5,
50  };
51 
52  /* ICMPv6 generic option header */
54  uint8_t type;
55  uint8_t len;
56  uint8_t data[0];
57  } __attribute__((packed));
58 
59 
60  /* ICMPv6 link layer address option */
62  struct icmpv6_option_hdr_t hdr;
63  uint8_t addr[ETHER_ADDR_LEN]; // len=1 (in 8-octets wide blocks) and we assume Ethernet here
64  } __attribute__((packed));
65 
66  /* ICMPv6 prefix information option */
68  struct icmpv6_option_hdr_t hdr;
69  uint8_t pfxlen;
70  uint8_t flags;
71  uint32_t valid_lifetime;
72  uint32_t preferred_lifetime;
73  uint32_t reserved;
74  uint8_t prefix[IPV6_ADDR_LEN];
75  } __attribute__((packed));
76 
77  /* ICMPv6 redirected option header */
79  struct icmpv6_option_hdr_t hdr;
80  uint8_t reserved[6];
81  uint8_t data[0];
82  } __attribute__((packed));
83 
84  /* ICMPv6 MTU option */
85  struct icmpv6_mtu_t {
86  struct icmpv6_option_hdr_t hdr;
87  uint8_t reserved[2];
88  uint32_t mtu;
89  } __attribute__((packed));
90 
91 public:
92 
93  union {
94  struct icmpv6_option_hdr_t *optu;
95  struct icmpv6_lla_option_t *optu_lla;
96  struct icmpv6_prefix_info_t *optu_pfx;
97  struct icmpv6_redirected_hdr_t *optu_rdr;
98  struct icmpv6_mtu_t *optu_mtu;
99  } icmpv6optu;
100 
101 #define icmpv6_opt icmpv6optu.optu
102 #define icmpv6_opt_lla icmpv6optu.optu_lla
103 #define icmpv6_opt_pfx icmpv6optu.optu_pfx
104 #define icmpv6_opt_rdr icmpv6optu.optu_rdr
105 #define icmpv6_opt_mtu icmpv6optu.optu_mtu
106 
107 public:
110  ficmpv6opt(uint8_t *data = (uint8_t*)0, size_t datalen = 0);
113  ficmpv6opt(struct icmpv6_option_hdr_t *data, size_t datalen);
116  virtual ~ficmpv6opt();
119  ficmpv6opt(ficmpv6opt const& opt);
122  ficmpv6opt& operator= (ficmpv6opt const& opt);
123 public:
126  uint8_t get_opt_type() const;
129  void set_opt_type(uint8_t type);
132  cmacaddr get_ll_taddr() const;
135  void set_ll_taddr(cmacaddr const& addr);
138  cmacaddr get_ll_saddr() const;
141  void set_ll_saddr(cmacaddr const& addr);
144  uint8_t get_pfx_on_link_flag() const;
147  void set_pfx_on_link_flag(uint8_t flag);
150  uint8_t get_pfx_aac_flag() const;
153  void set_pfx_aac_flag(uint8_t flag);
154 
155 public:
156 
157  friend std::ostream&
158  operator<< (std::ostream& os, ficmpv6opt const& opt) {
159  os << "<ficmvp6opt ";
160  os << "type:";
161  switch (opt.get_opt_type()) {
162  case ICMPV6_OPT_LLADDR_SOURCE: os << "LLADDR-SOURCE "; break;
163  case ICMPV6_OPT_LLADDR_TARGET: os << "LLADDR-TARGET "; break;
164  case ICMPV6_OPT_PREFIX_INFO: os << "PREFIX-INFO "; break;
165  case ICMPV6_OPT_REDIRECT: os << "REDIRECT "; break;
166  case ICMPV6_OPT_MTU: os << "MTU "; break;
167  default: os << "UNKNOWN "; break;
168  }
169  os << std::endl << dynamic_cast<fframe const&>( opt ) << std::endl;
170  os << ">";
171  return os;
172  };
173 };
174 
175 
176 
177 
178 
179 
180 
181 
182 class ficmpv6frame : public fframe {
183 
184 #define IPV6_ADDR_LEN 16
185 #define ETHER_ADDR_LEN 6
186 
187 public: /* ICMPv6 constants and definitions */
188 
189  enum icmpv6_ip_proto_t {
190  ICMPV6_IP_PROTO = 58,
191  };
192 
193  enum icmpv6_type_t {
194  ICMPV6_TYPE_DESTINATION_UNREACHABLE = 1,
195  ICMPV6_TYPE_PACKET_TOO_BIG = 2,
196  ICMPV6_TYPE_TIME_EXCEEDED = 3,
197  ICMPV6_TYPE_PARAMETER_PROBLEM = 4,
198  ICMPV6_TYPE_ECHO_REQUEST = 128,
199  ICMPV6_TYPE_ECHO_REPLY = 129,
200  ICMPV6_TYPE_MULTICAST_LISTENER_QUERY = 130,
201  ICMPV6_TYPE_MULTICAST_LISTENER_REPORT = 131,
202  ICMPV6_TYPE_MULTICAST_LISTENER_DONE = 132,
203  ICMPV6_TYPE_ROUTER_SOLICATION = 133,
204  ICMPV6_TYPE_ROUTER_ADVERTISEMENT = 134,
205  ICMPV6_TYPE_NEIGHBOR_SOLICITATION = 135,
206  ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT = 136,
207  ICMPV6_TYPE_REDIRECT_MESSAGE = 137,
208  ICMPV6_TYPE_ROUTER_RENUMBERING = 138,
209  ICMPV6_TYPE_ICMP_NODE_INFORMATION_QUERY = 139,
210  ICMPV6_TYPE_ICMP_NODE_INFORMATION_RESPONSE = 140,
211  ICMPV6_TYPE_INVERSE_NEIGHBOR_DISCOVERY_SOLICITATION_MESSAGE = 141,
212  ICMPV6_TYPE_INVERSE_NEIGHBOR_DISCOVERY_ADVERTISEMENT_MESSAGE = 142,
213  ICMPV6_TYPE_MULTICAST_LISTENER_DISCOVERY_REPORT = 143,
214  ICMPV6_TYPE_HOME_AGENT_ADDRESS_DISCOVERY_REQUEST_MESSAGE = 144,
215  ICMPV6_TYPE_HOME_AGENT_ADDRESS_DISCOVERY_REPLY_MESSAGE = 145,
216  ICMPV6_TYPE_MOBILE_PREFIX_SOLICITATION = 146,
217  ICMPV6_TYPE_MOBILE_PREFIX_ADVERTISEMENT = 147,
218  };
219 
220  enum icmpv6_destination_unreachable_code_t {
221  ICMPV6_DEST_UNREACH_CODE_NO_ROUTE_TO_DESTINATION = 0,
222  ICMPV6_DEST_UNREACH_CODE_COMMUNICATION_WITH_DESTINATION_ADMINISTRATIVELY_PROHIBITED = 1,
223  ICMPV6_DEST_UNREACH_CODE_BEYOND_SCOPE_OF_SOURCE_ADDRESS = 2,
224  ICMPV6_DEST_UNREACH_CODE_ADDRESS_UNREACHABLE = 3,
225  ICMPV6_DEST_UNREACH_CODE_PORT_UNREACHABLE = 4,
226  ICMPV6_DEST_UNREACH_CODE_SOURCE_ADDRESS_FAILED_INGRESS_EGRESS_POLICY= 5,
227  ICMPV6_DEST_UNREACH_CODE_REJECT_ROUTE_TO_DESTINATION = 6,
228  ICMPV6_DEST_UNREACH_CODE_ERROR_IN_SOURCE_ROUTING_HEADER = 7,
229  };
230 
231 
232 
233 
234 
235  /*
236  * ICMPv6 message types
237  */
238 
239  /* ICMPv6 generic header */
240  struct icmpv6_hdr_t {
241  uint8_t type;
242  uint8_t code;
243  uint16_t checksum;
244  uint8_t data[0];
245  } __attribute__((packed));
246 
247 
248  /*
249  * ICMPv6 error message types
250  */
251 
252  /* ICMPv6 message format for Destination Unreachable */
254  struct icmpv6_hdr_t icmpv6_hdr; // type=133, code=0
255  uint32_t unused; // a 32bit value
256  uint8_t data[0]; // the IP packet
257  } __attribute__((packed));
258 
259  /* ICMPv6 message format for Packet Too Big */
261  struct icmpv6_hdr_t icmpv6_hdr; // type=133, code=0
262  uint32_t unused; // a 32bit value
263  uint8_t data[0]; // the IP packet
264  } __attribute__((packed));
265 
266  /* ICMPv6 message format for Time Exceeded */
268  struct icmpv6_hdr_t icmpv6_hdr; // type=133, code=0
269  uint32_t unused; // a 32bit value
270  uint8_t data[0]; // the IP packet
271  } __attribute__((packed));
272 
273  /* ICMPv6 message format for Parameter Problem */
275  struct icmpv6_hdr_t icmpv6_hdr; // type=133, code=0
276  uint32_t pointer; // a 32bit value
277  uint8_t data[0]; // the IP packet
278  } __attribute__((packed));
279 
280  /* ICMPv6 echo request message format */
282  struct icmpv6_hdr_t icmpv6_hdr; // type=133, code=0
283  uint16_t id;
284  uint16_t seqno;
285  uint8_t data[0]; // arbitrary data
286  } __attribute__((packed));
287 
288  /* ICMPv6 echo reply message format */
290  struct icmpv6_hdr_t icmpv6_hdr; // type=133, code=0
291  uint16_t id;
292  uint16_t seqno;
293  uint8_t data[0]; // arbitrary data
294  } __attribute__((packed));
295 
296  /*
297  * ICMPv6 NDP message types
298  */
299 
300  /* ICMPv6 router solicitation */
302  struct icmpv6_hdr_t icmpv6_hdr; // type=133, code=0
303  uint32_t reserved; // reserved for later use, for now: mbz
304  struct ficmpv6opt::icmpv6_option_hdr_t options[0];
305  } __attribute__((packed));
306 
307  /* ICMPv6 router advertisement */
309  struct icmpv6_hdr_t icmpv6_hdr; // type=134, code=0
310  uint8_t cur_hop_limit;
311  uint8_t flags;
312  uint16_t rtr_lifetime;
313  uint32_t reachable_timer;
314  uint32_t retrans_timer;
315  struct ficmpv6opt::icmpv6_option_hdr_t options[0];
316  } __attribute__((packed));
317 
318  /* ICMPv6 neighbor solicitation */
320  struct icmpv6_hdr_t icmpv6_hdr; // type=135, code=0
321  uint32_t reserved; // reserved for later use, for now: mbz
322  uint8_t taddr[IPV6_ADDR_LEN]; // =target address
323  struct ficmpv6opt::icmpv6_option_hdr_t options[0];
324  } __attribute__((packed));
325 
326  /* ICMPv6 neighbor advertisement */
328  struct icmpv6_hdr_t icmpv6_hdr; // type=136, code=0
329  uint32_t flags;
330  uint8_t taddr[IPV6_ADDR_LEN]; // =target address
331  struct ficmpv6opt::icmpv6_option_hdr_t options[0];
332  } __attribute__((packed));
333 
334  /* ICMPv6 redirect message */
336  struct icmpv6_hdr_t icmpv6_hdr; // type=137, code=0
337  uint32_t reserved; // reserved for later use, for now: mbz
338  uint8_t taddr[IPV6_ADDR_LEN]; // =target address
339  uint8_t daddr[IPV6_ADDR_LEN]; // =destination address
340  struct ficmpv6opt::icmpv6_option_hdr_t options[0];
341  } __attribute__((packed));
342 
343 
344  /*
345  * ICMPv6 pseudo header
346  */
347 
348  /* for ICMPv6 checksum calculation */
350  uint8_t src[IPV6_ADDR_LEN];
351  uint8_t dst[IPV6_ADDR_LEN];
352  uint32_t icmpv6_len; // payload length (extension headers + ICMPv6 message)
353  uint8_t zeros[3]; // = 0
354  uint8_t nxthdr; // = 58 (=ICMPV6_IP_PROTO, see below)
355  } __attribute__((packed));
356 
357 
358 
359 #define DEFAULT_ICMPV6_FRAME_SIZE sizeof(struct icmpv6_hdr_t)
360 
361 public: // data structures
362 
363  union {
364  struct icmpv6_hdr_t *icmpv6u_hdr; // ICMPv6 message header
365  struct icmpv6_dest_unreach_hdr_t *icmpv6u_dst_unreach_hdr; // ICMPv6 destination unreachable
366  struct icmpv6_pkt_too_big_hdr_t *icmpv6u_pkt_too_big_hdr; // ICMPv6 packet too big
367  struct icmpv6_time_exceeded_hdr_t *icmpv6u_time_exceeded_hdr; // ICMPv6 time exceeded
368  struct icmpv6_param_problem_hdr_t *icmpv6u_param_problem_hdr; // ICMPv6 parameter problem
369  struct icmpv6_echo_request_hdr_t *icmpv6u_echo_request_hdr; // ICMPv6 echo request
370  struct icmpv6_echo_reply_hdr_t *icmpv6u_echo_reply_hdr; // ICMPv6 echo reply
371  struct icmpv6_router_solicitation_hdr_t *icmpv6u_rtr_solicitation_hdr; // ICMPv6 rtr solicitation
372  struct icmpv6_router_advertisement_hdr_t *icmpv6u_rtr_advertisement_hdr; // ICMPv6 rtr advertisement
373  struct icmpv6_neighbor_solicitation_hdr_t *icmpv6u_neighbor_solication_hdr; // ICMPv6 NDP solication header
374  struct icmpv6_neighbor_advertisement_hdr_t *icmpv6u_neighbor_advertisement_hdr; // ICMPv6 NDP advertisement header
375  struct icmpv6_redirect_hdr_t *icmpv6u_redirect_hdr; // ICMPV6 redirect header
376  } icmpv6u;
377 
378 #define icmpv6_hdr icmpv6u.icmpv6u_hdr
379 #define icmpv6_dest_unreach icmpv6u.icmpv6u_dst_unreach_hdr
380 #define icmpv6_pkt_too_big icmpv6u.icmpv6u_pkt_too_big_hdr
381 #define icmpv6_time_exceeded icmpv6u.icmpv6u_time_exceeded_hdr
382 #define icmpv6_param_problem icmpv6u.icmpv6u_param_problem_hdr
383 #define icmpv6_echo_request icmpv6u.icmpv6u_echo_request_hdr
384 #define icmpv6_echo_reply icmpv6u.icmpv6u_echo_reply_hdr
385 #define icmpv6_rtr_solicitation icmpv6u.icmpv6u_rtr_solicitation_hdr
386 #define icmpv6_rtr_advertisement icmpv6u.icmpv6u_rtr_advertisement_hdr
387 #define icmpv6_neighbor_solicitation icmpv6u.icmpv6u_neighbor_solication_hdr
388 #define icmpv6_neighbor_advertisement icmpv6u.icmpv6u_neighbor_advertisement_hdr
389 #define icmpv6_redirect icmpv6u.icmpv6u_redirect_hdr
390 
391  std::map<ficmpv6opt::icmpv6_option_type_t, ficmpv6opt> icmpv6opts; // ICMPv6 NDP options
392 
393  uint8_t *data; // ICMPv6 message body
394  size_t datalen; // ICMPv6 message body length
395 
396 private: // data structures
397 
398  std::string info; // info string
399 
400 public:
401 
402 
406  ficmpv6frame(
407  uint8_t *data,
408  size_t datalen);
409 
410 
414  ficmpv6frame(
415  size_t len = DEFAULT_ICMPV6_FRAME_SIZE);
416 
417 
421  virtual
422  ~ficmpv6frame();
423 
424 
428  void
430 
431 
435  ficmpv6opt&
436  get_option(ficmpv6opt::icmpv6_option_type_t type) throw (eICMPv6FrameNotFound);
437 
438 
439 public: // overloaded from fframe
440 
443  virtual bool
444  complete() const;
445 
448  virtual size_t
449  need_bytes() const;
450 
454  virtual void
455  validate(uint16_t total_len = 0) const;
456 
460  virtual void
461  initialize();
462 
466  virtual void
468  uint8_t *data, size_t datalen) throw (eFrameOutOfRange);
469 
473  virtual uint8_t*
474  payload() const throw (eFrameNoPayload);
475 
479  virtual size_t
480  payloadlen() const throw (eFrameNoPayload);
481 
482 public:
483 
487  uint8_t
488  get_icmpv6_code() const;
489 
493  void
494  set_icmpv6_code(uint8_t code);
495 
499  uint8_t
500  get_icmpv6_type() const;
501 
505  void
506  set_icmpv6_type(uint8_t type);
507 
511  uint8_t
512  get_icmpv6_ndp_rtr_flag() const;
513 
517  void
518  set_icmpv6_ndp_rtr_flag();
519 
523  uint8_t
524  get_icmpv6_ndp_solicited_flag() const;
525 
529  void
530  set_icmpv6_ndp_solicited_flag();
531 
535  uint8_t
536  get_icmpv6_ndp_override_flag() const;
537 
541  void
542  set_icmpv6_ndp_override_flag();
543 
548  get_icmpv6_neighbor_taddr() const;
549 
553  void
554  set_icmpv6_neighbor_taddr(caddress_in6 const& addr);
555 
556 
557 
558 
559 private: // methods
560 
563  void
564  parse_icmpv6_options(struct ficmpv6opt::icmpv6_option_hdr_t *option, size_t optlen) throw (eICMPv6FrameTooShort);
567  void
568  parse_icmpv6_dest_unreach() throw (eICMPv6FrameTooShort);
571  void
572  parse_icmpv6_pkt_too_big() throw (eICMPv6FrameTooShort);
575  void
576  parse_icmpv6_time_exceeded() throw (eICMPv6FrameTooShort);
579  void
580  parse_icmpv6_param_problem() throw (eICMPv6FrameTooShort);
583  void
584  parse_icmpv6_echo_request() throw (eICMPv6FrameTooShort);
587  void
588  parse_icmpv6_echo_reply() throw (eICMPv6FrameTooShort);
591  void
592  parse_icmpv6_rtr_solicitation() throw (eICMPv6FrameTooShort);
595  void
596  parse_icmpv6_rtr_advertisement() throw (eICMPv6FrameTooShort);
599  void
600  parse_icmpv6_neighbor_solicitation() throw (eICMPv6FrameTooShort);
603  void
604  parse_icmpv6_neighbor_advertisement() throw (eICMPv6FrameTooShort);
607  void
608  parse_icmpv6_redirect() throw (eICMPv6FrameTooShort);
609 
610 public:
611 
612  friend std::ostream&
613  operator<< (std::ostream& os, ficmpv6frame const& frame) {
614  os << dynamic_cast<fframe const&>( frame );
615  os << indent(2) << "<ficmpv6frame ";
616  os << "code:" << (int)frame.get_icmpv6_code() << " ";
617  os << "type:" << (int)frame.get_icmpv6_type() << " ";
618  os << ">" << std::endl;
619  return os;
620  };
621 };
622 
623 }; // end of namespace
624 
625 #endif
Definition: ficmpv6frame.h:281
Definition: ficmpv6frame.h:78
Definition: caddress.h:152
virtual uint8_t * payload() const
Definition: ficmpv6frame.cc:310
Definition: ficmpv6frame.h:289
void icmpv6_calc_checksum()
Definition: ficmpv6frame.cc:345
Definition: caddress.h:589
Definition: fframe.h:21
virtual ~ficmpv6frame()
Definition: ficmpv6frame.cc:35
Definition: ficmpv6frame.h:67
Definition: ficmpv6frame.h:349
Definition: ficmpv6frame.h:21
virtual void initialize()
Definition: ficmpv6frame.cc:54
Definition: ficmpv6frame.h:33
Definition: fframe.h:19
Definition: ficmpv6frame.h:23
ficmpv6opt & operator=(ficmpv6opt const &opt)
Definition: ficmpv6frame.cc:518
Definition: ficmpv6frame.h:253
Definition: ficmpv6frame.h:24
ficmpv6opt & get_option(ficmpv6opt::icmpv6_option_type_t type)
Definition: ficmpv6frame.cc:43
virtual bool complete() const
Definition: ficmpv6frame.cc:271
Definition: ficmpv6frame.h:20
Definition: ficmpv6frame.h:240
Definition: ficmpv6frame.h:53
Definition: ficmpv6frame.h:260
Definition: fframe.h:20
virtual size_t payloadlen() const
Definition: ficmpv6frame.cc:320
Definition: ficmpv6frame.h:182
Definition: fframe.h:22
Definition: logging.h:76
virtual void payload_insert(uint8_t *data, size_t datalen)
Definition: ficmpv6frame.cc:296
Definition: ficmpv6frame.h:22
Definition: ficmpv6frame.h:61
virtual size_t need_bytes() const
Definition: ficmpv6frame.cc:283
virtual void validate(uint16_t total_len=0) const
Definition: ficmpv6frame.cc:330
Definition: ficmpv6frame.h:85
Definition: fframe.h:31
ficmpv6frame(uint8_t *data, size_t datalen)
Definition: ficmpv6frame.cc:10
Definition: ficmpv6frame.h:25
Definition: ficmpv6frame.h:335