Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions elements/ip6/destinationoptionsencap.cc
Original file line number Diff line number Diff line change
@@ -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 <click/config.h>
#include "destinationoptionsencap.hh"
#include <click/args.hh>
#include <click/error.hh>
#include <clicknet/ip6.h>
CLICK_DECLS

DestinationOptionsEncap::DestinationOptionsEncap()
{
}

DestinationOptionsEncap::~DestinationOptionsEncap()
{
}

int
DestinationOptionsEncap::configure(Vector<String> &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<DestinationOptionsWithPad6 *>(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)
44 changes: 44 additions & 0 deletions elements/ip6/destinationoptionsencap.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef CLICK_DESTINATIONOPTIONSENCAP_HH
#define CLICK_DESTINATIONOPTIONSENCAP_HH
#include <click/element.hh>
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<String> &, ErrorHandler *) CLICK_COLD;

Packet *simple_action(Packet *);

private:
uint8_t _next_header; /* next header */
};

CLICK_ENDDECLS
#endif /* CLICK_DESTINATIONOPTIONSENCAP_HH */
87 changes: 87 additions & 0 deletions elements/ip6/fragmentationencap.cc
Original file line number Diff line number Diff line change
@@ -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 <click/config.h>
#include "fragmentationencap.hh"
#include <click/args.hh>
#include <click/error.hh>
#include <clicknet/ip6.h>
CLICK_DECLS

FragmentationEncap::FragmentationEncap()
{
}

FragmentationEncap::~FragmentationEncap()
{
}

int
FragmentationEncap::configure(Vector<String> &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<click_ip6_fragment *>(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)
47 changes: 47 additions & 0 deletions elements/ip6/fragmentationencap.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef CLICK_FRAGMENTATIONENCAP_HH
#define CLICK_FRAGMENTATIONENCAP_HH
#include <click/element.hh>
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<String> &, 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 */
83 changes: 83 additions & 0 deletions elements/ip6/hopbyhopencap.cc
Original file line number Diff line number Diff line change
@@ -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 <click/config.h>
#include "hopbyhopencap.hh"
#include <click/args.hh>
#include <click/error.hh>
#include <clicknet/ip6.h>
CLICK_DECLS

HopByHopEncap::HopByHopEncap()
{
}

HopByHopEncap::~HopByHopEncap()
{
}

int
HopByHopEncap::configure(Vector<String> &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<HopByHopOptionsWithPad6 *>(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)
48 changes: 48 additions & 0 deletions elements/ip6/hopbyhopencap.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef CLICK_HOPBYHOPENCAP_HH
#define CLICK_HOPBYHOPENCAP_HH
#include <click/element.hh>
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<String> &, ErrorHandler *) CLICK_COLD;

Packet *simple_action(Packet *);
private:
uint8_t _next_header; /* next header */
};

CLICK_ENDDECLS
#endif
Loading