-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
benjie
committed
Oct 17, 2000
1 parent
a71e1c2
commit a7b36ce
Showing
3 changed files
with
224 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters