diff --git a/elements/ip6/destinationoptionsencap.cc b/elements/ip6/destinationoptionsencap.cc new file mode 100644 index 0000000000..a88d02397c --- /dev/null +++ b/elements/ip6/destinationoptionsencap.cc @@ -0,0 +1,83 @@ +/* + * destionoptionsencap.{cc,hh} -- encapsulates packet in a Destination Options extension header with only a padN option available + * Glenn Minne + * + * Copyright (c) 1999-2000 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, subject to the conditions + * listed in the Click LICENSE file. These conditions include: you must + * preserve this copyright notice, and you cannot mention the copyright + * holders in advertising related to the Software without their permission. + * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This + * notice is a summary of the Click LICENSE file; the license in that file is + * legally binding. + */ + +#include +#include "destinationoptionsencap.hh" +#include +#include +#include +CLICK_DECLS + +DestinationOptionsEncap::DestinationOptionsEncap() +{ +} + +DestinationOptionsEncap::~DestinationOptionsEncap() +{ +} + +int +DestinationOptionsEncap::configure(Vector &conf, ErrorHandler *errh) +{ + if (Args(conf, this, errh) + .read_mp("PROTO", IntArg(), _next_header) + .complete() < 0) + return -1; + + return 0; +} + +Packet * +DestinationOptionsEncap::simple_action(Packet *p_in) +{ + // A Destination Options Extension header has a common part followed by an option part, which contains one or multiple option. + // This header contains one option, the Pad6 option, a special type of a PadN option. It adds 6 bytes of padding to + // our Destination Options Extension Header. + struct DestinationOptionsWithPad6 { + // common destination options extension header part + uint8_t ip6d_nxt; /* next header */ + uint8_t ip6d_len; /* 8-bit unsigned integer. Length of the + Destination Options header in 8-octet units, not + including the first 8 octets. */ + // the actual Pad6 option + uint8_t option_type; // Every PadN option including Pad6 has an option type of 1. + uint8_t option_data_len; // This explains about which specific PadN option we are talking about. We are talking about Pad6 so we need to insert 4. + uint32_t option_data; // Here are our 4 remaining bits of data so that we have in total 6 bytes of padding. These bits must all be set to zero. + // put all zeroes here. + }; + + WritablePacket *p = p_in->push(8); // make room for the new Destination Options extension header + + if (!p) + return 0; + + DestinationOptionsWithPad6 *destination_options_header = reinterpret_cast(p->data()); + + // set the values of the Destination Options extension header + destination_options_header->ip6d_nxt = _next_header; + destination_options_header->ip6d_len = 0; + + // set the values of the Pad6 option + destination_options_header->option_type = 1; + destination_options_header->option_data_len = 4; + destination_options_header->option_data = 0; + + return p; +} + +CLICK_ENDDECLS +EXPORT_ELEMENT(DestinationOptionsEncap) diff --git a/elements/ip6/destinationoptionsencap.hh b/elements/ip6/destinationoptionsencap.hh new file mode 100644 index 0000000000..ae4daab1dc --- /dev/null +++ b/elements/ip6/destinationoptionsencap.hh @@ -0,0 +1,44 @@ +#ifndef CLICK_DESTINATIONOPTIONSENCAP_HH +#define CLICK_DESTINATIONOPTIONSENCAP_HH +#include +CLICK_DECLS + +/* + * =c + * DestinationOptionsEncap([OFFSET]) + * =s ip6 + * + * =d + * + * Encapsulates a packet in a Destination Options extension header with + * only a padN option. + * + * =e + * + * InfiniteSource(LIMIT 1) + * -> UDPEncap(1200,1500) + * -> DestinationOptionsEncap(PROTO 17) + * -> IP6Encap(SRC fa80::0202:b3ff:fe1e:8329, DST f880::0202:b3ff:fe1e:0002, PROTO 60) + * -> EtherEncap(0x0800, 00:0a:95:9d:68:16, 00:0a:95:9d:68:17) + * -> ToDump("ip6.dump") + * + */ + +class DestinationOptionsEncap : public Element { + +public: + DestinationOptionsEncap(); + ~DestinationOptionsEncap(); + + const char *class_name() const { return "DestinationOptionsEncap"; } + const char *port_count() const { return PORTS_1_1; } + int configure(Vector &, ErrorHandler *) CLICK_COLD; + + Packet *simple_action(Packet *); + +private: + uint8_t _next_header; /* next header */ +}; + +CLICK_ENDDECLS +#endif /* CLICK_DESTINATIONOPTIONSENCAP_HH */ diff --git a/elements/ip6/fragmentationencap.cc b/elements/ip6/fragmentationencap.cc new file mode 100644 index 0000000000..3541e73aad --- /dev/null +++ b/elements/ip6/fragmentationencap.cc @@ -0,0 +1,87 @@ +/* + * fragmentationencap.{cc,hh} -- encapsulates packet in a Fragmentation Extension header + * Glenn Minne + * + * Copyright (c) 1999-2000 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, subject to the conditions + * listed in the Click LICENSE file. These conditions include: you must + * preserve this copyright notice, and you cannot mention the copyright + * holders in advertising related to the Software without their permission. + * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This + * notice is a summary of the Click LICENSE file; the license in that file is + * legally binding. + */ + +#include +#include "fragmentationencap.hh" +#include +#include +#include +CLICK_DECLS + +FragmentationEncap::FragmentationEncap() +{ +} + +FragmentationEncap::~FragmentationEncap() +{ +} + +int +FragmentationEncap::configure(Vector &conf, ErrorHandler *errh) +{ + _identification = 0; + bool more_fragments; + + if (Args(conf, this, errh) + .read_mp("PROTO", IntArg(), _next_header) + .read_mp("OFFSET", IntArg(), _offset) + .read_mp("M", BoolArg(), more_fragments) + .read_p("ID", IntArg(), _identification) + .complete() < 0) + return -1; + + if (_offset > 8191) { + return errh->error("OFFSET should be an integer between 0 and 8191"); + } + + + _offset = htons((_offset << 3) | more_fragments); // Explanation: + // The ip6_fragment struct has the field ip6_frag_offset which contains + // a) the actual offset on bits 0-13 + // b) 2 reserved bits that are zero on bits 14-15 + // c) the M field which is a bit that tells whether more fragments follow or not + // + // the actual variable will be in the first 13 bits (and must be shifted with 3 to the left) + // & at the same time we get 0 on the last 3 bits for which the bits 14-15 needed to be zero anyway + // + // since the last bit is already zero we just or him with a bit that tells whether or not we got more fragments or not + + _identification = htonl(_identification); + + return 0; +} + +Packet * +FragmentationEncap::simple_action(Packet *p_in) +{ + WritablePacket *p = p_in->push(sizeof(click_ip6_fragment)); // make room for the new Fragmentation extension header + + if (!p) + return 0; + + click_ip6_fragment *fragmentation_header = reinterpret_cast(p->data()); + + // set the values of the fragmentation extension header + fragmentation_header->ip6_frag_nxt = _next_header; + fragmentation_header->ip6_frag_reserved = 0; + fragmentation_header->ip6_frag_offset = _offset; + fragmentation_header->ip6_frag_id = _identification; + return p; +} + +CLICK_ENDDECLS +EXPORT_ELEMENT(FragmentationEncap) diff --git a/elements/ip6/fragmentationencap.hh b/elements/ip6/fragmentationencap.hh new file mode 100644 index 0000000000..6831e4d0cf --- /dev/null +++ b/elements/ip6/fragmentationencap.hh @@ -0,0 +1,47 @@ +#ifndef CLICK_FRAGMENTATIONENCAP_HH +#define CLICK_FRAGMENTATIONENCAP_HH +#include +CLICK_DECLS + +/* + * =c + * FragmentationEncap(PROTO, OFFSET, M, [ID]) + * =s ip6 + * + * =d + * + * Encapsulates a packet in a Fragmentation extension. + * + * =e + * + * InfiniteSource(LIMIT 1) + * -> UDPEncap(1200,1500) + * -> FragmentationEncap(PROTO 17, OFFSET 0, ID 0, M 0) + * -> IP6Encap(SRC fa80::0202:b3ff:fe1e:8329, DST f880::0202:b3ff:fe1e:0002, PROTO 44) + * -> EtherEncap(0x0800, 00:0a:95:9d:68:16, 00:0a:95:9d:68:17) + * -> ToDump("ip6.dump") + * + */ + +class FragmentationEncap : public Element { + +public: + FragmentationEncap(); + ~FragmentationEncap(); + + const char *class_name() const { return "FragmentationEncap"; } + const char *port_count() const { return PORTS_1_1; } + int configure(Vector &, ErrorHandler *) CLICK_COLD; + + Packet *simple_action(Packet *); + +private: + uint8_t _next_header; /* next header */ + uint16_t _offset; /* Fragment offset */ + uint32_t _identification; /* Packet identification value, generated by the source node. + Needed for reassembly of the original packet. */ + bool _more_fragments; /* 1 means more fragments follow; 0 means last fragment. */ +}; + +CLICK_ENDDECLS +#endif /* CLICK_FRAGMENTATIONENCAP_HH */ diff --git a/elements/ip6/hopbyhopencap.cc b/elements/ip6/hopbyhopencap.cc new file mode 100644 index 0000000000..c19b0ea866 --- /dev/null +++ b/elements/ip6/hopbyhopencap.cc @@ -0,0 +1,83 @@ +/* + * hopbyhopencap.{cc,hh} -- encapsulates packet in a Pad6 Hop-by-Hop extension header + * Glenn Minne + * + * Copyright (c) 1999-2000 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, subject to the conditions + * listed in the Click LICENSE file. These conditions include: you must + * preserve this copyright notice, and you cannot mention the copyright + * holders in advertising related to the Software without their permission. + * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This + * notice is a summary of the Click LICENSE file; the license in that file is + * legally binding. + */ + +#include +#include "hopbyhopencap.hh" +#include +#include +#include +CLICK_DECLS + +HopByHopEncap::HopByHopEncap() +{ +} + +HopByHopEncap::~HopByHopEncap() +{ +} + +int +HopByHopEncap::configure(Vector &conf, ErrorHandler *errh) +{ + if (Args(conf, this, errh) + .read_mp("PROTO", IntArg(), _next_header) + .complete() < 0) + return -1; + + return 0; +} + +Packet * +HopByHopEncap::simple_action(Packet *p_in) +{ + // A Hop-by-Hop header has a common part followed by an option part, which contains one or multiple option. + // This header contains one option, the Pad6 option, a special type of a PadN option. It adds 6 bytes of padding to + // our Hop-by-hop Extension Header. + struct HopByHopOptionsWithPad6 { + // common hop-byhop extension header part + uint8_t ip6h_nxt; /* next header */ + uint8_t ip6h_len; /* 8-bit unsigned integer. Length of the + Destination Options header in 8-octet units, not + including the first 8 octets. */ + // the actual Pad6 option + uint8_t option_type; // Every PadN option including Pad6 has an option type of 1. + uint8_t option_data_len; // This explains about which specific PadN option we are talking about. We are talking about Pad6 so we need to insert 4. + uint32_t option_data; // Here are our 4 remaining bits of data so that we have in total 6 bytes of padding. These bits must all be set to zero. + // put all zeroes here. + }; + + WritablePacket *p = p_in->push(8); // make room for the new Destination Options extension header + + if (!p) + return 0; + + HopByHopOptionsWithPad6 *hop_by_hop_header = reinterpret_cast(p->data()); + + // set the values of the Hop-by-Hop extension header + hop_by_hop_header->ip6h_nxt = _next_header; + hop_by_hop_header->ip6h_len = 0; + + // set the values of the Pad6 option + hop_by_hop_header->option_type = 1; + hop_by_hop_header->option_data_len = 4; + hop_by_hop_header->option_data = 0; + + return p; +} + +CLICK_ENDDECLS +EXPORT_ELEMENT(HopByHopEncap) diff --git a/elements/ip6/hopbyhopencap.hh b/elements/ip6/hopbyhopencap.hh new file mode 100644 index 0000000000..76054ace54 --- /dev/null +++ b/elements/ip6/hopbyhopencap.hh @@ -0,0 +1,48 @@ +#ifndef CLICK_HOPBYHOPENCAP_HH +#define CLICK_HOPBYHOPENCAP_HH +#include +CLICK_DECLS + +/* + * =c + * HopByHopEncap(PROTO) + * =s ip6 + * + * =d + * + * Encapsulates the packet in a Hop-By-Hop Extension header with a Pad6 option. + * + * See RouterAlertEncap for a specific Hop-By-Hop Extension header whose Options + * and padding fields are not all set to zero. + * + * =e + * A typical example can be found below. A packet with sample data is created + * with InfiniteSource(LIMIT 1). After which it got an UDP header, then a + * Hop-by-Hop header, then a IP6 header and then the UDP Checksum is fixed + * (that is, set correctly). + * + * InfiniteSource(LIMIT 1) + * -> UDPEncap(1200,1500) + * -> HopByHopEncap(PROTO 17) + * -> IP6Encap(SRC fa80::0202:b3ff:fe1e:8329, DST f880::0202:b3ff:fe1e:0002, PROTO 0) + * -> EtherEncap(0x0800, 00:0a:95:9d:68:16, 00:0a:95:9d:68:17) + * -> ToDump("ip6.dump") + * + * =a RouterAlertEncap, IP6Encap, UDPEncap */ + +class HopByHopEncap : public Element { +public: + HopByHopEncap(); + ~HopByHopEncap(); + + const char *class_name() const { return "HopByHopEncap"; } + const char *port_count() const { return PORTS_1_1; } + int configure(Vector &, ErrorHandler *) CLICK_COLD; + + Packet *simple_action(Packet *); +private: + uint8_t _next_header; /* next header */ +}; + +CLICK_ENDDECLS +#endif diff --git a/elements/ip6/routeralertencap.cc b/elements/ip6/routeralertencap.cc new file mode 100644 index 0000000000..f765bcc0c2 --- /dev/null +++ b/elements/ip6/routeralertencap.cc @@ -0,0 +1,96 @@ +/* + * routeralertencap.{cc,hh} -- encapsulates packet in a Router Alert Option extension header + * Glenn Minne + * + * Copyright (c) 1999-2000 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, subject to the conditions + * listed in the Click LICENSE file. These conditions include: you must + * preserve this copyright notice, and you cannot mention the copyright + * holders in advertising related to the Software without their permission. + * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This + * notice is a summary of the Click LICENSE file; the license in that file is + * legally binding. + */ + +#include +#include "routeralertencap.hh" +#include +#include +#include +CLICK_DECLS + +RouterAlertEncap::RouterAlertEncap() +{ +} + +RouterAlertEncap::~RouterAlertEncap() +{ +} + +int +RouterAlertEncap::configure(Vector &conf, ErrorHandler *errh) +{ + if (Args(conf, this, errh) + .read_mp("PROTO", IntArg(), _next_header) + .read_mp("OPTION", IntArg(), _router_alert_option) + .complete() < 0) + return -1; + + return 0; +} + +Packet * +RouterAlertEncap::simple_action(Packet *p_in) +{ + struct Router_Alert_Header { // This is a particular Hop-By-Hop Extension header which contains two different options. + //////////////////////////////////////////////////////////////// + // here is the general Hop-by-Hop header part without options // + //////////////////////////////////////////////////////////////// + uint8_t next_header; // type of the next header (e.g. UDP is 17, or Mobility Extension header is 135). + uint8_t hdr_ext_len; // length of the Hop-by-Hop Options header in 8-octet units, not including the first 8 octets. + + ////////// + // what will follow are 2 options: the router alert option AND a padding option // + ////////// + + /////////////////////////////////////////////// + // here follows the Router Alert Option part // + /////////////////////////////////////////////// + uint8_t option_type1; + uint8_t opt_data_len1; + uint16_t option_data1; + + ////////////////////////////////////////////////////////////////////////////////////////// + // here follows the padN Option part; we need padding because we need at least 8 octets // + ////////////////////////////////////////////////////////////////////////////////////////// + uint8_t option_type2; + uint8_t op_data_len2; + }; + + WritablePacket *p = p_in->push(sizeof(Router_Alert_Header)); // make room for the new Hop-by-Hop extension header + + if (!p) + return 0; + + Router_Alert_Header *hop_by_hop_extension_header = reinterpret_cast(p->data()); + + // set the values of the Hop-by-Hop extension header + hop_by_hop_extension_header->next_header = _next_header; + hop_by_hop_extension_header->hdr_ext_len = 0; // it is 0 because the first 8 octets don't count and we have only 8 octets in total. + hop_by_hop_extension_header->option_type1 = 0b00000101; // this is the code for the Router Alert Option type, first two zeroes indicate that nodes not recognizing this option type, should skip over this option and continue processing the header. + hop_by_hop_extension_header->opt_data_len1 = 0b00000010; // this is decimal for 2, the length of this option is 2 bytes or equivalently 16 bits. + hop_by_hop_extension_header->option_data1 = htons(_router_alert_option); // this is given by the user, it can be something as MLD or RSVP. + + hop_by_hop_extension_header->option_type2 = 1; // means that we use the padN option + hop_by_hop_extension_header->op_data_len2 = 0; // a padding of 2 bytes is just enough, 0 extra padding bytes required + + click_chatter("de hop_by_hop_extension_header->next_header = %i", hop_by_hop_extension_header->next_header); + + return p; +} + +CLICK_ENDDECLS +EXPORT_ELEMENT(RouterAlertEncap) diff --git a/elements/ip6/routeralertencap.hh b/elements/ip6/routeralertencap.hh new file mode 100644 index 0000000000..2ab8179a7d --- /dev/null +++ b/elements/ip6/routeralertencap.hh @@ -0,0 +1,47 @@ +#ifndef CLICK_ROUTERALERTENCAP_HH +#define CLICK_ROUTERALERTENCAP_HH +#include +CLICK_DECLS + +/* + * =c + * RouterAlertEncap([OFFSET]) + * =s ip6 + * + * =d + * + * Encapsulates a packet in a Hop-by-Hop option header with + * as option type IPv6 Router Alert Option. + * + * =e + * + * InfiniteSource(LIMIT 1) + * -> UDPEncap(1200,1500) + * -> RouterAlertEncap(PROTO 17, OPTION 0) + * -> IP6Encap(SRC fa80::0202:b3ff:fe1e:8329, DST f880::0202:b3ff:fe1e:0002, PROTO 0) + * -> EtherEncap(0x0800, 00:0a:95:9d:68:16, 00:0a:95:9d:68:17) + * -> ToDump("ip6.dump") + * + */ + +class RouterAlertEncap : public Element { + +public: + RouterAlertEncap(); + ~RouterAlertEncap(); + + const char *class_name() const { return "RouterAlertEncap"; } + const char *port_count() const { return PORTS_1_1; } + int configure(Vector &, ErrorHandler *) CLICK_COLD; + + Packet *simple_action(Packet *); + +private: + uint8_t _next_header; // next header following the IPv6 Hop-by-Hop extension header. + uint16_t _router_alert_option; // if our Hop-By-Hop Extension header happens to be a router alert then this value represents the value of the router alert option (RFC 2711) + // 0 means Multicast Listener Discovery message, 1 means RSVP message, 2 means Active Network message, 3-65535 are reserved to IANA for further use. + +}; + +CLICK_ENDDECLS +#endif diff --git a/elements/ip6/routing0encap.cc b/elements/ip6/routing0encap.cc new file mode 100644 index 0000000000..beac6550ca --- /dev/null +++ b/elements/ip6/routing0encap.cc @@ -0,0 +1,112 @@ +/* + * routing0encap.{cc,hh} -- encapsulates packet in a Routing0 extension header + * Glenn Minne + * + * Copyright (c) 1999-2000 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, subject to the conditions + * listed in the Click LICENSE file. These conditions include: you must + * preserve this copyright notice, and you cannot mention the copyright + * holders in advertising related to the Software without their permission. + * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This + * notice is a summary of the Click LICENSE file; the license in that file is + * legally binding. + */ + +#include +#include "routing0encap.hh" +#include +#include +#include + +#include +CLICK_DECLS + +RoutingZeroEncap::RoutingZeroEncap() +{ +} + +RoutingZeroEncap::~RoutingZeroEncap() +{ +} + +int +RoutingZeroEncap::configure(Vector &conf, ErrorHandler *errh) +{ + String unparsed_addresses; + + if (Args(conf, this, errh) + .read_mp("PROTO", IntArg(), _next_header) + .read_mp("ADDRESSES", StringArg(), unparsed_addresses) + .complete() < 0) + return -1; + + Vector word_list; + String current_word = ""; + IP6Address address; + + bool seen_space_recently = true; + for (int i = 0; i < unparsed_addresses.length(); i++) { + if (isspace(unparsed_addresses[i]) && !seen_space_recently) { // if we get a space, please evaluate + word_list.push_back(current_word); + seen_space_recently = true; + current_word = ""; + } else if (isspace(unparsed_addresses[i]) && seen_space_recently) { + // do nothing + } else { + // add character to current word + current_word += unparsed_addresses[i]; + seen_space_recently = false; + } + } + // if current_word is not empty, add this word to the words list + if (current_word != "") { + word_list.push_back(current_word); + } + + // try to parse word_list and add them to _ip6_addresses + for (int i = 0; i < word_list.size(); i++) { + if (IP6AddressArg().parse(word_list[i], address)) { + _ip6_addresses.push_back(*(in6_addr*) address.data()); + } else { + return errh->error("The address '%s' is not a valid IPv6 address", current_word.c_str()); + } + } + + _header_ext_length = 2 * _ip6_addresses.size(); /* RFC 2460 states that the header extension length is 2 times the number of addresses in a Routing 0 header */ + _segments_left = _ip6_addresses.size(); /* the number of still to be visited nodes is equal to all given ip6 addresses because none of them has been visited yet at the point + of packet creation */ + return 0; +} + +Packet * +RoutingZeroEncap::simple_action(Packet *p_in) +{ + WritablePacket *p = p_in->push(sizeof(click_ip6_rthdr0) + (_ip6_addresses.size() * sizeof(in6_addr))); // make room for the new Routing0 extension header + + if (!p) + return 0; + + click_ip6_rthdr0 *routing0_extension_header = reinterpret_cast(p->data()); + + // set the values of the Routing0 extension header + routing0_extension_header->ip6r0_nxt = _next_header; + routing0_extension_header->ip6r0_len = _header_ext_length; + routing0_extension_header->ip6r0_type = 0; + routing0_extension_header->ip6r0_segleft = _segments_left; + routing0_extension_header->ip6r0_reserved = 0; + + in6_addr* ip6_address = (in6_addr*) (routing0_extension_header + 1); + + for (int i = 0; i < _ip6_addresses.size(); i++) { + *ip6_address = _ip6_addresses[i]; + ip6_address++; + } + + return p; +} + +CLICK_ENDDECLS +EXPORT_ELEMENT(RoutingZeroEncap) diff --git a/elements/ip6/routing0encap.hh b/elements/ip6/routing0encap.hh new file mode 100644 index 0000000000..ad7edb3b47 --- /dev/null +++ b/elements/ip6/routing0encap.hh @@ -0,0 +1,65 @@ +#ifndef CLICK_ROUTING0ENCAP_HH +#define CLICK_ROUTING0ENCAP_HH +#include +#include + +#include +CLICK_DECLS + +/* + * =c + * RoutingZeroEncap(PROTO ADDRESSES) + * =s ip6 + * + * =d + * + * Encapsulates a packet in an IPv6 Routing Extension Header with + * as option type 0. + * + * Proto is the protocol following the RoutingZeroEncap header. + * ADDRESSES is a space separated list of ipv6 addresses to be visited + * before arriving the final node. Note that the list must be given + * between "" (double quotes), see below for an example. + * + * =e + * + * InfiniteSource(LIMIT 1) + * -> UDPEncap(1200,1500) + * -> RoutingZeroEncap(PROTO 17, ADDRESSES "fa80::0202:b3ff:fe1e:9000 fa80::0202:b3ff:fe1e:9001 fa80::0202:b3ff:fe1e:9002") + * -> IP6Encap(SRC fa80::0202:b3ff:fe1e:8329, DST f880::0202:b3ff:fe1e:0002, PROTO 43) + * -> EtherEncap(0x0800, 00:0a:95:9d:68:16, 00:0a:95:9d:68:17) + * -> ToDump("ip6.dump") + * + */ + +class RoutingZeroEncap : public Element { + +public: + RoutingZeroEncap(); + ~RoutingZeroEncap(); + + const char *class_name() const { return "RoutingZeroEncap"; } + const char *port_count() const { return PORTS_1_1; } + int configure(Vector &, ErrorHandler *) CLICK_COLD; + + Packet *simple_action(Packet *); + +private: + uint8_t _next_header; /* next header */ + uint8_t _header_ext_length; /* 8-bit unsigned integer. Length of the Routing + header in 8-octet units, not including the first + 8 octets. For the Type 0 Routing header, Hdr + Ext Len is equal to two times the number of + addresses in the header. */ + uint8_t _segments_left; /* 8-bit unsigned integer. Number of route + segments remaining, i.e., number of explicitly + listed intermediate nodes still to be visited + before reaching the final destination. */ + Vector _ip6_addresses; /* list containing the ipv6 addresses that must be visited */ + + + +}; + +CLICK_ENDDECLS +#endif /* ROUTING0ENCAP */ diff --git a/include/clicknet/ip6.h b/include/clicknet/ip6.h index 63b169363c..448c7c3aa8 100644 --- a/include/clicknet/ip6.h +++ b/include/clicknet/ip6.h @@ -39,6 +39,7 @@ struct click_ip6 { } ip6_ctlun; struct in6_addr ip6_src; /* 8-23 source address */ struct in6_addr ip6_dst; /* 24-39 dest address */ + }; #define ip6_v ip6_ctlun.ip6_un3.ip6_un3_v @@ -59,6 +60,39 @@ struct click_ip6 { #define IP6_CHECK_V(hdr) (((hdr).ip6_vfc & htonl(IP6_V_MASK)) == htonl(6 << IP6_V_SHIFT)) +/* Hop-by-Hop options header */ +struct click_ip6_hbh { + uint8_t ip6h_nxt; /* next header */ + uint8_t ip6h_len; /* length in units of 8 octets */ + /* followed by options */ +}; + +/* Destination options header */ +struct click_ip6_dest { + uint8_t ip6d_nxt; /* next header */ + uint8_t ip6d_len; /* length in units of 8 octets */ + /* followed by options */ +}; + +/* Routing header */ +struct click_ip6_rthdr { + uint8_t ip6r_nxt; /* next header */ + uint8_t ip6r_len; /* length in units of 8 octets */ + uint8_t ip6r_type; /* routing type */ + uint8_t ip6r_segleft; /* segments left */ + /* followed by routing type specific data */ +}; + + /* Type 0 Routing header */ +struct click_ip6_rthdr0 { + uint8_t ip6r0_nxt; /* next header */ + uint8_t ip6r0_len; /* length in units of 8 octets */ + uint8_t ip6r0_type; /* always zero */ + uint8_t ip6r0_segleft; /* segments left */ + uint32_t ip6r0_reserved; /* reserved field */ + /* followed by up to 127 struct in6_addr */ +}; + #ifndef IP6PROTO_FRAGMENT #define IP6PROTO_FRAGMENT 0x2c #endif @@ -90,6 +124,15 @@ uint16_t in6_cksum(const struct in6_addr *saddr, uint16_t ori_csum, unsigned char *addr, uint16_t len2); + +/** + * @brief Returns fragmentation header or null if not present + * @param ip6 header (+ data) of the packet + */ +// click_ip6_fragment* fragmentation_header(click_ip6* ip6_header); /* defined in ip6reassembler.cc */ +// click_ip6_fragment* fragmentation_header(click_ip6_hbh* ip6_header); /* defined in ip6reassembler.cc */ +// click_ip6_fragment* fragmentation_header(click_ip6_dest* ip6_header); /* defined in ip6reassembler.cc */ +// click_ip6_fragment* fragmentation_header(click_ip6_rthdr* ip6_header); /* defined in ip6reassembler.cc */ CLICK_CXX_UNPROTECT #include