Skip to content

Commit

Permalink
new udpgen element
Browse files Browse the repository at this point in the history
  • Loading branch information
benjie committed Oct 17, 2000
1 parent a71e1c2 commit a7b36ce
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 1 deletion.
154 changes: 154 additions & 0 deletions elements/linuxmodule/fastudpsrc.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* fastudpsource.{cc,hh} -- fast udp source, a benchmark tool
*
* 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 following
* conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Further elaboration of this license, including a DISCLAIMER OF ANY
* WARRANTY, EXPRESS OR IMPLIED, is provided in the LICENSE file, which is
* also accessible at http://www.pdos.lcs.mit.edu/click/license.html
*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <click/config.h>
#include <click/package.hh>
#include <click/click_ip.h>
#include "fastudpsrc.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

FastUDPSource::FastUDPSource()
: _packet(0)
{
add_output();
MOD_INC_USE_COUNT;
}

FastUDPSource::~FastUDPSource()
{
uninitialize();
MOD_DEC_USE_COUNT;
}

int
FastUDPSource::configure(const Vector<String> &conf, ErrorHandler *errh)
{
bool _cksum = true;
unsigned sp, dp;
unsigned rate;
int limit;
if (cp_va_parse(conf, this, errh,
cpUnsigned, "send rate", &rate,
cpInteger, "limit", &limit,
cpUnsigned, "packet length", &_len,
cpEthernetAddress, "src eth address", &_ethh.ether_shost,
cpIPAddress, "src ip address", &_sipaddr,
cpUnsigned, "src port", &sp,
cpEthernetAddress, "dst eth address", &_ethh.ether_dhost,
cpIPAddress, "dst ip address", &_dipaddr,
cpUnsigned, "dst port", &dp,
cpOptional,
cpBool, "do UDP checksum?", &_cksum,
0) < 0)
return -1;
if (sp >= 0x10000 || dp >= 0x10000)
return errh->error("source or destination port too large");
if (_len < 60) {
click_chatter("warning: packet length < 60, defaulting to 60");
_len = 60;
}
_ethh.ether_type = htons(0x0800);
_sport = sp;
_dport = dp;
_rate.set_rate(rate, errh);
_limit = (limit >= 0 ? limit : NO_LIMIT);
return 0;
}

int
FastUDPSource::initialize(ErrorHandler *)
{
_count = 0;
_packet = Packet::make(_len);
memcpy(_packet->data(), &_ethh, 14);
click_ip *ip = reinterpret_cast<click_ip *>(_packet->data()+14);
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(_len-14);
ip->ip_id = 0;
ip->ip_p = IP_PROTO_UDP;
ip->ip_src = _sipaddr;
ip->ip_dst = _dipaddr;
ip->ip_tos = 0;
ip->ip_off = 0;
ip->ip_ttl = 250;
ip->ip_sum = in_cksum((unsigned char *)ip, sizeof(click_ip));
_packet->set_dst_ip_anno(IPAddress(_dipaddr));
_packet->set_ip_header(ip, sizeof(click_ip));

// set up UDP header
udp->uh_sport = htons(_sport);
udp->uh_dport = htons(_dport);
unsigned short len = _len-14-sizeof(click_ip);
udp->uh_ulen = htons(len);
if (_cksum) {
unsigned csum = ~in_cksum((unsigned char *)udp, len) & 0xFFFF;
udp->uh_sum = csum_tcpudp_magic(_sipaddr.s_addr, _dipaddr.s_addr,
len, IP_PROTO_UDP, csum);
} else
udp->uh_sum = 0;

_skb = _packet->steal_skb();
return 0;
}

void
FastUDPSource::uninitialize()
{
if (_packet) {
_packet->kill();
_packet=0;
}
}

Packet *
FastUDPSource::pull(int)
{
if (_limit != NO_LIMIT && _count >= _limit) return 0;
#if 1
struct timeval now;
click_gettimeofday(&now);
if (_rate.need_update(now)) {
_rate.update();
_count++;
atomic_inc(&_skb->users);
return reinterpret_cast<Packet *>(_skb);
}
return 0;
#else
_count++;
atomic_inc(&_skb->users);
return reinterpret_cast<Packet *>(_skb);
#endif
}

ELEMENT_REQUIRES(linuxmodule)
EXPORT_ELEMENT(FastUDPSource)

69 changes: 69 additions & 0 deletions elements/linuxmodule/fastudpsrc.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#ifndef FASTUDPSRC_HH
#define FASTUDPSRC_HH

/*
* =c
* FastUDPSource(RATE, LIMIT, LEN, SETHADDR, SIPADDR, SPORT, DETHADDR, DIPADDR, DPORT [, CHECKSUM?])
* =s
* creates packets with static UDP/IP/Ethernet headers
* V<sources>
* =d
* FastUDPSource is a benchmark tool. At initialization time, FastUDPSource
* creates a UDP/IP packet of length LEN (min 60), with source ethernet
* address SETHADDR, source IP address SIPADDR, source port SPORT, destination
* ethernet address DETHADDR, destination IP address DIPADDR, and destination
* port DPORT. The UDP checksum is calculated if CHECKSUM? is true; it is
* true by default. Each time the FastUDPSource element is called, it
* increments the reference count on the skbuff created and returns the skbuff
* object w/o copying or cloning. Therefore, the packet returned by
* FastUDPSource should not be modified.
*
* FastUDPSource sents packets at RATE packets per second. It will send LIMIT
* number of packets in total.
*
* =e
* FastUDPSource(100000, 500000, 60, 0:0:0:0:0:0, 1.0.0.1, 1234, 1:1:1:1:1:1, 2.0.0.2, 1234)
* -> ToDevice;
*/

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

class FastUDPSource : public Element {

static const unsigned NO_LIMIT = 0xFFFFFFFFU;

GapRate _rate;
unsigned _count;
unsigned _limit;
unsigned _len;
click_ether _ethh;
struct in_addr _sipaddr;
struct in_addr _dipaddr;
unsigned short _sport;
unsigned short _dport;
bool _cksum;
WritablePacket *_packet;
struct sk_buff *_skb;

public:

FastUDPSource();
~FastUDPSource();

const char *class_name() const { return "FastUDPSource"; }
const char *processing() const { return PULL; }

FastUDPSource *clone() const { return new FastUDPSource; }

int configure(const Vector<String> &, ErrorHandler *);
int initialize(ErrorHandler *);
void uninitialize();
Packet *pull(int);
};

#endif
2 changes: 1 addition & 1 deletion elements/linuxmodule/todevice.cc
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ ToDevice::tx_intr()
if (sent == 0 && !busy) _idle_pulls++;
}
#endif
if (busy) _busy_returns++;
if (sent == 0 && busy) _busy_returns++;

#if HAVE_POLLING
if (_polling) {
Expand Down

0 comments on commit a7b36ce

Please sign in to comment.