click configuration file

Eddie Kohler kohler at aciri.org
Wed Oct 10 08:52:25 EDT 2001


Hi,

The CycleCount and StoreCycles elements are obsolete. Try this instead:

...
is -> udpgen ->
SetCycleCount ->
rm :: IPRateMonitor(PACKETS, 0, 1, 0, <MEM_LIMIT>) ->
st :: CycleCountAccum ->
co :: Counter -> Discard;

As for RoundRobinUDPIPEncap, I've attached rrudpipencap.{cc,hh}. Drop these
files in your 'elements/tcpudp' directory, run 'make elemlist', and you
should be ready to go. Let us know if you have any other problems!

love,
ed

p.s.

> for your information i have tried to contact the MULTOPS
> author but fail.

Bad Thomer!

-------------- next part --------------
/*
 * rrudpipencap.{cc,hh} -- element encapsulates packet in UDP/IP header
 * Benjie Chen, Eddie Kohler
 *
 * Copyright (c) 1999-2000 Massachusetts Institute of Technology.
 *
 * This software is being provided by the copyright holders under the GNU
 * General Public License, either version 2 or, at your discretion, any later
 * version. For more information, see the `COPYRIGHT' file in the source
 * distribution.
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <click/click_ip.h>
#include "rrudpipencap.hh"
#include <click/confparse.hh>
#include <click/error.hh>
#include <click/glue.hh>
#include "elements/standard/alignmentinfo.hh"
#ifdef __KERNEL__
# include <net/checksum.h>
#endif

RoundRobinUDPIPEncap::RoundRobinUDPIPEncap()
  : _addrs(0)
{
  add_input();
  add_output();
}

RoundRobinUDPIPEncap::~RoundRobinUDPIPEncap()
{
  uninitialize();
}

RoundRobinUDPIPEncap *
RoundRobinUDPIPEncap::clone() const
{
  return new RoundRobinUDPIPEncap;
}

int
RoundRobinUDPIPEncap::configure(const Vector<String> &conf, ErrorHandler *errh)
{
  if (conf.size() == 0)
    return errh->error("too few arguments");

  _naddrs = conf.size();
  _addrs = new Addrs[_naddrs];
  if (!_addrs)
    return errh->error("out of memory");

  int before = errh->nerrors();
  for (unsigned i = 0; i < _naddrs; i++) {
    Vector<String> words;
    cp_spacevec(conf[i], words);
    if (words.size() == 4)
      words.push_back("1");
    int sport, dport;
    if (words.size() != 5
	|| !cp_ip_address(words[0], (unsigned char *)&_addrs[i].saddr)
	|| !cp_integer(words[1], &sport)
	|| !cp_ip_address(words[2], (unsigned char *)&_addrs[i].daddr)
	|| !cp_integer(words[3], &dport)
	|| !cp_bool(words[4], &_addrs[i].cksum)
	|| sport < 0 || sport >= 0x10000 || dport < 0 || dport >= 0x10000)
      errh->error("argument %d should be `SADDR SPORT DADDR DPORT [CHECKSUM?]'", i);
    else {
      _addrs[i].sport = sport;
      _addrs[i].dport = dport;
      _addrs[i].id = 0;
    }
  }
  if (errh->nerrors() != before)
    return -1;

#ifdef __KERNEL__
  // check alignment
  {
    int ans, c, o;
    ans = AlignmentInfo::query(this, 0, c, o);
    _aligned = (ans && c == 4 && o == 0);
    if (!_aligned)
      errh->warning("IP header unaligned, cannot use fast IP checksum");
    if (!ans)
      errh->message("(Try passing the configuration through `click-align'.)");
  }
#endif
  
  return 0;
}

int
RoundRobinUDPIPEncap::initialize(ErrorHandler *)
{
  _pos = 0;
  return 0;
}

void
RoundRobinUDPIPEncap::uninitialize()
{
  delete[] _addrs;
  _addrs = 0;
}

Packet *
RoundRobinUDPIPEncap::simple_action(Packet *p)
{
  // pick right address
  Addrs *addr = &_addrs[_pos];
  _pos++;
  if (_pos == _naddrs) _pos = 0;

  // add to packet
  WritablePacket *q = p->push(sizeof(click_udp) + sizeof(click_ip));
  click_ip *ip = reinterpret_cast<click_ip *>(q->data());
  click_udp *udp = reinterpret_cast<click_udp *>(ip + 1);

  // set up IP header
  ip->ip_v = 4;
  ip->ip_hl = sizeof(click_ip) >> 2;
  ip->ip_len = htons(p->length());
  ip->ip_id = htons(addr->id++);
  ip->ip_p = IP_PROTO_UDP;
  ip->ip_src = addr->saddr;
  ip->ip_dst = addr->daddr;
  ip->ip_tos = 0;
  ip->ip_off = 0;
  ip->ip_ttl = 250;

  ip->ip_sum = 0;
#ifdef __KERNEL__
  if (_aligned) {
    ip->ip_sum = ip_fast_csum((unsigned char *)ip, sizeof(click_ip) >> 2);
  } else {
#endif
  ip->ip_sum = in_cksum((unsigned char *)ip, sizeof(click_ip));
#ifdef __KERNEL__
  }
#endif
  
  p->set_dst_ip_anno(IPAddress(addr->daddr));
  p->set_ip_header(ip, sizeof(click_ip));

  // set up UDP header
  udp->uh_sport = htons(addr->sport);
  udp->uh_dport = htons(addr->dport);
  unsigned short len = p->length() - sizeof(click_ip);
  udp->uh_ulen = htons(len);
  if (addr->cksum) {
    unsigned csum = ~in_cksum((unsigned char *)udp, len) & 0xFFFF;
#ifdef __KERNEL__
    udp->uh_sum = csum_tcpudp_magic(addr->saddr.s_addr, addr->daddr.s_addr,
				    len, IP_PROTO_UDP, csum);
#else
    unsigned short *words = (unsigned short *)&ip->ip_src;
    csum += words[0];
    csum += words[1];
    csum += words[2];
    csum += words[3];
    csum += htons(IP_PROTO_UDP);
    csum += htons(len);
    while (csum >> 16)
      csum = (csum & 0xFFFF) + (csum >> 16);
    udp->uh_sum = ~csum & 0xFFFF;
#endif
  } else
    udp->uh_sum = 0;
  
  return q;
}

EXPORT_ELEMENT(RoundRobinUDPIPEncap)
-------------- next part --------------
#ifndef RRUDPIPENCAP_HH
#define RRUDPIPENCAP_HH

/*
 * =c
 * RoundRobinUDPIPEncap(SADDR SPORT DADDR DPORT [CHECKSUM?] [, ...])
 * =d
 * Encapsulates each incoming packet in a UDP/IP packet with source address
 * SADDR, source port SPORT, destination address DADDR, and destination port
 * DPORT. The UDP checksum is calculated if CHECKSUM? is true; it is true by
 * default.
 *
 * The RoundRobinUDPIPEncap element adds both a UDP header and an IP header.
 *
 * You can give as many arguments as you'd like. Each argument specifies a
 * single UDP/IP header. The element will cycle through the headers in
 * round-robin order.
 *
 * The Strip element can be used by the receiver to get rid of the
 * encapsulation header.
 * =e
 *   RoundRobinUDPIPEncap(1.0.0.1 1234 2.0.0.2 1234,
 *   			  1.0.0.2 1093 2.0.0.2 1234)
 * =a Strip, UDPIPEncap */

#include <click/element.hh>
#include <click/glue.hh>
#include <click/click_udp.h>

class RoundRobinUDPIPEncap : public Element {

  struct Addrs {
    struct in_addr saddr;
    struct in_addr daddr;
    unsigned short sport;
    unsigned short dport;
    bool cksum;
    short id;
  };
  unsigned _naddrs;
  unsigned _pos;
  Addrs *_addrs;
  bool _aligned;

 public:
  
  RoundRobinUDPIPEncap();
  ~RoundRobinUDPIPEncap();
  
  const char *class_name() const	{ return "RoundRobinUDPIPEncap"; }
  const char *processing() const	{ return AGNOSTIC; }
  
  RoundRobinUDPIPEncap *clone() const;
  int configure(const Vector<String> &, ErrorHandler *);
  int initialize(ErrorHandler *);
  void uninitialize();

  Packet *simple_action(Packet *);
  
};

#endif


More information about the click mailing list