Hello,
I am attaching the code for IP6Encap element. It works the same was
IPEncap, except that it encapsulates packets with the IPv6 header.
Roman
/*
* ip6encap.{cc,hh} -- element encapsulates packet in IP6 header
* Roman Chertov
*
* Copyright (c) 2008 Santa Barbara Labs, LLC
*
* 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 "ip6encap.hh"
#include <click/nameinfo.hh>
#include <click/confparse.hh>
#include <click/error.hh>
#include <click/glue.hh>
CLICK_DECLS
IP6Encap::IP6Encap()
{
_use_dst_anno = false;
}
IP6Encap::~IP6Encap()
{
}
int
IP6Encap::configure(Vector<String> &conf, ErrorHandler *errh)
{
IP6Address src;
String dst_str;
uint32_t flow = 0;
int proto;
uint32_t hlim = 250;
uint32_t ip_class = 0;
memset(&_iph6, 0, sizeof(click_ip6));
if (cp_va_kparse(conf, this, errh,
"PROTO", cpkP+cpkM, cpNamedInteger, NameInfo::T_IP_PROTO, &proto,
"SRC", cpkP+cpkM, cpIP6Address, &src,
"DST", cpkP+cpkM, cpArgument, &dst_str,
"HLIM", 0, cpInteger, &hlim,
"CLASS", 0, cpInteger, &ip_class,
cpEnd) < 0)
return -1;
if (proto < 0 || proto > 255)
return errh->error("bad IP protocol");
_use_dst_anno = dst_str == "DST_ANNO";
if (_use_dst_anno)
memset(&_iph6.ip6_dst.s6_addr, 0, sizeof(_iph6.ip6_dst.s6_addr));
else if (!cp_ip6_address(dst_str, _iph6.ip6_dst.s6_addr, this))
return errh->error("DST argument should be IP address or 'DST_ANNO'");
// set up IP6 header
_iph6.ip6_v = 6;
_iph6.ip6_tc = ip_class;
_iph6.ip6_flow = flow;
_iph6.ip6_plen = 0;
_iph6.ip6_nxt = proto;
_iph6.ip6_hlim = hlim;
_iph6.ip6_src = src;
return 0;
}
int
IP6Encap::initialize(ErrorHandler *)
{
return 0;
}
Packet *
IP6Encap::simple_action(Packet *p_in)
{
WritablePacket *p = p_in->push(sizeof(click_ip6));
IP6Address a = DST_IP6_ANNO(p);
if (!p)
return 0;
click_ip6 *ip6 = reinterpret_cast<click_ip6 *>(p->data());
memcpy(ip6, &_iph6, sizeof(click_ip6));
if (_use_dst_anno && a) // use_dst_anno
ip6->ip6_dst = a;
else
SET_DST_IP6_ANNO(p, ip6->ip6_dst);
ip6->ip6_plen = htons(p->length() - sizeof(click_ip6));
p->set_ip6_header(ip6, sizeof(click_ip6));
return p;
}
String
IP6Encap::read_handler(Element *e, void *thunk)
{
IP6Encap *ip6e = static_cast<IP6Encap *>(e);
switch ((intptr_t)thunk) {
case 0:
return IP6Address(ip6e->_iph6.ip6_src).unparse();
case 1:
if (ip6e->_use_dst_anno)
return "DST_ANNO";
else
return IP6Address(ip6e->_iph6.ip6_dst).unparse();
default:
return "<error>";
}
}
void
IP6Encap::add_handlers()
{
add_read_handler("src", read_handler, 0, Handler::CALM);
add_write_handler("src", reconfigure_keyword_handler, "1 SRC");
add_read_handler("dst", read_handler, 1, Handler::CALM);
add_write_handler("dst", reconfigure_keyword_handler, "2 DST");
}
CLICK_ENDDECLS
EXPORT_ELEMENT(IP6Encap)
ELEMENT_MT_SAFE(IP6Encap)
#ifndef CLICK_IP6ENCAP_HH
#define CLICK_IP6ENCAP_HH
#include <click/element.hh>
#include <click/glue.hh>
#include <click/atomic.hh>
#include <clicknet/ip6.h>
#include <click/ip6address.hh>
CLICK_DECLS
/*
=c
IP6Encap(PROTO, SRC, DST, I<KEYWORDS>)
=s ip
encapsulates packets in static IP6 header
=d
Encapsulates each incoming packet in an IP6 packet with next header proto
PROTO, source address SRC, and destination address DST.
Its destination address annotation is also set to DST.
As a special case, if DST is "DST_ANNO", then the destination address
is set to the incoming packet's destination address annotation.
Keyword arguments are:
=over 2
=item HLIM
Integer, The hop limit of the packet with maximum value of 255
=item CLASS
Integer, The service class of the packet. Used for QoS
=e
Wraps packets in an IP6 header specifying IP protocol 4
(IP6-in-IP4), with source 2000:10:1::2 and destination 2000:20:1::2,
HLIM is set to 20 hops:
IP6Encap(4, 2000:10:1::2, 2000:20:1::2, HLIM 20)
You could also say "C<IP6Encap(ipip, ...)>".
=h src read/write
Returns or sets the SRC parameter.
=h dst read/write
Returns or sets the DST parameter.
=a UDPIP6Encap */
class IP6Encap : public Element { public:
IP6Encap();
~IP6Encap();
const char *class_name() const { return "IP6Encap"; }
const char *port_count() const { return PORTS_1_1; }
const char *processing() const { return AGNOSTIC; }
int configure(Vector<String> &, ErrorHandler *);
bool can_live_reconfigure() const { return true; }
int initialize(ErrorHandler *);
void add_handlers();
Packet *simple_action(Packet *);
private:
click_ip6 _iph6;
bool _use_dst_anno;
static String read_handler(Element *, void *);
};
CLICK_ENDDECLS
#endif
_______________________________________________
click mailing list
[email protected]
https://amsterdam.lcs.mit.edu/mailman/listinfo/click