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

Reply via email to